2012-08-01 52 views
4

我试图创建一个Trigger将通过一些IF ELSEIF语句运行,并检查新值是NULL但是它只能到第一个IF语句。MySQL更新设置值

This Trigger is AFTER UPDATE。我的问题是,如果我只有SET一列值是什么,其他SET到,他们是NULL或什么。如果不是UPDATE命令中的SET,我如何测试此列。

示例更新:

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 
+0

我不明白你的意思是什么“如何测试这个列,如果它没有设置这个更新命令。”你能解释更多吗? – octern 2012-08-01 16:34:36

回答

6

不能哪些列在SET子句中所引用的触发器内告知。

您只能通过比较NEW.colOLD.col的值来检查语句是否更改了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),因为旧的和新的价值是相等的。 (你的AFTER UPDATE触发器实际上看到的是存储的值,如果BEFORE INSERT触发器已将该值删除,并为该列提供了不同的值,则该值不一定是来自UPDATE语句的值。 )

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