Sql server 如何在SQL代理中公开有关存储过程失败的更多信息
我有一个SQL代理作业设置,在该作业中有一个执行存储过程的步骤。如果存储的进程失败,那么SQL代理作业将显示一条错误消息,但没有其他信息。类似stacktrace或者至少是正在运行的存储过程和行号的东西会非常有用 e、 g。 如果执行以下存储过程,则会出现错误消息,如“以用户身份执行:NT授权\网络服务。启动[SQLSTATE 01000](消息0)无效的对象名称“不存在”。[SQLSTATE 42S02](错误208)。步骤失败。”没有指示故障发生的确切位置Sql server 如何在SQL代理中公开有关存储过程失败的更多信息,sql-server,error-handling,sql-server-agent,Sql Server,Error Handling,Sql Server Agent,我有一个SQL代理作业设置,在该作业中有一个执行存储过程的步骤。如果存储的进程失败,那么SQL代理作业将显示一条错误消息,但没有其他信息。类似stacktrace或者至少是正在运行的存储过程和行号的东西会非常有用 e、 g。 如果执行以下存储过程,则会出现错误消息,如“以用户身份执行:NT授权\网络服务。启动[SQLSTATE 01000](消息0)无效的对象名称“不存在”。[SQLSTATE 42S02](错误208)。步骤失败。”没有指示故障发生的确切位置 CREATE PROCEDURE
CREATE PROCEDURE TestSpLogging AS
BEGIN
PRINT 'Start'
SELECT * FROM NonExistentTable
PRINT 'End'
END
公开此信息的最佳方法是什么?一种方法是在存储过程中添加一些错误处理。这里有一个简单的方法,我们在这里用的是这样的
declare
@Error int
,@ErrorMsg varchar(1000)
,@StepName varchar(500)
,@ProcedureName sysname
,@dtDateTime datetime
select @ProcedureName = object_name(@@procid)
begin try
select @StepName = 'Step 01: Select from table
PRINT 'Start'
SELECT * FROM NonExistentTable
PRINT 'End'
end try
begin catch
select @Error = @@ERROR
set @ErrorMsg = @ProcedureName + ' Error: ' + @StepName
+ ', dbErrorNbr:' + IsNull(convert(varchar(10),@Error),'Null')
raiserror (@ErrorMsg, 16, 1) with nowait
end catch
一种方法是向存储过程中添加一些错误处理。这里有一个简单的方法,我们在这里用的是这样的
declare
@Error int
,@ErrorMsg varchar(1000)
,@StepName varchar(500)
,@ProcedureName sysname
,@dtDateTime datetime
select @ProcedureName = object_name(@@procid)
begin try
select @StepName = 'Step 01: Select from table
PRINT 'Start'
SELECT * FROM NonExistentTable
PRINT 'End'
end try
begin catch
select @Error = @@ERROR
set @ErrorMsg = @ProcedureName + ' Error: ' + @StepName
+ ', dbErrorNbr:' + IsNull(convert(varchar(10),@Error),'Null')
raiserror (@ErrorMsg, 16, 1) with nowait
end catch
到目前为止,使用上详述的方法似乎已经足够有效。它只需要更新顶级存储过程,并将失败的存储过程的名称和行号输出到SQL代理 输出错误如下所示: 以用户身份执行:NT授权\网络服务。***[InnerStoredProc2],5。错误208:无效的对象名称“不存在表”。[SQLSTATE 42000](错误50000)启动[SQLSTATE 01000](错误0)。步骤失败了 步骤摘要: 创建以下错误处理程序存储过程:
CREATE PROCEDURE error_handler_sp AS
DECLARE @errmsg nvarchar(2048),
@severity tinyint,
@state tinyint,
@errno int,
@proc sysname,
@lineno int
SELECT @errmsg = error_message(), @severity = error_severity(), -- 10
@state = error_state(), @errno = error_number(),
@proc = error_procedure(), @lineno = error_line()
IF @errmsg NOT LIKE '***%' -- 11
BEGIN
SELECT @errmsg = '*** ' + coalesce(quotename(@proc), '<dynamic SQL>') +
', ' + ltrim(str(@lineno)) + '. Errno ' +
ltrim(str(@errno)) + ': ' + @errmsg
RAISERROR(@errmsg, @severity, @state)
END
ELSE
RAISERROR(@errmsg, @severity, @state)
go
到目前为止,使用上详述的方法似乎已经足够有效。它只需要更新顶级存储过程,并将失败的存储过程的名称和行号输出到SQL代理 输出错误如下所示: 以用户身份执行:NT授权\网络服务。***[InnerStoredProc2],5。错误208:无效的对象名称“不存在表”。[SQLSTATE 42000](错误50000)启动[SQLSTATE 01000](错误0)。步骤失败了 步骤摘要: 创建以下错误处理程序存储过程:
CREATE PROCEDURE error_handler_sp AS
DECLARE @errmsg nvarchar(2048),
@severity tinyint,
@state tinyint,
@errno int,
@proc sysname,
@lineno int
SELECT @errmsg = error_message(), @severity = error_severity(), -- 10
@state = error_state(), @errno = error_number(),
@proc = error_procedure(), @lineno = error_line()
IF @errmsg NOT LIKE '***%' -- 11
BEGIN
SELECT @errmsg = '*** ' + coalesce(quotename(@proc), '<dynamic SQL>') +
', ' + ltrim(str(@lineno)) + '. Errno ' +
ltrim(str(@errno)) + ': ' + @errmsg
RAISERROR(@errmsg, @severity, @state)
END
ELSE
RAISERROR(@errmsg, @severity, @state)
go
这会起作用,但可能需要对现有代码库进行大量更改,例如,如果存储过程调用其他存储过程,而其他存储过程又调用了其他过程,并且每个存储过程执行了许多步骤,则需要在整个代码中添加此逻辑。这会起作用,但可能需要对现有代码库进行大量更改,例如。如果存储的proc调用了其他存储的proc,而其他存储的proc又调用了其他存储的proc,并且每个存储的proc执行了许多步骤,那么您需要在整个代码中添加此逻辑。