如何解决错误“当前命令触发的操作已经修改了要更新的元组”?

时间:2019-06-28 12:55:27

标签: postgresql plpgsql database-trigger

我创建一个表项,如下所示:

Item {
    id ,
    item_name ,
    position ,
    is_parent ,
    parent_id// parent is an other item
}

我创建一个函数来更新所有项目的位置,例如,如果我插入位置2的项目并且位置2的项目已经存在,则该项目的位置将被修改并具有位置3。 / p>

插入之前

| id  |    item_name    | position | is_parent | parent_id
|  1  |     item1       |   2      |   FALSE   |
|  2  |     item2       |   3      |   FALSE   |

插入后

  

插入位置为2的item3

| id  |    item_name    | position | is_parent | parent_id |
|  1  |     item1       |   3      |   FALSE   |           |
|  2  |     item2       |   4      |   FALSE   |           |
|  3  |     item3       |   2      |   FALSE   |           |

要做此修改,我创建了这个函数:

CREATE OR REPLACE FUNCTION public.update_position_item()
  RETURNS trigger AS
$BODY$  BEGIN 
    IF(TG_OP = 'UPDATE') THEN
        IF(NEW.position <= OLD.position ) THEN
            EXECUTE 'UPDATE "item" SET position=position+1 WHERE position>=' || NEW.position || ' AND position<' || OLD.position || ' AND id<>' || NEW.id || ';';
        ELSE
            EXECUTE 'UPDATE "item" SET position=position-1 WHERE position>' || OLD.position || ' AND position<=' || NEW.position || ' AND id<>' || NEW.id || ';';
        END IF;
    ELSIF(TG_OP = 'INSERT') THEN
        EXECUTE 'UPDATE "item" SET position=position+1 WHERE position>=' || NEW.position || ' AND id<>' || NEW.id || ';';        
    ELSIF(TG_OP = 'DELETE') THEN
        EXECUTE 'UPDATE "item" SET position=position-1 WHERE position>' || OLD.position || ' AND id<>' || OLD.id || ';';
    END IF;     
    RETURN NEW;
  END; 
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION public.update_position_item()
  OWNER TO postgres;

触发器关联为:

CREATE TRIGGER update_item_position
  AFTER INSERT OR UPDATE OR DELETE
  ON public.item
  FOR EACH ROW
  EXECUTE PROCEDURE public.update_position_item();

它运作良好,但是当我创建一个函数以更新is_parent的值时,出现错误。

用于更新is_parent的功能

CREATE OR REPLACE FUNCTION public.isparent()
  RETURNS trigger AS
$BODY$
BEGIN
IF NEW.parent_id IS NOT NULL THEN
    UPDATE item SET is_parent = true WHERE id = NEW.parent_id;
ELSE
    IF(TG_OP = 'UPDATE') THEN
        IF (NEW.parent_id IS NULL AND OLD.parent_id IS NOT NULL) THEN
        IF((SELECT COUNT(*) FROM item WHERE parent_id = OLD.parent_id) < 1) 
            THEN UPDATE item SET is_parent = false WHERE id = OLD.parent_id;
        END IF ;
        END IF;
    END IF;  
END IF;   
 RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION public.isparent()
  OWNER TO postgres;

触发助手

CREATE TRIGGER before_insert_update_isparent
  BEFORE INSERT OR UPDATE
  ON public.item
  FOR EACH ROW
  EXECUTE PROCEDURE public.isparent();

当我尝试插入位置= 2的item4时出现错误

error position already exist

此外,我尝试插入位置为2的 item4 ,但是另一个项目已经具有位置= 2 ,所以出现了错误。但是,当我要插入的item4暂时没有任何位置时,我没有错误,就是插入。

当我要更新或删除其位置很重要的项目时遇到相同的问题。

0 个答案:

没有答案