2013-08-28 87 views
3

我知道在删除触发器中没有“NEW”值,所以不确定这是否可能。我试图使用删除触发器之前记录一些值,这工作正常,但我也想阻止删除任何记录,如果用户没有在where子句中指定任何东西。基本上,我不希望他们擦掉整张桌子。 (附代码错误实际上是应用程序开发者)Mysql删除前触发器,防止删除如果没有where子句?

目前我有:

delimiter $$ 
create trigger tg_order_shipping_bd 
before delete on order_shipping 
FOR EACH ROW 
begin 

     insert into order_shipping_log 
     (log_type, inv_nbr, old_tracking_nbr) 
     values ('DEL', OLD.inv_nbr, OLD.tracking_nbr); 

end 
$$ 

那么,有一个聪明的方法来计算受影响的行,如果大于1,防止删除和错误?也许只是重新思考我们如何处理这个问题更好。感谢您的任何建议。

回答

3

这实际上是一个开发者应该只做一次的错误......但是,如果您认为它需要在系统范围内,这是正确的修复方法。没有聪明需要。 (另外,MySQL中的触发器是FOR EACH ROW,所以你的问题的答案是“不是真的”,尽管你可以巧妙地使用一个或两个会话变量来破解它)。

MySQL有一个名为sql_safe_updates的系统变量。

mysql> SET GLOBAL sql_safe_updates = 1; 
Query OK, 0 rows affected (0.00 sec) 

断开并重新连接,以便您的会话获取新的全局值。

mysql> delete from t1; 
ERROR 1175 (HY000): You are using safe update mode and you tried to update 
        a table without a WHERE that uses a KEY column 

当使用命令行客户端,你可以暂时启用此设置只用于此标志的会话:

$ mysql --i-am-a-dummy 

(不,我不是做这件事)。

+0

非常好!我不知道那个!我会考虑到这一点。是的,它不可能发生,我们总是小心谨慎,但如果不检查变量,不会在不知不觉中搞砸。我通常会将记录标记为已删除并使用视图或sproc,或者首先在重要表格上检查值。在这种情况下还可以工作的是更新为NULL,而不是在代码中删除。尽管使用安全更新,这是一个很酷的主意!非常感谢您的意见! – gregthegeek

+1

此外,关于意外删除的主题,这里有一个免费提示...如果您启用了二进制日志记录并将'binlog_format'设置为'row',那么当删除行时,二进制日志实际上包含每个列中的所有列值删除行。在紧急情况下,您可以解析“mysqlbinlog”的输出并重建丢失的内容。根据存储引擎和其他设置的不同,如果'binlog_format'设置为'mixed',这也可能是真实的。 –

+0

啊,太棒了!谢谢! – gregthegeek