我正在调试从BizTalk调用的存储过程。
在之前的帖子中,有人建议使用sp_trace_generateevent。 [Use SQL Debugger when stored proc called by an external process
因为我需要显示一个变量,所以我想出了以下内容,它可以工作,我可以看到SQL Profiler中的值(使用EventClass = UserConfigurable:0“
Declare @message nvarchar(128)
Set @message = 'Hello World 2 '
exec sp_trace_generateevent @event_class=82, @userinfo = @message
但是当我把它放在问题存储过程中的“BEGIN CATCH”中时,我在profiler中看不到任何内容:
BEGIN CATCH
DECLARE @message nvarchar(128)
SET @message = LTRIM(STR(ERROR_MESSAGE()))
exec sp_trace_generateevent @event_class=82, @userinfo = @message
SET @CatchErrors =
'Catch: [LTL].[CreateShipment] - ErrorNumber: '+LTRIM(STR(ERROR_NUMBER()))
+ ' ErrorSeverity: '+LTRIM(STR(ERROR_SEVERITY()))
+ ' ErrorState: '+LTRIM(STR(ERROR_STATE()))
+ ' ErrorProcedure: '+LTRIM(STR(ERROR_PROCEDURE()))
+ ' ErrorLine: '+LTRIM(STR(ERROR_LINE()))
+ ' ErrorMessage: '+LTRIM(STR(ERROR_MESSAGE()))
END CATCH
然后我在Catch中放了一个Catch:
BEGIN CATCH
BEGIN TRY
DECLARE @message nvarchar(128)
SET @message = LTRIM(STR(ERROR_MESSAGE()))
exec sp_trace_generateevent @event_class=82, @userinfo = @message
END TRY
BEGIN CATCH
SET @Message = 'Error in sp_trace_generateevent'
END CATCH
SET @CatchErrors =
'Catch: [LTL].[CreateShipment] - ErrorNumber: '+LTRIM(STR(ERROR_NUMBER()))
+ ' ErrorSeverity: '+LTRIM(STR(ERROR_SEVERITY()))
+ ' ErrorState: '+LTRIM(STR(ERROR_STATE()))
+ ' ErrorProcedure: '+LTRIM(STR(ERROR_PROCEDURE()))
+ ' ErrorLine: '+LTRIM(STR(ERROR_LINE()))
+ ' ErrorMessage: '+LTRIM(STR(ERROR_MESSAGE()))
END CATCH
现在我可以在分析器中看到“sp_trace_generateevent中的SET @Message ='错误”,但我真的需要查看错误的原因。
我在SSMS中测试时遇到的问题无法再现,只有当我从BizTalk调用时。我的意图是将@CatchErrors(作为输出参数)冒泡回BizTalk,但它也不起作用。
此外 - BizTalk正在与拥有SQL SysAdmin的用户一起运行(它在我的开发机器上)。
使用master..sp_tracegeneratedevent
时也会得到相同的结果基于@Jeroen的回复,我切换到了这个,但仍然遇到了一些错误。
DECLARE @message nvarchar(128)
BEGIN TRY
SET @message = Convert(nvarchar(128),SUBSTRING(ERROR_MESSAGE(),1,128))
exec sp_trace_generateevent @event_class=82, @userinfo=@message
END TRY
更新#1:这让我感到沮丧。当我在SQL中测试时它可以工作,但是当我从BizTalk测试它没有。所以我真的想要一个调试功能。我现在抓住我捕获的捕获物......而且它们都在捕捉,我不知道为什么。相同的代码在除以零的简单示例中工作正常。更复杂的是,这是一个由BizTalk调用的存储过程调用的存储过程。如果我发现错误,我应该能够在我的主要和子存储过程中的@CatchErrors输出参数中将它返回给BizTalk。
BEGIN CATCH
DECLARE @message nvarchar(128)
BEGIN TRY
SET @message = Convert(nvarchar(128),SUBSTRING(ERROR_MESSAGE(),1,128))
exec sp_trace_generateevent @event_class=82, @userinfo=@message
END TRY
BEGIN CATCH
SET @Message = 'Error in sp_trace_generateevent'
END CATCH
BEGIN TRY
SET @CatchErrors =
'Catch: [RG].[CreateShipment] - ErrorNumber: '+CAST(ERROR_NUMBER() AS VARCHAR(35))
+ ' ErrorSeverity: '+CAST(ERROR_SEVERITY() AS VARCHAR(35))
+ ' ErrorState: '+CAST(ERROR_STATE() AS VARCHAR(35))
+ ' ErrorProcedure: '+CAST(IsNull(ERROR_PROCEDURE(),'') AS VARCHAR(200))
+ ' ErrorLine: '+CAST(ERROR_LINE() AS VARCHAR(35))
+ ' ErrorMessage: '+CAST(ERROR_MESSAGE() AS VARCHAR(4000))
END TRY
BEGIN CATCH
BEGIN TRY
SET @Message = 'Error in Set @CatchErrors='
SET @CatchErrors =
'Catch: [LTL.CreateShipmentStopLineItem]- Error: ' + CAST(ERROR_MESSAGE() AS VARCHAR(4000))
END TRY
BEGIN CATCH
SET @Message = 'Error in Set @CatchErrors2'
END CATCH
END CATCH
END CATCH
更新#2 - 在SSMS中进行测试:
我正在使用SSMS进行测试,没有一个问题存在问题。如果我不止一次运行它,它会在Print语句中出现违反主键的情况。
Declare @shipstopline LTL.TT_ShipmentStopLineItem
DECLARE @messageID bigint
DECLARE @CatchErrorsResult varchar(max)
insert into @shipstopline values ('2', '1', 'Eggs','1','2','3','1','100','1','12','1','1','1','10','20','1')
EXEC LTL.CreateShipmentStopLineItem @MessageId = 2, @ShipmentStopID=1, @CreateBy=108004, @ShipmentStopLineItem=@shipstopline, @loopid=1, @catchErrors=@CatchErrorsResult OUT
select RowCreated, * from LTL.ShipmentStopLineItem order by LTL.ShipmentStopLineItem.RowCreated desc
print @CatchErrorsResult
答案 0 :(得分:1)
好吧,如果你试试这个:
SET XACT_ABORT ON;
BEGIN TRY
SELECT 1 / 0;
END TRY
BEGIN CATCH
DECLARE @message nvarchar(128);
SET @message = LTRIM(STR(ERROR_MESSAGE()));
exec sp_trace_generateevent @event_class=82, @userinfo = @message
END CATCH
您可以立即获得有关错误的反馈:
Msg 8114,Level 16,State 5,Line 8转换数据类型时出错 nvarchar浮动。
那是因为你STR()
打电话给你的是不正确的事情 - STR
格式化浮点值,只有那些。 (为了灵活转换,请使用FORMAT
和/或CONCAT
,后者总是隐式地将内容转换为字符串而不会抱怨。)
除此之外,存储过程的第一个参数是@eventid
,而不是@event_class
(这通常是一个错误,但扩展存储过程更灵活 - 你可以调用参数@banana
它仍然有效。但是,为了清楚起见,我们应该使用记录的名称。所以:
SET XACT_ABORT ON;
BEGIN TRY
SELECT 1 / 0;
END TRY
BEGIN CATCH
DECLARE @message nvarchar(128) = ERROR_MESSAGE();
EXEC sp_trace_generateevent @eventid=82, @userinfo = @message;
END CATCH
在我的探查器中,这会产生一个带有
的UserConfigurable:0
事件
遇到零错误。
请注意,如果没有TRY / CATCH
,即使没有通过Exception
事件生成自己的跟踪事件,您仍然可以获得错误。
答案 1 :(得分:0)
事实证明,BizTalk调用Stored Proc两次,一次使用FmtOnly = On,再一次使用FmtOnly = Off。我在第一次调用后得到了无效的强制转换异常,因此Stored Proc基本上没有真正执行。由于FmtOnly = On,我被分析器误导了,认为它实际上正在执行我在那里看到的语句。因此sp_TraceGenerateEvent实际上并不在FmtOnly = On的第一次传递上运行,但是当我超过其他错误时,它在第二次传递中运行正常,FmtOnly = Off。
参考:类似的questoin我发布了为什么SQL Profiler在SSMS运行和同一存储过程的BizTalk运行之间看起来不同的原因:Can SQL Begin Try/Catch be lying to me (in the profiler)?