Функция триггера Postgresql работает, но выдает дубликаты - PullRequest
0 голосов
/ 15 марта 2012

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

Первый триггер работает, но он производит дублированные данные.Триггер должен содержать «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()
    ;

1 Ответ

0 голосов
/ 15 марта 2012

Кажется, вы запутались, дав 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;

Также: мне не хватает нескольких ограничений внешнего ключа. Я ожидаю, что тестовые данные будут иметь по крайней мере те же ключевые поля, что и obx как ключ-кандидат. (плюс версия / дата сома, ключевое поле параметра) Кажется, ваша модель данных не подходит для поддержки данных, которые вы в нее вводите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...