我尝试使用
OLD.num
和 NEW.num
创建触发器,如下所示:
CREATE TRIGGER my_trigger
AFTER INSERT ON test FOR EACH ROW
SET @old_num = OLD.num, @new_num = NEW.num;
-- ↑ Here -- ↑ Here
但是,我收到以下错误:
错误 1363 (HY000):INSERT 触发器中没有旧行
那么,我该如何解决呢?
UPDATE TRIGGER
中,您可以使用OLD
关键字来访问正在被更新替换的行数据。 NEW
关键字允许访问传入的行数据,如果成功,该数据将替换旧行。
UPDATE
触发器的示例是:
CREATE TRIGGER upd_check AFTER UPDATE ON SomeTable
FOR EACH ROW
BEGIN
IF (OLD.LastChangedBy <> NEW.LastChangedBy) THEN
INSERT INTO AuditSomeTable(ID, LastChangedBy)
VALUES (OLD.ID, OLD.LastChangedBy);
END IF;
END;
SQLFiddle在这里
根据创建的触发器类型,
OLD
和 NEW
行可能不可用:
插入触发器
NEW
伪行。更新触发器
NEW
和 OLD
伪行删除触发器
OLD
伪行即
OLD
触发器上没有 INSERT
行,NEW
触发器上也没有 DELETE
行。
OP的问题
OP没有提供实际的代码,评论中提到的错误消息:
INSERT 触发器中没有旧行
表示OP无意中创建了一个
INSERT TRIGGER
,而不是问题中所示的UPDATE TRIGGER
。 INSERT
触发器没有 OLD
伪表。
出现错误的最可能的解释
"There is no OLD row in on INSERT trigger"
是您正在执行一条创建
AFTER INSERT
触发器的语句,而不是创建 AFTER UPDATE
触发器。
您无法从该行引用 OLD 值(因为该行在 INSERT 之前已存在)的原因是该行在 INSERT 之前不存在。
在触发器主体中,OLD 和 NEW 关键字使您能够访问受触发器影响的行中的列。 OLD 和 NEW 是 MySQL 对触发器的扩展;它们不区分大小写。
在INSERT触发器中,只能使用NEW.col_name;没有旧行。在 DELETE 触发器中,只能使用 OLD.col_name;没有新行。在 UPDATE 触发器中,您可以使用 OLD.col_name 引用行更新前的列,使用 NEW.col_name 引用行更新后的列。
如果我答对了你的问题..
答案是否定的!您不能在 AFTER INSERT 触发器中使用 OLD.col_name。
供您参考 mysql 参考手册,它明确指出:
在INSERT触发器中,只能使用NEW.col_name;没有旧行。在 DELETE 触发器中,只能使用 OLD.col_name;没有新行。在 UPDATE 触发器中,您可以使用 OLD.col_name 引用行更新前的列,使用 NEW.col_name 引用行更新后的列。
这是我的完整代码,说明当某些列值更新时触发器如何工作
DELIMITER $$
CREATE TRIGGER `salestatus_after_update` AFTER UPDATE ON `salesdata`
FOR EACH ROW BEGIN
IF NEW.sale_status <> OLD.sale_status THEN
SET @changetype = 'Sale Status Updated';
ELSE
SET @changetype = 'Sale Edited';
END IF;
INSERT INTO sales_notification (sale_id, changetype, notify_to, old_value, new_value) VALUES (NEW.id, @changetype, NEW.submit_by, OLD.sale_status, NEW.sale_status);
END$$
DELIMITER ;