Postgresql触发函数工作但生成重复

时间:2012-03-15 16:29:54

标签: postgresql triggers duplicates

三个Postgresql表(Windows V 9.1.3) 表obx是一个动态表,用于从多台计算机接收数据。 我们想要产生一个后插入触发器功能 表testcode是一个固定表,其中包含我们尝试与obx表匹配的值。如果testcode TestID整数字段不为null,我们希望使用表obx上的after insert触发器将数据插入到新表finaldata中。

第一个触发器有效,但它会产生重复数据。触发器必须包含“LIMIT 3”,因为其中一台机器一次发送三个结果。 仅使用SQL尝试第二个选项但不起作用。

表finaldata中标记为XY的字段供内部使用。

    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 :(得分: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版本/日期,参数键区)您的数据模型似乎不适合支持您输入的数据。