2012-02-14 74 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 

但当触发火灾,Postgres的抱怨说,它无法找到一个名为“tg_table_name”

我猜我做得显然是错误的表,但我是pl/PGSQL的新手。有没有人有任何建议如何更新旧记录(与匹配RecordID和较小的TransactionID)?

回答

2

在普通SQL中,不能使用变量作为标识符。您需要构建SQL语句并使用EXECUTEDynamic 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; 

注意我在变量是如何传递与使用条款。简化语法。
您可以在此related answer中找到更多信息和手册的链接。

+0

谢谢,这绝对是正确的路要走。我不得不做一些调整才能使它工作。我的最后的代码是: 'BEGIN EXECUTE ' UPDATE“' || TG_RELNAME ||'“ SET ”冗余“=真 WHERE ”DocumentID“= $ 1 AND ”的recordId“= $ 16 AND ”的TransactionID“<$ 3 AND“Redundant”= false' USING NEW。“DocumentID”, NEW。“RecordID”, NEW。“TransactionID”; RETURN NEW; END' 我不得不添加双引号来保存我的表名的大小写(可能特定于我的情况),并在USING语句之前取下第一个分号。 非常感谢您的帮助! – Drewmate 2012-02-14 21:19:20

+0

@Drewmate:改为使用['quote_ident(TG_RELNAME)'](http://www.postgresql.org/docs/current/interactive/functions-string.html#FUNCTIONS-STRING-OTHER)。我没有想到混合大小写标识符,因为我**从不**使用它们。小写字母标识符让你在PostgreSQL中更轻松。你必须错过我的更新,我修复了分号。 – 2012-02-14 21:35:42

+0

关于标识符的好建议。我想我会把一切都切换成小写。 – Drewmate 2012-02-14 21:43:03

相关问题