2010-02-07 33 views
3

當我使用usp_RethrowError(作爲Using TRY...CATCH in Transact-SQL文章technet.microsoft站點中的示例給出的示例)時,發出信號有問題。SQL Server:獲取提出錯誤的查詢

有沒有什麼辦法讓這觸發usp_RethrowError過程內這個錯誤的查詢?我還想將查詢文本添加到@ErrorMessage

你可以找到usp_RethrowError存儲過程的代碼如下:

CREATE PROCEDURE usp_RethrowError AS 
    -- Return if there is no error information to retrieve. 
    IF ERROR_NUMBER() IS NULL 
     RETURN; 

    DECLARE 
     @ErrorMessage NVARCHAR(4000), 
     @ErrorNumber  INT, 
     @ErrorSeverity INT, 
     @ErrorState  INT, 
     @ErrorLine  INT, 
     @ErrorProcedure NVARCHAR(200); 

    -- Assign variables to error-handling functions that 
    -- capture information for RAISERROR. 
    SELECT 
     @ErrorNumber = ERROR_NUMBER(), 
     @ErrorSeverity = ERROR_SEVERITY(), 
     @ErrorState = ERROR_STATE(), 
     @ErrorLine = ERROR_LINE(), 
     @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-'); 

    -- Build the message string that will contain original 
    -- error information. 
    SELECT @ErrorMessage = 
     N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' + 
      'Message: '+ ERROR_MESSAGE(); 

    -- Raise an error: msg_str parameter of RAISERROR will contain 
    -- the original error information. 
    RAISERROR 
     (
     @ErrorMessage, 
     @ErrorSeverity, 
     1,    
     @ErrorNumber, -- parameter: original error number. 
     @ErrorSeverity, -- parameter: original error severity. 
     @ErrorState,  -- parameter: original error state. 
     @ErrorProcedure, -- parameter: original error procedure name. 
     @ErrorLine  -- parameter: original error line number. 
     ); 
GO 
+0

這就是ERROR_PROCEDURE()不 – 2010-02-07 02:17:31

+0

是的,但我想整個查詢,包括參數使用... – 2010-02-07 02:25:36

回答

1

不幸的是動態管理視圖仍然使它在這個信息讓困難的,因爲它們存儲SQL_TEXT的程序,而不是用戶實際做了。但是,在這種情況下,DBCC仍然是你的朋友。不是世界上最有效率的東西,但它會找出用戶輸入的內容(而不是程序中的語句),但是這可以揭示錯誤發生時正在使用哪些參數?

ALTER PROCEDURE dbo.usp_RethrowError 
AS 
BEGIN 
    SET NOCOUNT ON; 

    -- Return if there is no error information to retrieve. 
    IF ERROR_NUMBER() IS NULL 
     RETURN; 

    DECLARE 
     @ErrorMessage NVARCHAR(MAX), 
     @ErrorNumber  INT, 
     @ErrorSeverity INT, 
     @ErrorState  INT, 
     @ErrorLine  INT, 
     @ErrorProcedure NVARCHAR(200); 

    -- Assign variables to error-handling functions that 
    -- capture information for RAISERROR. 
    SELECT 
     @ErrorNumber = ERROR_NUMBER(), 
     @ErrorSeverity = ERROR_SEVERITY(), 
     @ErrorState = ERROR_STATE(), 
     @ErrorLine = ERROR_LINE(), 
     @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-'); 

    -- Build the message string that will contain original 
    -- error information. 
    SELECT @ErrorMessage = 
     N'Error %d, Level %d, State %d, Procedure %s, Line %d, ' + 
      'Message: '+ ERROR_MESSAGE(); 

    DECLARE 
     @sql NVARCHAR(255), 
     @original_statement NVARCHAR(MAX); 

    SET @sql = N'DBCC INPUTBUFFER(' + RTRIM(@@SPID) + ');'; 

    CREATE TABLE #dbcc 
    (
     EventType SYSNAME, 
     Parameters INT, 
     EventInfo NVARCHAR(MAX) 
    ); 

    INSERT #DBCC EXEC(@sql); 

    SELECT TOP 1 @original_statement = EventInfo 
     FROM #dbcc; 

    SET @ErrorMessage = @ErrorMessage + N' 
     Original statement: 
     ' + @original_statement + ' 
     '; 

    -- Raise an error: msg_str parameter of RAISERROR will contain 
    -- the original error information. 
    RAISERROR 
     (
     @ErrorMessage, 
     @ErrorSeverity, 
     1,    
     @ErrorNumber, -- parameter: original error number. 
     @ErrorSeverity, -- parameter: original error severity. 
     @ErrorState,  -- parameter: original error state. 
     @ErrorProcedure, -- parameter: original error procedure name. 
     @ErrorLine  -- parameter: original error line number. 
     ); 
END 
GO 
+0

出色答卷! 一個問題:爲什麼'SELECT TOP 1 @original_statement = EventInfo FROM #dbcc;'?爲什麼'TOP 1'?這個'#dbcc'表有多於一行嗎?或者只是爲了確保在設置'@ original_statement'變量時'SELECT TOP 1 @original_statement = EventInfo'不會抱怨? – 2010-02-07 20:04:01

+0

是的我還沒有看到這個DBCC返回多於一行的情況,但你永遠不知道行爲何時會改變。當我編碼的解決方案,我認爲更好的安全比抱歉,而不必看看是否有任何例外的規則。我通常在任何情況下將表結果分配給變量時這樣做,但如果我的藉口是爲了防止未定義的行爲,我可能應該使用ORDER BY。 :-) – 2010-02-07 20:40:01