2014-02-26 31 views
12

我有一个表t,它有一个名为“trgInsAfter”的“插入后”触发器。到底如何调试它?我不是这方面的专家,所以执行的问题和步骤可能看起来很愚蠢。如何调试T-SQL触发器?

我到目前为止执行的步骤是:1。 连接到server instance通过SSMS(使用Windows管理员帐户)

  1. 右击从SSMS左手树,双击触发节点打开它,触发器的代码在一个新的查询窗口被打开(称之为窗口-1)为:等等...,

    ALTER TRIGGER trgInsAfter AS .... BEGIN ... END 
    
  2. 打开另一个查询窗口(称之为窗口-2),输入sql来插入一个行到表T:

    insert t(c1,c2) values(1,'aaa') 
    
  3. 设置断点在窗口-1(在触发器的代码)

  4. 设置断点在窗口-2(插入SQL代码)

  5. 单击工具栏上的Debug按钮,而窗口-2是当前窗口

    插入SQL代码的断点命中,但是当我看到窗口-1,在触发代码断点有一个提示说'unable to bind SQL breakpoint, object containing the breakpoint not loaded'

我有点明白的问题:SSMS怎么能知道,在窗口-1中的代码是触发

我要调试?我看不到在哪里告诉SSMS'嘿,这个查询编辑器中的代码是表t的inssert触发器的代码'

有什么建议吗?

感谢

+0

http://timwise.blogspot.co.uk/2012/05/debugging-stored-procedures-in-vs2010.html –

回答

24

你实际上在想这个。

我第一次在一个窗口中运行此查询(设置的东西了):

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

完美,F11做到了! 猜测我一直在使用C++/C#代码太长时间,并养成了加载所有相关源代码文件和预设断点的习惯:( – bondijct

+0

只是想在包含触发器源代码的自动弹出窗口中添加该代码代码,其路径格式如下: 'mssql :: // mywin7pc \ bdsql/mydemodb /?/ = 338100245' \ / /?/=编号 – bondijct

+0

不幸的是,我无法在虚拟表中看到“插入”和“删除”的值 – Santhos

3

有SSMS中调试菜单,但你可能需要在服务器上,以便能够调试,所以如果是远程访问,它的正确建立不起来吧。 该调试选项将允许您执行代码,并进入您的触发器并以此方式进行调试(因为您可以调试大多数其他代码)。

Debug menu

如果没有进入调试菜单/功能,你必须调试“手动”:

首先确保您的触发器是通过将触发输入到一个运行正常调试表。然后你可以验证它的调用是否正确。 然后,您可以像使用调试表中的值一样调试触发器的查询,就像调用任何其他sql查询一样。

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轻松关闭调试插入;或者完全删除调试代码。

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 

其中创建的表称为临时用exaclty列名和INSERTED值。