我正在设置主主复制并尝试通过设置更新前触发器来进行一些测试。
运行下面的代码时出现错误
CREATE TRIGGER update_blogs
BEFORE UPDATE ON blogs
FOR EACH ROW
BEGIN
IF (NEW.updated_replication < OLD.updated_replication) THEN
SET NEW= OLD ;
END IF;
END$$
错误1064(42000):您的SQL语法有错误;检查手册 对应于您的MySQL服务器版本,以便在&#39;&#39;附近使用正确的语法。在 第6行
我想要做的只是在新行的updated_replication(timestamp)
值更大时才允许更新行。
我正在使用mysql。
任何人都可以告诉我哪里错了。我该如何调试这些错误?这是任何一种语法错误吗?
答案 0 :(得分:3)
两个问题:
第一个问题:你不能SET NEW = OLD
。您只能分配单个列,而不能分配整行。因此,您可以确保新值不会降低:
IF (NEW.updated_replication < OLD.updated_replication) THEN
SET NEW.updated_replication = OLD.updated_replication;
END IF;
但是这将设置一列,并让任何其他列根据产生此触发器的UPDATE进行更改。这可能会给你留下与自己不一致的数据。
如果您希望整行恢复到旧列值,则必须在SET
语句中编写一系列赋值,每行对应一行。
如果您想要中止整个更新,那么您需要学习SIGNAL feature。
IF (NEW.updated_replication < OLD.updated_replication) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'You can\'t travel backwards in time!';
END IF;
这不会回滚事务,只是产生触发器的单个UPDATE。在同一交易中进行的任何其他更改仍有待处理。
第二个问题:在使用复合语句定义触发器时未设置DELIMITER
。请在此处查看我的回答:Create function through MySQLdb
答案 1 :(得分:0)
我不认为使用tableA = tableB
分配数据库记录是合法的,这基本上是NEW=OLD
正在做的事情。
如果不需要更新,最好做一些其他操作:
CREATE TRIGGER update_blogs
BEFORE UPDATE ON blogs
FOR EACH ROW
BEGIN
IF (NEW.updated_replication >= OLD.updated_replication) THEN
SET NEW.invalid = True;
END IF;
END;$$
其中invalid
是仅为此目的添加的列。然后,定期运行的存储过程可以通过删除它们来处理这些记录。