【问题标题】:How do I catch an error from a stored proc within a stored proc in VBA如何从 VBA 中的存储过程中的存储过程中捕获错误
【发布时间】:2012-04-19 16:57:10
【问题描述】:

我有一个存储过程调用了其他几个,其中一个由于重复的主键而无法将行插入表中

引发的错误是 消息 2627,级别 14,状态 1,程序 ...,第 16 行 违反 PRIMARY KEY 约束“...”。无法在对象“...”中插入重复键。

我通过 VBA 从 Excel 电子表格中调用 this,并使用通常的 On Error 处理,但例程在没有触发错误的情况下静默失败。

我不确定这是由于存储过程中的存储过程还是错误的严重性太低。

有没有人经历过这样的事情并可以提出解决方法?

我最初的尝试是在存储过程调用周围放置一个 BEGIN TRY / BEGIN CATCH 块,CATCH 以更高的严重性运行 RAISERROR,但它似乎没有被触发。

谢谢

【问题讨论】:

  • 我会查看您的 vba 代码。获取正在发送的确切 sql 代码并检查您是否通过 ssms 收到错误。在代码中添加断点并逐步执行。
  • 顶级存储过程如何处理来自被调用存储过程的错误?它是否退出并显示错误消息?在这里显示一些实际代码(VBA/存储过程)可能会有所帮助。
  • @TimWilliams 最初它没有做任何特别的事情——我认为它会冒泡。我尝试对调用的存储过程进行捕获,但即使从 SSMS 运行时它也不会触发,我可以在输出窗口中清楚地看到错误。
  • @RussellHart - 我已经做到了 :) SSMS 显示一个错误,该错误会终止存储过程中的存储过程。主要过程继续进行(我猜错误还不够严重)。 VBA 代码运行良好,完全没有错误。我最初只是执行 DBCmd.Execute,但将其更改为 SET rs = DBCmd.Execute,以防它需要返回记录集以监视错误。不过还是没有运气:(

标签: sql-server excel vba error-handling


【解决方案1】:

在外部过程中添加一个显式事务。 BEGIN TRANSACTION 开头,COMMIT TRANSACTION 结尾。

然后在开始事务之前添加SET XACT_ABORT ON;。这将处理批处理失败。

在出现错误的内部 proc 之后,检查语句级别错误的错误值,例如

IF @@ERROR <> 0 
BEGIN
    ROLLBACK TRANSACTION; 
    RETURN 1; 
END

【讨论】:

  • 就是这样,谢谢。将其包装在交易中可以正确地冒泡。谢谢拉塞尔。
【解决方案2】:

我们在 T-SQL 中使用 OUTPUT 变量来执行此操作,尽管我只知道它的 SQL 方面:您需要使用 VBA 从 SQL 中获取输出参数。将输出变量声明为 varchar,并立即将其设置为 '':

DECLARE @MyError VARCHAR(500) OUTPUT
SET @MyError = ''

在 T-SQL 中进行常规错误检查,如果确实发现错误,请将描述设置到 @MyError 变量中。您的 VBA 代码将始终收到 @MyError 消息,但它通常是一个空字符串 ''。如果不是,则转到 VBA 中的错误处理。

【讨论】:

  • 谢谢@RussellFox 这个解决方法应该有效——我只是好奇为什么这个特定的错误不会直接出现在 VBA 上,而其他人会这样做。再说一次,我只能认为这是一件严重的事情。
  • 这是一个事务问题,语句失败但不是批处理。看我的回答。
  • This 帖子谈到了这一点:它说应该返回 19 及更高级别的严重性,但最后一篇帖子说您必须使用 ADO 错误捕获而不是 VBA。
  • @RussellFox 关键是错误是在存储过程中终止存储过程。调用者没有被终止,因此 ADO 错误捕获和 VBA 错误捕获都不起作用。这包括将错误严重性提高到 19。
  • 那么你需要在每次调用子进程时捕获错误,如果子进程失败,则在主进程中调用 RAISERROR。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 2011-01-02
  • 2017-05-02
  • 2014-11-27
  • 2014-04-21
相关资源
最近更新 更多