根据我的经验,它们不是一个好主意,因为它们可能会导致令人惊讶的副作用,并且很难调试(特别是当一个触发器触发另一个触发器时)。通常情况下,开发人员甚至不会考虑是否存在触发因素。
另一方面,如果每次在数据库中创建新FOO时都必须执行逻辑,那么将其放在FOO表上的插入触发器可能是最安全的地方。
我们唯一使用触发器的时候是非常简单的事情,比如设置一行的修改日期字段。
我正在努力弄清楚触发器是否有必要,并感谢任何建议。如果它们是必要的,在实施它们时要考虑的最重要的问题是什么?
根据我的经验,它们不是一个好主意,因为它们可能会导致令人惊讶的副作用,并且很难调试(特别是当一个触发器触发另一个触发器时)。通常情况下,开发人员甚至不会考虑是否存在触发因素。
另一方面,如果每次在数据库中创建新FOO时都必须执行逻辑,那么将其放在FOO表上的插入触发器可能是最安全的地方。
我们唯一使用触发器的时候是非常简单的事情,比如设置一行的修改日期字段。
我正在努力弄清楚触发器是否有必要,并感谢任何建议。如果它们是必要的,在实施它们时要考虑的最重要的问题是什么?
当前回答
我认为它们可以是邪恶的,但只能和其他正在开发的东西一样邪恶。
虽然我并没有太多使用它们的经验,但我在最近的一个项目中使用了它们,这让我得出了这个结论。我遇到的问题是,它们可能导致业务逻辑在两个位置结束,一个代码库和一个数据库。
我认为这与使用scprocs类似。您经常会遇到一些开发人员,他们非常擅长将业务逻辑写入SQL到数据库中,而那些不擅长的人将业务逻辑放在其他地方。
所以我的经验法则是看看你项目的结构是什么。如果在数据库中存储业务逻辑似乎是可行的,那么使用触发器可能是有用的。
其他回答
这个答案特别适用于SQL Server。(虽然它也可能适用于其他rdbms,我不知道。我更愿意在这里给出一个答案,但这是一个抄袭。)
到目前为止,所有答案中都没有提到的一个方面是安全性。因为在默认情况下,触发器是在执行触发触发器的语句的用户的上下文中执行的,这可能会导致安全威胁,除非检查所有触发器。
在BOL中“管理触发器安全性”标题下给出的示例是一个用户创建了一个包含代码GRANT CONTROL SERVER TO JohnDoe的触发器;以便升级自己的权限。
触发器的主要问题是
它们是完全全局的——无论表活动的上下文是什么,它们都适用; 他们是隐秘的;你很容易忘记他们的存在,直到他们用意想不到的(非常神秘的)后果伤害了你。
这只是意味着它们需要在适当的情况下谨慎使用;在我的经验中,这仅限于关系完整性问题(有时比您可以声明的粒度更细);而且通常不是出于商业或交易目的。YMMV。
说他们是邪恶的是一种夸张,但他们可以引起网格。当一个触发器触发其他触发器时,情况就变得非常复杂了。让我们假设它们很麻烦:http://www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html
由于多并发问题,在Oracle中使用触发器执行业务逻辑比看起来要难。在其他会话提交之前,您不会在另一个会话中看到更改。
触发器的概念并不邪恶,限制触发器的嵌套是邪恶的。
在高层次上,触发器有两个用例1
1)让事情“自动地”发生。在这种情况下,触发器会产生副作用,它们会以超出预期的方式改变数据,因为执行了(原语)操作符insert、update或delete并导致触发器触发。
这里的普遍共识是,触发器确实有害。因为它们改变了INSERT、UPDATE或DELETE语句的众所周知的语义。更改这三个原语SQL操作符的语义将会对其他开发人员造成不利影响,这些开发人员将来需要对数据库表进行操作,而这些表在使用SQL原语操作时不再以预期的方式运行。
2)执行数据完整性规则,而不是我们可以声明式处理的规则(使用CHECK, PRIMARY KEY, UNIQUE KEY和外键)。在这个用例中,所有触发器所做的就是查询(SELECT)数据,以验证由INSERT/UPDATE/DELETE所做的更改是否被允许。就像声明性约束对我们的作用一样。只有在这种情况下,我们(开发人员)才编写了实施程序。
对于后一种用例,使用触发器是无害的。
我的博客地址是:http://harmfultriggers.blogspot.com