【问题标题】:postgresql trigger function - duplicates or missing datapostgresql 触发器函数 - 重复或丢失数据
【发布时间】:2012-03-25 22:21:11
【问题描述】:

postgresql 9.1 DB 写入从机器自动发送的数据。这很好用。

我有一个 AFTER INSERT ...FOR EACH ROW 触发器 - 这也有效。 触发器通过查看另一个表来工作,如果字段中有值,它就会触发。

我有两个问题 - 一种。一些机器发送超过 1 个结果。我使用 LIMIT 1 来防止重复,这意味着我错过了来自发送多个结果的机器的数据。有什么替代方法? 湾。有些机器共享相同的测试代码,我找不到一种方法来限定它,以便在我使用 NEW 值时使其在 SELECT 中特定于机器。这是代码

CREATE FUNCTION testcode_matches()
    RETURNS TRIGGER as $$
DECLARE
    var INTEGER;
    name text;
    short text;
    id integer;
BEGIN
    SELECT count("TestID") from testcode WHERE "testcode"."Parameter" = NEW."Parameter" into var;
    IF var > 0 THEN
        SELECT "TestName", "ShortTestName", "TestID" 
        from testcode where "Parameter" = NEW."Parameter" Limit 1 into name, short, id;

        INSERT INTO finaldata /* various fields */
        SELECT /* various fields */ name, short, id
        from obx 
        WHERE "obx"."Parameter" = NEW."Parameter"
        LIMIT 1;
    END if;
    RETURN NEW;
END;
$$ language plpgsql;

【问题讨论】:

  • 您是否期望来自from testcode where "Parameter" = NEW."Parameter" 查询的ID 不止一个?在这种情况下:LIMIT 1;导致随机 id 被检索(并插入到 finaldata 中)。恕我直言,您可以将所有 {testcode,obx} 放入子查询中,并省略所有变量。查询将变成普通的 SQL。 ASO:您可以添加表定义和触发器本身吗?
  • ve received another answer below which has helped me out but Im 有兴趣了解子查询。你能建议一个链接让我看看吗?触发器本身是 -- 表 "public"."obx" 的触发器结构 -- ---------------------------- CREATE TRIGGER " finaldata_matches”在“public”上插入之后。“obx”对于每一行执行过程“testcode_matches”();

标签: function postgresql triggers duplicates


【解决方案1】:

纯 SQL 版本,没有所有变量的东西。 (未知细节省略或猜测)(未经测试)

CREATE FUNCTION testcode_matches()
    RETURNS TRIGGER as $meat$
BEGIN

    INSERT INTO finaldata ( name, short, id /* various fields */ )
    SELECT tc.name, tc.shorttestname, tc.id /* various fields */
    FROM testcode tc
    JOIN obx ON obx.parameter = tc.parameter
    WHERE tc.parameter = NEW.parameter
    AND tc.id = NEW.id -- is this the PK for testcode ??
                ;
    RETURN NEW;
END;
$meat$ language sql;

更新:

set search_path='tmp';

DROP TABLE obx CASCADE;
CREATE TABLE obx
        ( parameter INTEGER NOT NULL PRIMARY KEY
        );

DROP TABLE testcode CASCADE;
CREATE TABLE testcode
        ( ID INTEGER NOT NULL PRIMARY KEY
        , parameter INTEGER NOT NULL  REFERENCES obx(parameter)
        , zname VARCHAR
        , shorttestname VARCHAR
        );

DROP TABLE finaldata CASCADE;
CREATE TABLE finaldata
        ( ID INTEGER NOT NULL PRIMARY KEY
        , zname VARCHAR
        , shorttestname VARCHAR
        );


DROP FUNCTION testcode_matches();
CREATE FUNCTION testcode_matches()
    RETURNS TRIGGER
    AS $meat$
BEGIN

    INSERT INTO finaldata ( id, zname, shorttestname /* various fields */ )
    SELECT tc.id, tc.zname, tc.shorttestname /* various fields */
    FROM testcode tc
    JOIN obx ON obx.parameter = tc.parameter
    WHERE tc.parameter = NEW.parameter
    AND tc.id = NEW.id -- is this the PK for testcode ??
                ;
    RETURN NEW;
END;
$meat$ language plpgsql;

DROP TRIGGER testcode_ins;
CREATE TRIGGER testcode_ins
        AFTER INSERT ON testcode
        FOR EACH ROW
        EXECUTE PROCEDURE testcode_matches()
        ;

【讨论】:

  • 帮助很大,解决了第一个问题。我需要检查第二个,除非我连接到从机器获取数据数据的数据库,否则很难做到这一点。我不得不改变语言。 “[Err] ERROR: SQL functions cannot return type trigger” 所以我改成了“$meat$ language plpgsql;”你让我朝着正确的方向前进 - 非常感谢
  • 您对 SQL 函数无法返回 TRIGGER 的权利。 (顺便说一句,下次请在问题中添加一些有用的东西,例如表定义等,避免猜测。)
  • 我快到了。我从您那里了解了 CASCADE 函数以及编写触发函数的另一种方式。我已经重新发布了该工作并提供了更多详细信息,感谢您的帮助。
猜你喜欢
  • 2021-08-03
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-16
相关资源
最近更新 更多