2012-03-15 2 views
0

Три таблицы Postgresql (Windows V 9.1.3) Таблица obx - это динамическая таблица, которая извлекает данные с нескольких компьютеров. Мы хотим создать функцию триггера после вставки Табличный тестовый код является фиксированной таблицей, которая содержит значения, которые мы пытаемся сопоставить с таблицей obx. Если testcode TestID целочисленное поле не является нулевым, мы хотим вставить данные в новую таблицу finaldata, используя триггер после вставки в таблицу obx.Функция триггера Postgresql работает, но производит дубликаты

Первый триггер работает, но он производит дубликаты данных. Триггер должен содержать «LIMIT 3», поскольку одна из машин посылает три результата за раз. Пробовал второй вариант, используя только SQL, но не работает.

Поля, отмеченные XY в таблице finaldata, предназначены для внутреннего использования.

CREATE TABLE "public"."obx" (
"obxID" serial primary key, 
"Pid" varchar, 
"Sid" varchar, 
"SidOrig" varchar, 
"Parameter" varchar, 
"Result" varchar, 
"ResultOrig" varchar, 
"Units" varchar, 
"RefRange" varchar, 
"Flag" varchar, 
"FlagOrig" varchar, 
"OperatorID" varchar, 
"ObsTime" char(14), 
"MsgTime" char(14), 
"UnixTime" int4, 
"Analyzer" varchar, 
"Segment" varchar 
) 
; 

CREATE TABLE "public"."testcode" (
"TcodeID" serial primary key, 
"Analyzer" varchar, 
"Parameter" varchar, 
"TestName" varchar, 
"ShortTestName" varchar, 
"TestID" int4 
) 
; 

CREATE TABLE "public"."finaldata" (
"FdataID" serial primary key, 
"Pid" varchar, 
"Sid" varchar, 
"SidOrig" varchar, 
"Parameter" varchar, 
"Result" varchar, 
"ResultOrig" varchar, 
"Units" varchar, 
"OperatorID" varchar, 
"ObsTime" varchar, 
"MsgTime" varchar, 
"Analyzer" varchar, 
"TestName" varchar, 
"ShortTestName" varchar, 
"TestID" varchar, 
"XYchar1" varchar, 
"XYchar2" varchar, 
"XYchar3" varchar, 
"XYint1" int4, 
"XYint2" int4, 
"XYint3" int4, 
"XYGuid" uuid 
) 
; 

    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 ("Pid", "Sid", "SidOrig", "Parameter", "Result", "ResultOrig", "Units", "OperatorID", "ObsTime", "MsgTime", "Analyzer", "TestName", "ShortTestName", "TestID") 
    SELECT "Pid", "Sid", "SidOrig", "Parameter", "Result", "ResultOrig", "Units", "OperatorID", "ObsTime", "MsgTime", "Analyzer", name, short, id 
    from obx WHERE "obx"."Parameter" = NEW."Parameter" 
    LIMIT 3; 
    END if; 
    RETURN NEW; 
    END; 


    ---------------------------- 
    -- Triggers structure for table "public"."obx" 
    -- ---------------------------- 
    CREATE TRIGGER finaldata_ins 
    AFTER INSERT ON obx 
    FOR EACH ROW 
    EXECUTE PROCEDURE testcode_matches() 
    ; 


    CREATE FUNCTION testcode_matches() 
    RETURNS TRIGGER AS $meat$ 
    BEGIN 
     INSERT INTO finaldata ("Pid", "Sid", "SidOrig", "Parameter", "Result", "ResultOrig", "Units", "OperatorID", "ObsTime", "MsgTime", "Analyzer", "TestName", "ShortTestName", "TestID") 
     SELECT "obx"."Pid", "obx"."Sid", "obx"."SidOrig", "obx"."Parameter", "obx"."Result", "obx"."ResultOrig", "obx"."Units", "obx"."OperatorID", "obx"."ObsTime", "obx"."MsgTime", "obx"."Analyzer", "TestName", "ShortTestName", "TestID" 
     FROM obx testcode 
     JOIN obx ON "obx"."Parameter" = "testcode"."Parameter" 
     WHERE "testcode"."Parameter" = NEW."Parameter" 
     AND "testcode"."TestID" = NEW."TestID" 
      ; 
     RETURN NEW; 
    END; 
    $meat$ 
    LANGUAGE plpgsql; 


    ---------------------------- 
    -- Triggers structure for table "public"."obx" 
    -- ---------------------------- 
    CREATE TRIGGER finaldata_ins 
    AFTER INSERT ON obx 
    FOR EACH ROW 
    EXECUTE PROCEDURE testcode_matches() 
    ; 

ответ

0

