2014-10-02 128 views
0

我有一個存儲過程,我試圖在查詢窗口中調試它...當我打開存儲過程,我在代碼中設置了一些斷點,但他們從來沒有得到在下面的代碼中,我可以遍歷USE行,然後設置ANSI_NULLS ON,然後代碼只是說成功執行了命令,即使我在它下面的所有代碼中都設置了斷點。我錯過了什麼?在MS SQL服務器2008中調試存儲過程

USE [Tool1] 
GO 
/****** Object: StoredProcedure [dbo].[aspdnsf_ImportProductPricing_XML] Script Date: 10/02/2014 09:38:17 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 


Alter proc [dbo].[aspdnsf_ImportProductPricing_XML] 
    @pricing ntext 

AS 
BEGIN 
SET NOCOUNT ON 

CREATE TABLE #tmp (ProductID int, VariantID int, KitItemID int, Name nvarchar(400), KitGroup nvarchar(800), SKU nvarchar(50), SKUSuffix nvarchar(50), ManufacturerPartNumber nvarchar(50), Cost money, MSRP money, Price money, SalePrice money, Inventory int) 
DECLARE @hdoc int, @retcode int 
EXEC @retcode = sp_xml_preparedocument 
        @hdoc OUTPUT, 
        @pricing 

INSERT #tmp 
SELECT * 
FROM OPENXML(@hdoc, '/productlist/productvariant', 2) 
     WITH (ProductID int, VariantID int, KitItemID int, Name nvarchar(400), KitGroup nvarchar(800), SKU nvarchar(50), SKUSuffix nvarchar(50), ManufacturerPartNumber nvarchar(50), Cost money, MSRP money, Price money, SalePrice money, Inventory int) 


UPDATE dbo.ProductVariant 
SET Price = t.Price, 
    SalePrice = nullif(t.SalePrice,0), 
    Inventory = t.Inventory, 
    Cost = t.cost 
FROM dbo.ProductVariant p 
    join #tmp t on p.ProductID = t.ProductID and p.VariantID = t.VariantID 
WHERE KitItemID = 0 


UPDATE dbo.KitItem 
SET PriceDelta = t.Price 
FROM dbo.KitItem k 
    join #tmp t on k.KitItemID = t.KitItemID 
WHERE t.KitItemID > 0 



exec sp_xml_removedocument @hdoc 

DROP TABLE #tmp 
END 
+3

調試在SQL Server存儲過程中相當沒用,特別是當涉及到#temp表時。你有沒有考慮過古老的'PRINT'和'SELECT'? – 2014-10-02 14:02:57

回答

1

當您調試存儲過程時,您必須爲該過程準備exec語句。您可以在其上設置斷點,然後使用運行按鈕開始調試。當你進入程序時,新的窗口將被打開。在那個窗口中設置斷點。他們會工作。

+0

調試時可以在「斷點」查看臨時表的內容嗎? – 2014-10-02 14:06:51

+0

@PhilipKelley在'DEBUG'中,你可以看到過程和局部變量的流程。要查看錶格的內容,您必須使用臨時的'SELECT'語句。所以從這一點我同意@AaronBertrand的評論。但是,如果您需要'DEBUG'觸發器來觸發另一個觸發器,那麼使用SSMS'DEBUG'有時會很有用。 – 2014-10-02 14:10:20

+0

這個工作完美,事後我覺得很愚蠢的嘗試調試一個ALTER語句。 – user3267755 2014-10-02 14:53:01

0

幾年前我放棄了對SQL的調試,很遺憾聽到它甚至在最新版本中都沒有改進。下面是調試存儲過程時使用的tatcic的概述,它可能會幫助您,也可能不會幫助您。

首先,將代碼剪切並粘貼到新的「工作」窗口。

運行任何必要的特殊格式化命令,例如,

USE [Tool1] 
GO 
/****** Object: StoredProcedure [dbo].[aspdnsf_ImportProductPricing_XML] Script Date: 10/02/2014 09:38:17 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

接下來,註釋掉都記錄下來通過創建(或改變)過程語句,就像這樣:

--USE [Tool1] 
--GO 
--/****** Object: StoredProcedure [dbo].[aspdnsf_ImportProductPricing_XML] Script Date: 10/02/2014 09:38:17 ******/ 
--SET ANSI_NULLS ON 
--GO 
--SET QUOTED_IDENTIFIER ON 
--GO 


--Alter proc [dbo].[aspdnsf_ImportProductPricing_XML] 
-- @pricing ntext 

如果有參數,撲通一聲倒在他們面前的一個DECLARE聲明,並刪除任何output設置。

更換AS語句與SET的值對於每個參數,並且使用這些來設置測試值

從那裏,通過代碼的一部分向下滾動,突出顯示該點和前面的所有文本(移+控制+家)並執行(F5),並觀察發生了什麼。插入PRINT和SELECT語句並根據需要重複,慢慢增加每次調用執行多少代碼,或者在可能的情況下只運行少數幾行代碼。 (這就是爲什麼在SQL中進行真實世界調試真的很不錯,而且我沒有看到發生這種情況,部分原因是由於@Temp表和部分原因是BEGIN TRANSACTION/EXECUTE/GOTO午餐/ ROLLBACK),但我離題了。其中一個問題就是你的#Temp表。在第一次傳遞時,它會被創建,隨後的所有傳遞都會得到「表已存在」錯誤。懶惰(因爲它不工作,你運行它第一次)解決方法:

DROP TABLE #tmp 
CREATE TABLE #tmp (ProductID int, <etc>) 

模糊變通:

IF object_id('tempdb..#Tmp') is not null 
    DROP TABLE #tmp 

CREATE TABLE #tmp (ProductID int) 

sp_xml_preparedocument/sp_xml_removedocument將是另一種疑難雜症。不知道該如何處理,我們在年前爲Xquery提供了。

+0

[對於使用局部變量與參數非常小心](http://www.brentozar.com/archive/2014/06/tuning-stored-procedures-local-variables-problems/)。 – 2014-10-02 14:50:27