2014-02-27 75 views
1

我正在處理一個觸發器,雖然我很容易,應該工作,但它不工作。MySQL - 觸發前插入+如果數據已存在+枚舉列

這裏是(摘要)表結構:

PK_id | FK1_id | FK2_id | status 
1  | 12  | 15  | 'ok' 

status列被定義爲與enum('ok', 'ok_2', 'not_ok') NUT NULL沒有默認值。

觸發器應確認兩個FKx_id值的組合已經存在,如果是,應該設置status爲「ok_2」,否則「OK」,如果statusINSERT INTO設置它沒有觸及。

觸發我現在所擁有的(僅機身!):

BEGIN 
    DECLARE cnt INT; 
    SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id); 
    IF cnt > 0 AND NEW.status IS NULL THEN 
     SET NEW.status = 'ok_2'; 
    ELSEIF NEW.status IS NULL THEN 
     SET NEW.status = 'ok'; 
    END IF; 
END 

很不幸,這觸發設置status總是'ok' - 請注意,該status不是INSERT查詢(因此被視爲NULL的一部分)。我以前試過這個觸發器主體具有相同的結果:

BEGIN 
    IF (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id) > 0 AND NEW.status IS NULL THEN 
     SET NEW.status = 'ok_2'; 
    ELSEIF NEW.status IS NULL THEN 
     SET NEW.status = 'ok'; 
    END IF; 
END 

而且這(與非常相同的結果):

BEGIN 
    IF EXISTS(SELECT * FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id LIMIT 1) AND NEW.status IS NULL THEN 
     SET NEW.status = 'ok_2'; 
    ELSEIF NEW.status IS NULL THEN 
     SET NEW.status = 'ok'; 
    END IF; 
END 

誰能告訴我,爲什麼第一個條件是永遠不會滿足,即使我插入表中已經存在的相同組合FKx_id

編輯:我交換條件,結果也是一樣的 - 沒有 'ok_2' 狀態設置:

BEGIN 
    DECLARE cnt INT; 
    SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id); 
    IF cnt = 0 AND NEW.status IS NULL THEN 
     SET NEW.status = 'ok'; 
    ELSEIF NEW.status IS NULL THEN 
     SET NEW.status = 'ok_2'; 
    END IF; 
END 
+0

檢查'status'是否定義爲'status data_type default'''? '空字符串'不等於'null'。 'if(''不爲null,'true','false')'返回一個'true'。 –

+0

當定義爲'default''時,除非你打算爲所述字段插入一個值,否則它將是該字段上定義的*默認值*。 –

+0

'status'沒有默認值,因此當在'INSERT'查詢中省略時,它被認爲是'NULL'。如果不這樣做,那麼即使是第二個條件也不會被滿足,甚至不會插入「ok」。或者會嗎? 'status'是一個'enum('ok','ok_2','not_ok')'...... – shadyyx

回答

1

明白了。

的問題是這個聲明的status列:

status enum('ok', 'ok_2', 'not_ok') NOT NULL 

帶領入status被預填充與第一個枚舉的值,如果status沒有在INSERT語句設置。因此,解決辦法是下一個觸發體:

BEGIN 
    DECLARE cnt INT; 
    SET cnt = (SELECT COUNT(*) FROM `table` WHERE `FK1_id` = NEW.FK1_id AND `FK2_id` = NEW.FK2_id); 
    IF cnt = 0 THEN 
     SET NEW.status = 'ok'; 
    ELSEIF NEW.status = 'ok' THEN 
     SET NEW.status = 'ok_2'; 
    END IF; 
END 

現在,如果我這樣做插入首次

INSERT INTO表(FK_1,FK_2)VALUES(100,150)

的狀態'ok',如果我插入此第二次

INSERT INTO表(FK_1,FK_2)VALUES(100,150)

狀態爲'ok_2'如果我明確設置狀態是這樣的:

INSERT INTO表(FK_1,FK_2,狀態)VALUES(100,150, 'NOT_OK')

狀態爲'not_ok'

因此,當使用沒有默認值的枚舉時,它們被設置爲NOT NULL - 不要指望它們在插入時爲NULL。可能會預先填入第一枚枚舉的值。

+0

嗯。新的教訓... –

+0

當然,我也是:-) – shadyyx

+0

@Ravinder如果這不是一個upvote的理由,我不知道...;) – fancyPants

相關問題