Кажется, вы путаете себя, давая OBX имя корреляции "testcode":

TESTTABLES:

SET search_path='tmp'; 
    DROP TABLE "obx" CASCADE; 
    CREATE TABLE "obx" (
    "obxID" serial primary key, 
    "Pid" varchar, 
    "Sid" varchar, 
    "SidOrig" varchar, 
    "Parameter" varchar, 
    "Result" varchar, 
    "ResultOrig" varchar, 
    "Units" varchar, 
    "RefRange" varchar, 
    "Flag" varchar, 
    "FlagOrig" varchar, 
    "OperatorID" varchar, 
    "ObsTime" char(14), 
    "MsgTime" char(14), 
    "UnixTime" int4, 
    "Analyzer" varchar, 
    "Segment" varchar 
    ); 

DROP TABLE "testcode" CASCADE; 
CREATE TABLE "testcode" (
    "TcodeID" serial primary key, 
    "Analyzer" varchar, 
    "Parameter" varchar, 
    "TestName" varchar, 
    "ShortTestName" varchar, 
    "TestID" int4 
    ) ; 
DROP TABLE "finaldata" CASCADE; 
CREATE TABLE "finaldata" (
    "FdataID" serial primary key, 
    "Pid" varchar, 
    "Sid" varchar, 
    "SidOrig" varchar, 
    "Parameter" varchar, 
    "Result" varchar, 
    "ResultOrig" varchar, 
    "Units" varchar, 
    "OperatorID" varchar, 
    "ObsTime" varchar, 
    "MsgTime" varchar, 
    "Analyzer" varchar, 
    "TestName" varchar, 
    "ShortTestName" varchar, 
    "TestID" varchar, 
    "XYchar1" varchar, 
    "XYchar2" varchar, 
    "XYchar3" varchar, 
    "XYint1" int4, 
    "XYint2" int4, 
    "XYint3" int4, 
    "XYGuid" uuid 
    ) ; 

Функция & & триггер:

DROP FUNCTION testcode_matches() CASCADE; 
    CREATE FUNCTION testcode_matches() 
    RETURNS TRIGGER AS $meat$ 
    BEGIN 
     INSERT INTO finaldata ("Pid", "Sid", "SidOrig", "Parameter", "Result", "ResultOrig", "Units" 
       , "OperatorID", "ObsTime", "MsgTime", "Analyzer", "TestName", "ShortTestName", "TestID") 
     SELECT ob."Pid", ob."Sid", ob."SidOrig", ob."Parameter", ob."Result", ob."ResultOrig", ob."Units" 
       , ob."OperatorID", ob."ObsTime", ob."MsgTime", ob."Analyzer" 
       , tc."TestName", tc."ShortTestName", tc."TestID" 
     FROM obx ob 
     JOIN testcode tc ON ob."Parameter" = tc."Parameter" 
     WHERE ob."Parameter" = NEW."Parameter" 
     -- AND ob."TestID" = NEW."TestID" -- Column does not exist 
     AND ob."obxID" = NEW."obxID" -- This appears to be the PK for obx 
      ; 
     RETURN NEW; 
    END; 
    $meat$ LANGUAGE plpgsql; 


    CREATE TRIGGER finaldata_ins 
    AFTER INSERT ON obx 
    FOR EACH ROW 
    EXECUTE PROCEDURE testcode_matches() 
    ; 

TESTDATA:

INSERT INTO testcode ("TestID", "Parameter") VALUES (101, 'Fudge'); 

INSERT INTO obx -- i"obxID" serial primary key, 
     ("Pid", "Sid" , "Parameter") VALUES ('Foo', 'Bar' ,'Fudge') ; 

SELECT * FROM finaldata; 

Кроме того: у меня отсутствуют некоторые ограничения внешнего ключа. Я бы ожидал, что testdata будет иметь не менее те же ключевые поля, что и obx, в качестве ключа-кандидата. (плюс som version/date, Parameter keyfield) Кажется, ваш datamodel не подходит для поддержки данных, которые вы подаете в него.

+0

WHERE ob. "Параметр" = NEW. "Параметр" И tc. "TestID" = NEW. "TestID" – user1044111

+0

> Я пропускаю несколько ограничений внешнего ключа. Я бы ожидал, что у testdata будут по крайней мере те же ключевые поля, что и obx, как ключ-кандидат. (plus som version/date, Parameter keyfield) Пожалуйста, сделайте любые предложения - я на пределе своих знаний здесь. – user1044111

+0

Я изменил это, но теперь получаю ошибку WHERE ob. "Parameter" = NEW. «Параметр» И tc. «TestID» = NEW. «TestID» [Err] ERROR: запись «new» не имеет поля «TestID» – user1044111

Смежные вопросы