如何避免"元组已被修改"在PostgreSQL中使用BEFORE触发器时出错?

时间:2015-06-12 04:51:29

标签: postgresql triggers plpgsql

在尝试使用触发器(PostgreSQL 9.1)来防止重复条目时,我收到以下错误:

错误:要更新的元组已被当前命令触发的操作修改 提示:考虑使用AFTER触发器而不是BEFORE触发器将更改传播到其他行。强调文本

执行以下命令收到此错误:

update dx set cicd9='721.90', cdesc='osteoarthritis of spine, nos' where cicd9 = '721.90' and cdesc=' osteoarthritis of spine, nos';

(这里的尝试是删除cdesc中的空格。)

如果我"返回空虚"从触发器中的更新,然后一切都被删除!?

如何编写触发器以允许调用"更新dx"工作,但防止导致重复键的结果?

(注意:如果目标记录正在更新为已经存在的"新"值,我正在尝试删除"旧"值并保留" new" value。如果我在更新时返回NULL,则删除旧值,但没有记录新值??)。

我做错了什么?

以下是我正在使用的触发器:

  CREATE OR REPLACE FUNCTION dx_ins_up_before()
  RETURNS trigger AS 
  $func$

BEGIN
    IF TG_OP = 'UPDATE' THEN

        RAISE NOTICE 'doing update';

        IF EXISTS (SELECT 1 FROM dx
                WHERE (cicd9,    cdesc,    groupid,    tposted)
                = (new.cicd9, new.cdesc, new.groupid, new.tposted) ) 
        THEN
        RAISE NOTICE 'doing delete from update';

              DELETE FROM dx 
                WHERE (cicd9,    cdesc,    groupid,    tposted)
                = (OLD.cicd9, OLD.cdesc, OLD.groupid,  OLD.tposted ); 
        END IF;
        RETURN new; 
    ELSE
    -- doing insert
        RAISE NOTICE 'doing insert';

        IF EXISTS (SELECT 1 FROM dx
                WHERE (cicd9,    cdesc,    groupid,    tposted)
                = (new.cicd9, new.cdesc, new.groupid, new.tposted) ) 
        THEN
        RAISE NOTICE 'return null from insert';
            RETURN NULL;    
        END IF;
    END IF;                 
END;    

$func$  LANGUAGE plpgsql;


 CREATE TRIGGER dx_ins_up_trigger
BEFORE INSERT OR UPDATE OF cicd9,cdesc,groupid,tposted
ON dx
FOR EACH ROW
EXECUTE PROCEDURE dx_ins_up_before();

dx中的约束是:

CONSTRAINT noduplicate_dx UNIQUE (cicd9, cdesc, groupid, tposted),

TIA

0 个答案:

没有答案