我有一张桌子,我想在其中执行UPDATE
。我的问题是更新更改主键并可能因碰撞而产生错误,例如:我想更新密钥从1-15更新到1-16,并且存在1-16,因此出现错误
我知道如何通过PHP实现,但如果没有冲突,我只需要UPDATE
,如果发生冲突,我只需DELETE
旧行并取消UPDATE
。所以我决定使用触发器,因为我觉得它非常干净,例如:如果我想{1}到1-15到1-16,并且存在1-16,则删除1-15并中止UPDATE
。这是我试图创建的触发器:
UPDATE
但是回复了MySQL错误:
CREATE TRIGGER table_trigger BEFORE UPDATE ON table
FOR EACH ROW
BEGIN
IF ( SELECT COUNT(1) FROM table WHERE item_id = NEW.item_id AND related_id = NEW.related_id ) THEN
DELETE FROM table WHERE item_id = OLD.item_id AND related_id = OLD.related_id;
ROLLBACK TRANSACTION;
END IF;
END;//
这是DELETE行。我没有太多关于触发器的知识,我怎样才能实现它我正在尝试的东西?我是在正确的方式吗?
答案 0 :(得分:2)
我使用
ROLLBACK TRANSACTION
尝试中止更新
根据documentation on Triggers(偶数函数)不能使用显式提交/回滚。这是不允许的。
触发器不能使用显式或隐式开始或结束事务的语句,例如START TRANSACTION,COMMIT或ROLLBACK。
如果您不想在条件匹配时执行update
,最好抛出错误。它不会让更新发生。
示例:
delimiter //
drop trigger if exists table_trigger //
CREATE TRIGGER table_trigger BEFORE UPDATE ON table
FOR EACH ROW
BEGIN
declare rowCount int default 0;
declare error_message varchar(1024) default '';
SELECT COUNT(1) into rowCount FROM table
WHERE item_id = NEW.item_id
AND related_id = NEW.related_id ;
IF ( rowCount > 0 ) THEN -- if( rowCount ) -- too works
-- DELETE FROM table
-- WHERE item_id = OLD.item_id
-- AND related_id = OLD.related_id;
-- ROLLBACK TRANSACTION; -- this is not allowed
set error_message =
concat( error_message, 'Update not allowed for ' );
set error_message =
concat( error_message, 'combination \'item_id=' );
set error_message =
concat( error_message, NEW.item_id, '\' and ');
set error_message =
concat( error_message, '\'related_id=', NEW.related_id, '\'' );
-- throw the error
-- Update not allowed for combination
-- 'itemid=1' and 'related_id=5' ( example )
signal sqlstate 23000 set message_text = error_message;
END IF;
END;//
delimiter ;