MySQL - 在插入之前触发+如果数据已经存在+枚举列

时间:2014-02-27 09:28:21

标签: mysql sql

我正在制作一个触发器,虽然我很容易并且应该可以正常工作但是它无效。

这是(抽象)表结构:

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',如果status已设置在INSERT 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

1 个答案:

答案 0 :(得分: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。可能会预先填充第一个枚举值。