2014-02-26 35 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值。