2011-08-09 32 views
4

所以,這裏是我的問題當錶行被更新時,我正在比較新值和舊值。但新的或舊的價值有時會是空的。所以下面的代碼不起作用。我能解決這個問題嗎?比較空值與MySQL觸發器中的另一個值

謝謝

BEFORE UPDATE ON mytable 
    FOR EACH ROW 
BEGIN 
     IF OLD.assignedto != NEW.assignedto 
     THEN 
       INSERT INTO history 
        (
         asset , 
         changedfield  , 
         oldvalue , 
         newvalue  
        ) 
        VALUES 
        (
         NEW.asset, 
         'assignedto', 
         OLD.assignedto, 
         NEW.assignedto 
        ); 
     END IF; 
    END$$ 

回答

3

嘗試:

IF ( (OLD.assignedto IS NOT NULL AND NEW.assignedto IS NOT NULL 
      AND OLD.assignedto != NEW.assignedto) 
    OR (OLD.assignedto IS NULL AND NEW.assignedto IS NOT NULL) 
    OR (OLD.assignedto IS NOT NULL AND NEW.assignedto IS NULL) 
    ) 

的評論是非常正確的。

+0

'NULL或'會'NULL'。你必須使用'COALESCE()'。 – glglgl

+1

您的評論是正確的,除非您絕對不必**使用'COALESCE()'工作。也就是說,合併的答案很好。 –

+0

你是對的!我沒有意識到這一點。 – glglgl

1

空已與is null/is not null結構進行比較:

if ((old.assignedto != new.assignedto) or (old.assignedto is null) or (new.assignedto is null)) 

You'l必須調整,要滿足您的要求,因爲這會回來,如果真要麼爲null,或者他們不相等對彼此。也許你需要處理兩者都爲空的情況。

1

不能與NULL進行比較,因爲NULL被定義爲比較中永遠不匹配的值,甚至是其他NULLS。如果你不相信我,試試自己吧。

SELECT NULL = NULL; 

您將不得不檢查所涉及的列是否爲非空且不爲空。您可以使用AND或OR運算符將這樣的測試合併到您已有的邏輯中。

1
IF COALESCE(OLD.assignedto != NEW.assignedto, OLD.assignedto IS NULL AND NEW.assignedto IS NULL) 

如果OLD.assignedto != NEW.assignedto部分有一個運營商NULL,整個表達式得到NULL,使得COALESCE()返回下一個參數,而不是返回真值使用時,其中一個是NULL - 另一種必須NULL爲好。

14

MySQL有一個特殊的空安全同性檢查操作:

< =>

NULL安全等。該運算符與=運算符執行相等比較,但如果兩個操作數 都爲NULL,則返回1而不是NULL;如果一個操作數爲NULL,則返回0而不是NULL。

mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL; 
     -> 1, 1, 0 
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL; 
     -> 1, NULL, NULL 

您可以使用該操作符與NOT運算符:

mysql> SELECT NOT (1 <=> 1), NOT (NULL <=> NULL), NOT (1 <=> NULL); 
     -> 0, 0, 1 

所以,你的情況,你應該寫:

IF NOT (OLD.assignedto <=> NEW.assignedto) 
+0

最有用的答案這個問題! +1 – djmj