2016-09-15 43 views
0

我有一個插入成千上萬行的存儲過程,如果在任何行中有錯誤的數據,它會失敗。我在while循環中執行插入操作,如果有一種方法可以讓它吐出存儲過程失敗的那一行,那就好了。查詢和循環是這樣:T-SQL找出哪個行導致錯誤

WHILE @rownum > 1 
BEGIN 
    INSERT INTO dbo.bestsellers (id, name, datastring, country) 
    VALUES (@id, @name, @datastring, @country) 
END 

有沒有辦法把它吐出來的@id,@name,@datastring,@country在它被壞數據失敗由於數據?

+0

創建第一清潔數據(try_parse,測試DATALENGTH()等的處理。)然後運行你的過程。或者,您可以讓一個進程刪除將失敗的數據,將其插入到審計表中,然後使用通過檢查的數據運行插入。 – dfundako

+0

這在我的情況下是不可能的 - 這是一個被移交給我的過程,以解決這個存儲過程。另一個原因是@datastring實際上是一個完整的查詢,我不能'解析',直到它在存儲過程中的下一步實際上被執行爲dyn sql。 –

+1

如果可能,您應該考慮重寫這個基於循環的過程,將其作爲一組數據插入。 RBAR(排成行)效率不高。 –

回答

0

您可以使用TRY CATCH結構,並在CATCH塊中引發包含變量的所有值和其中的@rownum的自定義錯誤消息。

+0

- 我需要獲取dbo.bestsellers表中的行的id。 @rownum有些不同,來自不同的表格。我以前從來沒有在tsql中做過try/catch。 –

+0

但是,如果在INSERT上發生錯誤,表中不會有行ID,因爲該行不會被插入。無論如何,你可以得到你想要插入的變量。 –

0

以下try catch塊應該工作:

BEGIN TRY 
    WHILE @rownum > 1 
    BEGIN 
     INSERT INTO dbo.bestsellers (id, name, datastring, country) 
     VALUES (@id, @name, @datastring, @country) 
    END 
END TRY 
BEGIN CATCH 

    PRINT '================================================'; 
    PRINT 'ERROR: @rownum=' + cast(@rownum as varchar) + ' @name=' + @name + ' @datastring=' + @datastring + ' @country=' + @country; 
    PRINT '================================================'; 
    THROW 

END CATCH;