导致 INSERT 失败的触发器? 可能的?
在清理这个答案 我了解了一些关于 MySQL 中的 TRIGGER
和存储过程的知识,但令我惊讶的是,BEFORE INSERT
和 BEFORE UPDATE
触发器可以修改数据,它们似乎无法导致插入/更新失败(即验证)。 在这种特殊情况下,我能够通过以导致主键重复的方式操作数据来使其工作,这在这种特殊情况下是有意义的,但在一般意义上不一定有意义。
MySQL 中可以实现这种功能吗? 在任何其他 RDBMS 中(遗憾的是我的经验仅限于 MySQL)? 也许是 THROW EXCEPTION
风格的语法?
In cleaning up this answer I learnt a bit about TRIGGER
s and stored procedures in MySQL, but was stunned that, while BEFORE INSERT
and BEFORE UPDATE
triggers could modify data, they seemingly couldn't cause the insert/update to fail (ie. validation). In this particular case I was able to get this to work by manipulating the data in such a way as to cause a primary key duplicate, which in this particular case made sense, but doesn't necessarily make sense in a general sense.
Is this sort of functionality possible in MySQL? In any other RDBMS (my experience is limited to MySQL sadly)? Perhaps a THROW EXCEPTION
style syntax?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
从这个博客文章
From this blog post
这是我的做法。 请注意
SET NEW='some error';
。 MySQL 会告诉你“变量‘new’不能设置为‘错误:无法删除此项目。销售表中有包含此项目的记录。’”你可以在代码中捕获此内容,然后显示结果错误:)
Here is the way I did it. Note the
SET NEW='some error';
. MySQL will tell you "Variable 'new' can't be set to the value of 'Error: Cannot delete this item. There are records in the sales table with this item.'"You can trap this in your code and then show the resulting error :)
因为当我在 MySQL 触发器中搜索错误处理时,这篇文章出现在顶部,所以我想我应该分享一些知识。
如果出现错误,您可以强制 MySQL 使用 SIGNAL,但如果您不将其指定为 SQLEXCEPTION 类,那么什么都不会发生,因为并非所有 SQLSTATE 都被认为是坏的,即使如此,您也必须确保 RESIGNAL 如果您有任何嵌套的 BEGIN/END 块。
或者,可能更简单,在触发器中声明一个退出处理程序并重新发出异常信号。
如果你的身体发生错误,它会被抛回顶部并错误退出。 这也可以用于存储过程等。
这适用于任何 5.5+ 版本。
Because this article comes up towards the top when I search for error handling in MySQL triggers, I thought I'd share some knowledge.
If there is an error, you can force MySQL to use a SIGNAL, but if you don't specify it as a class as SQLEXCEPTION, then nothing will happen, as not all SQLSTATEs are considered bad, and even then you'd have to make sure to RESIGNAL if you have any nested BEGIN/END blocks.
Alternatively, and probably simpler still, within your trigger, declare an exit handler and resignal the exception.
And if in your body there occurs an error, it will be thrown back up to the top and exit with an error. This can also be used in stored procedures and whatnot.
This works with anything version 5.5+.
这将通过引发异常来中止您的 INSERT(来自 http://www.experts -exchange.com/Database/MySQL/Q_23788965.html)
用法:
This will abort your INSERT by raising an exception (from http://www.experts-exchange.com/Database/MySQL/Q_23788965.html)
Usage:
不适用于触发器
(存储函数或触发器中不允许使用动态 SQL)
我使用了一个非常肮脏的解决方案:
If NEW.test=1 then
调用TEST_CANNOT_BE_SET_TO_1;
万一;
当 test=1 时,Mysql 抛出以下异常:
PROCEDURE administratie.TEST_CANNOT_BE_SET_TO_1 不存在
不复杂,但快速且有用。
Doen't work in triggers
(Dynamic SQL is not allowed in stored function or trigger)
I use a very dirty solution:
If NEW.test=1 then
CALL TEST_CANNOT_BE_SET_TO_1;
end if;
When test=1 Mysql throws the following exception:
PROCEDURE administratie.TEST_CANNOT_BE_SET_TO_1 does not exist
Not sophisticated but fast and usefull.
在 MS SQL 中,您可以使用正确的语法使其工作:
http://msdn. microsoft.com/en-us/magazine/cc164047.aspx
in MS SQL you could make it work using proper syntax:
http://msdn.microsoft.com/en-us/magazine/cc164047.aspx