MS SQL Server 2014:哪个存储过程是我的错误?

Rob*_*gie 4 sql-server stored-procedures error-handling sql-server-2014

作为 Microsoft SQL Server 2014 上的一三个一般问题,也许我应该已经知道答案,或者甚至可能曾经知道 -

当我的存储过程运行其他存储过程时,如何找出哪个存储过程的代码产生了错误?

是否有一种特殊的方法来处理来自 Transact-SQL 的错误,以标识给定存储过程中的错误位置?

存储过程中的程序代码能否获得它所在过程的名称?

如果这是唯一的方法,我准备将“SET @MyNameIs = N'HastilyWrittenProcedure”放入程序代码中。然后我可以输入“PRINT @MyNameIs + 'break.'。" 在所有的错误处理程序中。

Ste*_*o64 5

使用@@procid获取当前正在执行的例程,使用 object_name() 将 id 转换为名称


Han*_*dyD 5

当我的存储过程运行其他存储过程时,如何找出哪个存储过程的代码产生了错误?

在您的 CATCH 块中,您可以使用ERROR_PROCEDURE()来获取发生错误的过程或触发器的名称。

如果您只是在内部过程的 CATCH 块中使用 THROW,那么您的外部过程可以访问这些系统函数(ERROR_PROCEDURE()、ERROR_LINE() 等)以检索有关外部过程的 CATCH 块中的内部过程失败的信息。

是否有一种特殊的方法来处理来自 Transact-SQL 的错误,以标识给定存储过程中的错误位置?

在您的 CATCH 块中,您可以使用ERROR_LINE()来获取发生错误的过程或触发器的名称。

存储过程中的程序代码能否获得它所在过程的名称?

使用此代码:SELECT OBJECT_NAME(@@PROCID)获取过程本身内的过程名称。

下面是在嵌套过程场景中使用的这些示例


Cra*_*ein 5

使用扩展事件的另一个想法。

创建扩展事件会话以捕获错误

CREATE EVENT SESSION [Track_Errors] ON SERVER 
ADD EVENT sqlserver.error_reported(
    ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_name,sqlserver.is_system,sqlserver.server_instance_name,sqlserver.server_principal_name,sqlserver.sql_text))
ADD TARGET package0.event_file(SET filename=N'D:\some_path\track_errors',max_file_size=(50),max_rollover_files=(5))
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=ON)
GO


ALTER EVENT SESSION [Track_Errors] ON SERVER STATE = START
Run Code Online (Sandbox Code Playgroud)

然后在你的嵌套的存储过程,使用RAISEERRORTHROW打印出扩展事件的消息列存储过程的名称。

RAISERROR ('sp_test_nested_error', 16, 1) WITH NOWAIT
THROW 50000, N'sp_test_nested_error', 1;
Run Code Online (Sandbox Code Playgroud)

下面是我用来测试的两个存储过程

-- nested stored procedure
CREATE procedure [dbo].[sp_test_nested_error]
AS

BEGIN TRY
-- Generate a divide-by-zero error  
  SELECT
    1 / 0 AS Error;
END TRY
BEGIN CATCH
    THROW 50000, N'sp_test_nested_error', 1;
END CATCH;
GO


-- parent stored procedure
CREATE procedure [dbo].[sp_test_proc]
AS

exec sp_test_nested_error
GO
Run Code Online (Sandbox Code Playgroud)

以及由此产生的扩展事件输出

在此处输入图片说明