MySQL 触发器不完全有效

MySQL Trigger not entirely working

我的触发器没有错误地返回。但是当我测试它时,没有返回错误消息并且测试数据存储在 table.. 这不是我想要的。

基本上(这是为了课程作业),我想要一个触发器,当插入 Barcelona 以外的位置时显示错误消息进入 table.

这是我的触发器。正如我所说,没有错误返回,但它不起作用?

DELIMITER $$

CREATE TRIGGER after_location_insert_finance
AFTER INSERT ON Finance
FOR EACH ROW

BEGIN  
DECLARE LocationTrigger varchar(255);  
DECLARE msg varchar(255);  

SELECT Location INTO LocationTrigger  
FROM Finance  
WHERE Location != "Barcelona";  

IF(LocationTrigger != "Barcelona") THEN  
SIGNAL SQLSTATE '45000'  
SET MESSAGE_TEXT = 'Not a valid location';  
END IF;

END$$

如果 LocationTrigger 为空,IF 中的表达式将不会计算为 TRUE。

如果 Boss 中没有满足 WHERE 子句条件的行,LocationTrigger 将为 NULL。

我不明白为什么没有检查插入到 location 列中的值;或者当我们比较 'Barcelona'.

的字面值时,为什么我们 运行 是 Boss table 的查询

似乎我们希望在 BEFORE 触发器而不是 AFTER 触发器中进行这种检查。

我们要允许 location 的 NULL 值吗?

如果我们允许为 location 插入的唯一值是 'Barcelona',并且如果我们不允许 NULL 值,那么我们不需要搞乱任何查询Boss table。做个对比...

 BEGIN
    IF NOT ( NEW.location <=> 'Barcelona' ) THEN
       SIGNAL ...
    END IF;
 END

也许触发器的目标是实施参照完整性约束(我们通常通过声明 FOREIGN KEY 约束来实施,而不是实施过程。)

假设 "valid" 位置由 Boss table、

location 个值的域定义

假设我们不允许 NULL 值,那么:

BEGIN
   DECLARE ls_location  VARCHAR(255) DEFAULT NULL;
   -- check if the value being inserted exists in a lookup table
   SELECT b.location INTO ls_location
     FROM Boss b
    WHERE b.location = NEW.location
    LIMIT 1 
   ;
   -- if we didn't find a match, ls_location will be NULL
   IF ls_location IS NULL THEN 
      SIGNAL ... 
   END IF;
END

如果在 Boss 中找不到匹配的行,则 ls_location 将为 NULL。

"not equals" 与 NULL 的比较将计算为 NULL,而不是 TRUE 或 FALSE。

布尔逻辑 SQL 是三值... TRUE、FALSE 和 NULL

 SELECT 0     = 1      AS c0
      , 0    <> 1      AS c1
      , 0     = NULL   AS c2
      , 0    <> NULL   AS c3
      , NULL  = NULL   AS c4
      , NULL <> NULL   AS c5