SQL 知道如果触发器失败,哪个语句激活了触发器

本文关键字:触发器 语句 激活 活了 失败 如果 SQL | 更新日期: 2023-09-27 17:57:14

我在C#应用程序中使用SQL Server,并且正在使用批处理语句。我遇到的问题是在语句失败的情况下,无论出于何种原因,我都需要知道哪个语句失败并返回它。

我已经设法通过在 SQL 语句周围放置一个try catch来做到这一点(因此如果失败它不会退出),然后 C# cmd.ExecuteQuery返回受影响的行数。

我现在遇到的问题是,如果由于触发器而发生故障,则触发器在原始批处理的try catch之外,因此不会被捕获,而是会被 C# 应用程序捕获。此时,批处理的状态处于不确定状态,整个事情失败。

我需要某种方法来知道哪个语句(或到目前为止受影响的行数,或批处理中的索引)触发了导致异常的触发器。无论我在SQL还是C#中可以做些什么,我都对任何事情持开放态度。

谢谢。

SQL 知道如果触发器失败,哪个语句激活了触发器

这不是

一个答案,但它太大了,无法发表评论,需要格式化。

假设我有一个语句,例如 开始尝试插入爵士手值 (2) 结束尝试开始捕捉结束捕获。如果表 JAZZHANDS 有一个触发器,可以插入其他表格中的任何内容,如果该触发器失败,它将不会循环回来并从原始插入中被捕获到 CATCH 中。交易完全失败

我不知道你为什么这么想。以下 SQL:

create table JazzHands (ID int not null,constraint CK_ID_JH CHECK (ID < 10))
go
create table JazzHands2 (ID int not null,constraint CK_ID_JH2 CHECK (ID < 5))
go
create trigger T_JazzHands on JazzHands after insert
as
    insert into JazzHands2(ID)
    select ID from inserted
go
--1
begin try
    insert into JazzHands (ID) values (11)
    PRINT 'No error 1'
end try
begin catch
    Print 'error 1'
end catch
go
--2
begin try
    insert into JazzHands (ID) values (6)
    PRINT 'No error 2'
end try
begin catch
    Print 'error 2'
end catch
go
--3
begin try
    insert into JazzHands (ID) values (1)
    PRINT 'No error 3'
end try
begin catch
    Print 'error 3'
end catch
go

生产:

(0 row(s) affected)
error 1
(0 row(s) affected)
(0 row(s) affected)
error 2
(1 row(s) affected)
(1 row(s) affected)
No error 3

两个表都包含一行。与您的断言相反,当表本身中的某些内容阻止插入成功,或者表上的触发器中的某些内容阻止插入成功时,会发生完全相同的错误处理,并且通常无法区分。


如果您确实有一个实际示例,其中触发器的失败与直接在表格上的失败产生的行为不同,请将此类示例编辑到您的问题中。

你要找的是最后一句话,对吧?您可以通过调用 DBCC INPUTBUFFER 从触发器内部获取此信息。

另请参阅这是否有帮助:

SELECT session_id, TEXT
FROM sys.dm_exec_connections
CROSS APPLY sys.dm_exec_sql_text(most_recent_sql_handle) AS ST