4

我正在尝试创建一个Trigger将通过一些IF ELSEIF语句运行并检查新值NULL但是它只适用于第一个IF语句。

TriggerAFTER UPDATE. 我的问题是,如果我只是SET一个列值,其他列是什么SET,是它们NULL还是什么。SET如果此列不在此UPDATE命令上,我该如何测试它。

示例更新:

UPDATE  `stations_us`.`current_prices` SET  `midPrice` =  '3.59' WHERE  `current_prices`.`_id` =1;

目前还有其他列不更新,但可以根据 PHP 脚本进行更新。

扳机:

BEGIN
-- Definition start
IF(NEW.regPrice IS NOT NULL) THEN
INSERT INTO prices (stationID, price, type, 
prevPrice, prevDate, dateCreated, apiKey, uid) 
VALUES(NEW.stationID, NEW.regPrice, 'reg', OLD.regPrice,
OLD.regDate, NEW.regDate, NEW.lastApiUsed, NEW.lastUpdatedBy);

ELSEIF(NEW.midPrice IS NOT NULL) THEN
INSERT INTO prices (stationID, price, type, 
prevPrice, prevDate, dateCreated, apiKey, uid) 
VALUES(NEW.stationID, NEW.midPrice, 'mid', OLD.midPrice,
OLD.midDate, NEW.midDate, NEW.lastApiUsed, NEW.lastUpdatedBy);

ELSEIF(NEW.prePrice IS NOT NULL) THEN
INSERT INTO prices (stationID, price, type, 
prevPrice, prevDate, dateCreated, apiKey, uid) 
VALUES(NEW.stationID, NEW.prePrice, 'pre', OLD.prePrice,
OLD.preDate, NEW.preDate, NEW.lastApiUsed, NEW.lastUpdatedBy);
END IF;
-- Definition end
END
4

1 回答 1

6

您无法在触发器内部判断 SET 子句中引用了哪些列。

您只能通过比较和col的值来检查语句的值是否被更改。NEW.colOLD.col

IF NOT (NEW.regPrice <=> OLD.regPrice)

测试(NEW.col IS NOT NULL)不足以判断该值是否已更改。考虑旧值为 4.95 且新值为 NULL 的情况,看起来您可能想要检测该更改。


请注意,一条 UPDATE 语句可能会为多个列设置值:

UPDATE foo SET col1 = 'a', col2 = 'b', col3 = 'c' WHERE ...

另请注意,可以将列设置为 NULL,并且可以将列设置为其现有值

UPDATE foo SET col1 = 'a', col2 = NULL, col3 = col3 WHERE ...

在这种情况下,在您的触发器内部,NEW.col2将评估为 NULL,(NEW.col3 <=> OLD.col3)并将评估为 1 (TRUE),因为 OLD 和 NEW 值相等。

(您的 AFTER UPDATE 触发器真正看到的是已存储的值,如果 BEFORE INSERT 触发器与该值混淆并为该列提供了不同的值,则不一定是 UPDATE 语句中的值。)

如果您的意图是记录值的更改,您可能不想要 ELSIF,而是希望遍历所有列以检查其值是否已更改。

于 2012-08-01T16:37:20.203 回答