我试图创建一个 before 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
(...)
我收到语法错误
。所以我真的有两个问题:
1º 为什么我的删除前触发器不起作用?我真的错过了什么吗?
2° 与代替删除触发器相关的语法错误是什么?
非常感谢。
最佳答案
你不能用触发器来做到这一点。触发器只会在与至少一行匹配的删除时触发,因此,如果用户尝试删除不存在的客户端而不是收到您的自定义错误,他们只会收到以下消息:
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
关于mysql - 在 SQL 上删除触发器之前。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23407520/