2012-03-08 4 views
0

postgresql 9.1 DB는 컴퓨터에서 자동으로 전송되는 데이터를 씁니다. 이것은 잘 작동합니다.postgresql trigger function - 데이터 중복 또는 누락

각 후 트리거에 대해 AFTER INSERT ... FOR EACH ROW 트리거가 있습니다. 이것은 또한 작동합니다. 트리거는 다른 테이블을보고 작동하며 필드에 값이있는 경우 트리거합니다.

나는 두 가지 문제점이 있습니다 : a. 일부 기계는 1 개 이상의 결과를 보냅니다. 중복을 방지하기 위해 LIMIT 1을 사용하고 있는데 이는 하나 이상의 결과를 보내는 컴퓨터의 데이터가 누락되었음을 의미합니다. 이것에 대한 대안은 무엇입니까? b. 어떤 머신은 같은 테스트 코드를 공유하기 때문에 새로운 값을 사용할 때 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; 
+0

당신이 쿼리'은'testcode에서 "매개 변수"= NEW "매개 변수"에서 하나 개 이상의 ID를 기대하고 있습니까? 이 경우 : LIMIT 1; 임의의 ID가 검색되도록합니다 (그리고 최종 데이터에 삽입됩니다). IMHO 모든 {testcode, obx}를 하위 쿼리에 넣을 수 있으며 모든 변수를 생략 할 수 있습니다. 쿼리는 일반 SQL이됩니다. ASO : 테이블 정의와 트리거 자체를 추가 할 수 있습니까? – wildplasser

+0

아래에서 또 다른 답을 얻었으나 나를 도와 줬지만 하위 쿼리에 대해 배우는 데 관심이 있습니다. 보고 싶은 링크를 제안 해 주시겠습니까? 트리거 자체는 입니다 - "public"테이블의 구조를 트리거합니다. "obx" - ---------------------------- CREATE TRIGGER "finaldata_matches"AFTER INSERT ON "public". "obx"각 행에 대해 실행 절차 "testcode_matches"(); – user1044111

답변

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; 

UPDATE :.

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() 
     ; 
+0

큰 도움이되었으며 첫 번째 문제를 정리했습니다. 컴퓨터에서 데이터 데이터를 가져 오는 DB에 연결되어 있지 않으면 두 번째 및 그 작업을 수행하기가 어렵습니다. 나는 언어를 바꿔야했다. "[Err] ERROR : SQL 함수가 타입 트리거를 반환 할 수 없습니다"그래서 "$ meat $ language plpgsql;"로 변경되었습니다. 당신은 올바른 방향으로 저를 데려갔습니다 - 많은 감사 – user1044111

+0

SQL 함수가 TRIGGER를 반환 할 수 없다는 귀하의 권리. (다음에 BTW, ** 테이블에 정의와 같은 몇 가지 유용한 것들을 추가하여 추측을 피하십시오.) – wildplasser

+0

나는 거의 다 왔어. 트리거 함수를 작성하는 또 다른 방법은 물론 CASCADE 함수에 대해 배웠습니다. 당신의 도움에 감사드립니다. – user1044111