postgresql触发器功能 - 重复或丢失数据

时间:2012-03-08 12:20:09

标签: function postgresql triggers duplicates

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;

1 个答案:

答案 0 :(得分:0)

Plain-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()
        ;