如何调试T-SQL触发器?
我有一个表t,它有一个名为trgInsAfter的“after insert”触发器。我该如何调试它呢?我不是这方面的专家,所以提出的问题和执行的步骤可能看起来很愚蠢 到目前为止,我执行的步骤包括: 1.通过如何调试T-SQL触发器?,sql,Sql,我有一个表t,它有一个名为trgInsAfter的“after insert”触发器。我该如何调试它呢?我不是这方面的专家,所以提出的问题和执行的步骤可能看起来很愚蠢 到目前为止,我执行的步骤包括: 1.通过SSMS(使用Windows管理员帐户)连接到服务器实例 右键单击SSMS中左侧树中的触发器节点并双击将其打开,触发器的代码将在新的查询窗口(称为该窗口-1)中打开,如下所示:blah ALTER TRIGGER trgInsAfter AS .... BEGIN ... END 打开另
SSMS
(使用Windows管理员帐户)连接到服务器实例
右键单击SSMS中左侧树中的触发器节点并双击将其打开,触发器的代码将在新的查询窗口(称为该窗口-1)中打开,如下所示:blah
ALTER TRIGGER trgInsAfter AS .... BEGIN ... END
打开另一个查询窗口(称此窗口为-2),输入sql以在表t中插入一行:
insert t(c1,c2) values(1,'aaa')
在Window-1(触发器代码)中设置断点
在Window-2中设置断点(插入SQL代码)
当Window-2为当前窗口时,单击工具栏上的“调试”按钮
插入SQL代码的断点被命中,但当我查看Window-1时,触发器代码中的断点有一个工具提示:“无法绑定SQL断点,包含断点的对象未加载”
我可以理解这个问题:SSMS
如何知道Window-1中的代码是触发器
我想调试?我看不出哪里可以告诉SSMS‘嘿,这个查询编辑器中的代码是表t的inssert触发器的代码’
有什么建议吗
谢谢SSMS中有一个调试菜单,但您可能需要在服务器上才能进行调试,因此如果是远程访问,可能不会为其设置。 该调试选项将允许您执行代码,并进入触发器并以这种方式进行调试(就像调试大多数其他代码一样) 如果无法访问调试菜单/功能,则必须“手动”调试: 首先,通过将触发器的输入插入调试表,确保触发器正确运行。然后您可以验证是否正确调用了它。
然后,您可以像调试任何其他sql查询一样,使用调试表中的值调试触发器的查询。您实际上已经考虑过了 我首先在一个窗口中运行此查询(以进行设置): 然后我可以扔掉那扇窗户。我打开一个新的查询窗口,写下:
insert into X(ID) values (1),(2)
并在该行上设置断点。然后,我启动调试器(
Debug
从菜单或工具栏或Alt-F5)并等待(有一段时间,调试器从来都不会太快)使其达到该断点。然后,点击这里,我选择进入(F11)。lo(再等待一小段时间后)会打开一个新窗口,这是我的触发器,调试器停止的下一行代码是触发器中的插入Y…
行。我现在可以在触发器中设置任何进一步的断点。无论出于何种原因,我都无法让@Damien\u异教徒的解决方案起作用。
至少,不是在连接到表的触发器上。当我执行步进
时,它每次只执行查询,而不执行触发器
然后我注意到,在该方法的注释中,您无论如何都看不到任何表值
所以
我最终创建了一个通用调试表
USE [Your_DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Debug_Table](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](60) NOT NULL,
[Value] [sql_variant] NULL,
[Description] [varchar](max) NULL,
[Captured] [datetime] NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
然后在我的扳机里我做了这样的事情
DECLARE @ItemNum nvarchar(128)
SELECT @ItemNum = Item_Number FROM inserted
DECLARE @debugOn as bit = 1
-- Debug
IF @debugOn = 1
BEGIN
INSERT INTO Debug_Table (Name, Value, Description, Captured)
VALUES ( 'Item Number', @ItemNum, 'The item number from the inserted table in tr_VaultItemIterations_ZCode_Monitor.', GETDATE())
END;
-- End Debug
从表中触发触发器后,我可以查看插入到Debug_表中的任何变量
调试完成后,您可以通过将
@debugOn
变量更改为0
轻松关闭调试插入,以防将来需要再次调试;或者干脆完全删除调试代码。我也无法进入,它将直接进入我的而不是插入
触发器。因此,我最终用以下内容替换触发器:
ALTER TRIGGER [MyView_Instead_Insert]
ON [MyView]
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON
select * into temp from INSERTED
END
它创建了一个名为temp的表,其中包含插入的
列名和值 太好了,F11成功了!我想我使用C++/C#代码的时间太长了,习惯于加载所有相关的源代码文件和预设断点:(只想在包含触发器源代码的自动弹出窗口中添加,其路径的格式如下:mssql:://mywin7pc\bdsql/mydemodhb/?/=338100245
\//?/=idSadly,我无法看到虚拟表中的值inserted
和deleted
@Santhos-不仅仅是inserted
>和删除了。你会发现在调试时检查任何表内容都不是一个简单的方法。恐怕调试经验非常缺乏。@Damien_不相信你是完全正确的。我已经决定采取另一种方法,创建一个临时调试表,我正在使用Inserts、时间戳和一些辅助触发器。
ALTER TRIGGER [MyView_Instead_Insert]
ON [MyView]
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON
select * into temp from INSERTED
END