2012-02-14 2 views
1

트리거 함수를 사용하여 동일한 테이블의 이전 레코드를 업데이트하고 새 레코드가이를 대체하는 경우 중복으로 표시하려고합니다.PL/pgsql을 사용하여 동일한 테이블의 이전 레코드를 업데이트하는 트리거

이 트리거를 발생시키는 테이블을 업데이트하는 일반적인 방법으로 TG_TABLE_NAME을 사용하려고합니다.

BEGIN 
    UPDATE TG_TABLE_NAME 
    SET "Redundant"=true 
    WHERE "DocumentID"=NEW."DocumentID" 
    AND "RecordID" = NEW."RecordID" 
    AND "TransactionID" < NEW."TransactionID" 
    AND "Redundant" = false ; 
    RETURN NEW; 
END 

그러나 트리거 화재, 포스트 그레스 그것은, 내가 분명히 뭔가를 잘못하고 있어요 추측하고있어 "tg_table_name"

라는 테이블을 찾을 수 없다는 불평 때 : 내 코드는 다음과 같습니다 나는 pl/PGSQL을 처음 사용합니다. 누구든지 오래된 레코드를 (레코드 ID와 작은 TransactionID가 일치하는) 업데이트하는 방법에 대한 조언이 있습니까?

답변

2

식별자는 일반 SQL에서 변수를 사용할 수 없습니다. SQL 문을 작성하고 EXECUTE을 사용해야합니다. Dynamic SQL.

CREATE FUNCTION foo() RETURNS trigger AS 
$BODY$ 
BEGIN 
EXECUTE ' 
    UPDATE ' || quote_ident(TG_RELNAME) || ' 
    SET "Redundant" = true 
    WHERE "DocumentID" = $1 
    AND "RecordID" = $2 
    AND "TransactionID" < $3 
    AND "Redundant" = FALSE' 
USING 
    NEW."DocumentID" 
    ,NEW."RecordID" 
    ,NEW."TransactionID"; 

    RETURN NEW; 
END; 
$BODY$ language plpgsql; 

주 내가 USING 절에 변수를 전달 방법 : 이 같을 수 없습니다. 구문을 단순화합니다.
자세한 내용과 매뉴얼에 대한 링크는 related answer에서 찾을 수 있습니다.

+0

감사합니다. 이것은 분명히 올바른 길이었습니다. 나는 그것이 작동하게하기 위해 두 번의 비틀기를해야했다. 내 마지막 코드를했다 : 은' 가 ' UPDATE EXECUTE BEGIN "'|| TG_RELNAME을 || '"= 사실 WHERE "DocumentID"= $ (1) AND "recordId를"= $ 2 AND "transactionId는"<$ 3 SET "중복" AND "중복"= 거짓 ' USING NEW. "DocumentID", NEW. "RecordID", NEW. "TransactionID"; 새로운 기능으로 돌아 가기. END' 내 테이블 이름의 대소 문자를 보존하기 위해 큰 따옴표를 추가해야하고 (아마도 대소 문자와 관련이 있음) USING 문 앞에 첫 번째 세미콜론을 없앴습니다. 도움을 주셔서 감사합니다. – Drewmate

+0

@Drewmate : 대신 ['quote_ident (TG_RELNAME)'] (http://www.postgresql.org/docs/current/interactive/functions-string.html#FUNCTIONS-STRING-OTHER)를 사용하십시오. 나는 혼합 된 대소 문자를 생각하지 않았다. 왜냐하면 나는 ** 사용하지 않았기 때문이다. 소문자 식별자를 사용하면 PostgreSQL에서 쉽게 사용할 수 있습니다. 세미콜론을 수정 한 곳에서 내 업데이트를 놓쳤을 것입니다. –

+0

식별자에 대한 좋은 조언. 나는 모든 것을 소문자로 바꿀 것입니다. – Drewmate

관련 문제