在SQL上删除触发器之前。

时间:2014-05-01 12:18:56

标签: mysql sql triggers

我正在尝试创建一个delete触发器,因此,如果用户输入了错误的id,他会收到一条错误消息。
我使用了以下代码......

CREATE TRIGGER pos_id
BEFORE DELETE ON CLIENTS 
FOR EACH ROW 
BEGIN 

DECLARE TOTAL INT;
SET TOTAL = ( SELECT COUNT( * ) FROM CLIENTS ) ;

IF( old.id <0 OR old.id > total ) 
  THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error. Client doesn't exist';

END IF ;
END

此外,它不起作用。消息未出现,触发器似乎不起作用。当我在互联网上寻找解决问题的方法时,我学会了触摸,而不是触发器,我发现它非常有趣。

但是当我尝试......

 CREATE TRIGGER pos_id
    INSTEAD OF DELETE ON CLIENTS 
    BEGIN
(...)

...或

CREATE TRIGGER pos_id
ON CLIENTS 
INSTEAD OF DELETE
BEGIN
(...)

我得到syntax error。所以我真的有两个问题:

1º为什么我之前的删除触发器不起作用?我真的错过了什么吗? 2º与删除触发器相关的语法错误是什么?

非常感谢你。

1 个答案:

答案 0 :(得分:0)

你不能用触发器做到这一点。触发器只会触发至少与一行匹配的删除,因此如果用户尝试删除不存在的客户端而不是获取自定义错误,他们就会得到这个:

mysql > delete from clients where id = -1;
Query OK, 0 rows affected (0.00 sec)

此外,您应该明确检查行的存在,而不是依赖于输入是否小于零或大于表中的行计数等。此外,您需要在错误消息中转义撇号。

您可以使用存储过程完成此操作。如果您可以使用存储过程让用户删除行而不是对客户端表执行显式删除,那么您可以抛出自定义错误。

例如(我不知道id列的数据类型。我假设为int,但您应该更改它以匹配表中的实际数据类型):

delimiter $$

drop procedure if exists delete_client $$

create procedure delete_client (p_client_id int) 
begin
  declare v_client_exists int default 0;

  select count(*)
  into v_client_exists
  from clients 
  where id = p_client_id;

   if (v_client_exists = 0)
   then
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error. Client doesn''t exist';
   else
     delete from clients where id = p_client_id;
   end if;

end $$

delimiter ;

然后执行删除操作:

mysql > call delete_client(-1);
ERROR 1644 (45000): Error. Client doesn't exist
mysql > call delete_client(2);
Query OK, 1 row affected (0.00 sec)
mysql > call delete_client(2);
ERROR 1644 (45000): Error. Client doesn't exist