我有一个表t,它有一个名为trgInsAfter的“after insert”触发器。究竟我该如何调试呢?我不是这方面的专家,因此所执行的问题和步骤可能看起来很愚蠢。
到目前为止我执行的步骤是:
1.通过server instance
(使用Windows管理员帐户)
SSMS
右键单击SSMS左侧树中的触发节点,然后双击打开它,触发器的代码在新的查询窗口中打开(调用此Window-1),如下所示:blah .... ,
ALTER TRIGGER trgInsAfter AS .... BEGIN ... END
打开另一个查询窗口(调用此Window-2),输入sql将一行插入表t:
insert t(c1,c2) values(1,'aaa')
在Window-1中设置断点(在触发器代码中)
在Window-2(插入SQL代码)
单击工具栏上的“调试”按钮,而“窗口2”是当前窗口
插入SQL代码的断点被命中,但是当我查看Window-1时,触发器代码中的断点有一个工具提示'unable to bind SQL breakpoint, object containing the breakpoint not loaded'
我可以理解这个问题:SSMS
如何知道Window-1中的代码是触发器
我想调试?我不知道在哪里告诉SSMS'嘿,这个查询编辑器中的代码是表t的inssert触发器的代码'
有什么建议吗?
由于
答案 0 :(得分:32)
你实际上是在考虑这个。
我首先在一个窗口中运行此查询(进行设置):
create table X(ID int not null)
create table Y(ID int not null)
go
create trigger T_X on X
after insert
as
insert into Y(ID) select inserted.ID
go
然后我可以丢弃那个窗口。我打开一个新的查询窗口,写:
insert into X(ID) values (1),(2)
并在该行设置断点。然后我启动调试器(Debug
从菜单或工具栏或Alt-F5)并等待(一段时间,调试器从未太快),以便它命中该断点。然后,在那里,我选择了Step Into
(F11)。并且(稍微等待之后)打开一个新窗口,这是我的触发器,调试器停止的下一行代码是触发器中的insert into Y...
行。我现在可以在触发器中设置我想要的任何其他断点。
答案 1 :(得分:2)
SSMS中有一个DEBUG菜单,但您可能需要在服务器上才能进行调试,因此如果是远程访问,则无法正确设置它。 该调试选项将允许您执行代码,并以此方式进入触发器并进行调试(因为您调试了大多数其他代码)。
如果无法访问调试菜单/功能,则必须“手动”调试:
首先通过将触发器的输入插入调试表来确保触发器正常运行。然后你可以验证它被正确调用。 然后,您可以使用调试表中的值调试触发器的查询,就像调整任何其他SQL查询一样。
答案 2 :(得分:0)
无论出于何种原因,我都无法获得@ Damien_The_Unbeliever的解决方案。
至少,不是附加到表的触发器。当我执行Step Into
时,它每次都执行查询而不会进入触发器。
然后我在该方法的评论中注意到,无论如何你都看不到任何表值。
所以......
我最终创建了一个通用的调试表。
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_Table的任何变量。
完成调试后,您可以通过将@debugOn
变量更改为0
来轻松关闭调试插入,以防将来需要再次调试;或者只是完全删除调试代码。
答案 3 :(得分:0)
我也无法Step Into
,它会直接超过INSTEAD OF INSERT
触发器。所以我最终用以下方法替换了触发器:
ALTER TRIGGER [MyView_Instead_Insert]
ON [MyView]
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON
select * into temp from INSERTED
END
创建了一个名为temp的表,其中包含INSERTED
的列名和值的exaclty。