创建触发器后的 SQL Server

Posted

技术标签:

【中文标题】创建触发器后的 SQL Server【英文标题】:SQL Server after create trigger 【发布时间】:2013-09-26 16:00:28 【问题描述】:

我有一个创建后触发器,它从插入的行中读取数据,对其进行解析并将其添加到另一个表中。

但是当这个触发器失败时,我的整个插入失败。我的问题是

    为什么创建后触发器被视为插入操作的一部分,即使它在插入完成并检查约束和验证后被触发?

    有什么方法可以将触发器的执行与插入操作分离?

失败可能类似于触发器尝试插入的另一个表上的数据约束违规。即使没有失败,如果触发器在插入事务之外执行,也可以提高事务时间。

【问题讨论】:

这可以通过触发器内部的异常管理来实现,查看此讨论***.com/questions/884334/… “触发失败”是什么意思?你可以再详细一点吗?这里发生的故障类型可以决定您可以采取哪些措施来解决问题。 @AaronBertrand:我已经更新了我的问题。即使触发器没有失败,也可以通过让触发器在插入事务之外自行运行来改进事务时间 @Vimsha 触发器在做什么? @AaronBertrand:触发器解析插入的数据并在另一个表中创建一行。这是一个非常复杂的解析。所以我希望事务不要等到解析完成 【参考方案1】:

为什么在创建触发器之后被视为插入操作的一部分 即使它在插入完成后被触发并且约束和 检查验证?

插入和触发器被视为一个事务。如果失败,则交易失败,因此会回滚以保持数据完整性

有什么方法可以将触发器的执行与插入分离 操作?

您可以将其包装在 try catch 块中。

【讨论】:

既然在事务执行之前会检查数据完整性,为什么一定要成为事务的一部分呢? AFTER specifies that the DML trigger is fired only when all operations specified in the triggering SQL statement have executed successfully. All referential cascade actions and constraint checks also must succeed before this trigger fires. -> 这是来自微软文档【参考方案2】:

您可以使用队列表和后台作业来防止触发器使外部事务失败。成功的只是插入到队列表中。

CREATE TABLE dbo.TriggerProcessingQueue
(
  ...columns...,
  Processed BIT NOT NULL DEFAULT = 0
);

所以现在触发器可以只对这个队列表执行插入操作,并且一些后台作业可以处理Processed = 0 所在的所有行并将它们标记为Processed = 1。现在,当后台作业正在运行时,这可能会稍微干扰触发器,但您可以通过简单地调整作业的计划和/或每次处理的行数来微调它。

您也可以考虑服务代理,但激活过程必须知道要处理哪些数据...

【讨论】:

以上是关于创建触发器后的 SQL Server的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2017 触发器将旧值作为更新后的新值

SQL Server触发器根据导入时的文件名填写值

SQL server与Oracle触发器的创建与使用

SQL server 创建触发器详解

SQL Server 创建触发器(trigger)

SQL Server 创建触发器(trigger)