【问题标题】:Ignore or handle an error when running a query in SQL Server在 SQL Server 中运行查询时忽略或处理错误
【发布时间】:2018-02-08 12:41:15
【问题描述】:

当我通过 SQL Server Mgmt Studio 执行批量插入查询时,它会产生以下错误,但会完成其他查询的插入过程。

消息 18054,级别 16,状态 1,程序 X,第 14 行
引发了错误 50001,严重性 -1,状态 1,但在 sys.messages 中未找到具有该错误号的消息。如果错误大于 50000,请确保使用 sp_addmessage 添加用户定义的消息。

消息 18054,级别 16,状态 1,过程 Y,第 14 行
引发了错误 50001,严重性 -1,状态 1,但在 sys.messages 中未找到具有该错误号的消息。如果错误大于 50000,请确保使用 sp_addmessage 添加用户定义的消息。

消息 18054,级别 16,状态 1,过程 Z,第 14 行
引发了错误 50001,严重性 -1,状态 1,但在 sys.messages 中未找到具有该错误号的消息。如果错误大于 50000,请确保使用 sp_addmessage 添加用户定义的消息。

但是,当通过终端中的 ant 作业执行插入查询时,进程停止并显示以下错误消息。

BUILD FAILED
C:\test\mssql\build.xml:27: The following error occurred while executing this line:
C:\test\mssql\build-core.xml:74: com.microsoft.sqlserver.jdbc.SQLServerException: Error 50001, 
severity -1, state 1 was raised, but no message with that error number was found in sys.messages. If error is larger than 50000, 
make sure the user-defined message is added using sp_addmessage.
        at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515)

我试图通过忽略它来处理错误:

set ANSI_WARNINGS OFF;

并且通过为抛出错误的过程定义 try-catch 块:

BEGIN TRY  
    RAISERROR (50001,-1,1, 'X');
    RAISERROR (50001,-1,1, 'Y');
    RAISERROR (50001,-1,1, 'Z');
END TRY  
BEGIN CATCH  
    DECLARE @ErrorMessage NVARCHAR(4000);  
    DECLARE @ErrorSeverity INT;  
    DECLARE @ErrorState INT;  

    SELECT   
        @ErrorMessage = ERROR_MESSAGE(),  
        @ErrorSeverity = ERROR_SEVERITY(),  
        @ErrorState = ERROR_STATE();  
    RAISERROR (@ErrorMessage, -- Message text.  
               @ErrorSeverity, -- Severity.  
               @ErrorState -- State.  
               );  
END CATCH;  

但错误仍然存​​在于终端,构建失败。

如果我将自定义错误消息定义如下:

EXEC sp_addmessage 50001, 16, N'Test Message'; 
GO

我刚刚收到上述错误消息代替but no message with that error number was found in sys.messages. If error is larger than 50000, make sure the user-defined message is added using sp_addmessage.

有什么方法可以处理抛出错误的过程并像 SQL 客户端一样继续插入直到结束。

【问题讨论】:

  • 尝试CATCH 手动提出的错误似乎..多余。如果您不想引发错误,为什么还要引发错误?
  • RAISERROR 可以引用存储在 sys.messages 目录视图中的用户定义消息或动态构建消息。如果您查看第一个代码块存在错误,我的理解是我试图定义现有错误并捕获它们。可能是我错了,但需要处理第一个代码块中的错误。
  • 我不清楚您的实际问题是什么。是否要忽略生成的错误并继续执行语句?如果是这样,您必须在客户端捕获异常。这就是决定 T-SQL 批处理产生的第一个错误应该生成一个阻止事情继续进行的异常的代码。您无法在 T-SQL 端捕获错误并恢复批处理,因为它没有相应的功能。您需要为每个单独的语句提供其自己的TRY .. CATCH。请注意,ANSI_WARNINGS 对此完全没有影响,XACT_ABORT 会。
  • 好吧,也许老 ON ERROR RESUME NEXT 可以工作,但我不清楚 Subash 真正想要做什么
  • @SubashBasnet 当我查看第一个代码块时,我看到错误的唯一原因是您有 3 个 RAISERROR 语句。我不明白你为什么要忽略你提出的错误,而你一开始就不能提出它。我怀疑您提供的示例代码可能对说明您在真实代码中实际尝试执行的操作没有帮助。

标签: sql sql-server sql-server-2008


【解决方案1】:

想一想你必须要问什么,我认为你的问题的答案是这样的:

您需要将可能导致您希望忽略的错误的每个语句放在它自己的 TRY..CATCH 块中。在每个 catch 块中,您可以根据错误消息决定是要抛出它并停止处理,还是什么都不做,只将其存储在一个变量中,然后继续。

然后在一切结束时,您可以检查您的变量以查看是否有任何错误被您忽略并在当时抛出它们(如果您甚至想要),而不回滚已经运行的语句成功。

【讨论】:

  • 谢谢!只是围绕 try-catch 块中的整批查询解决了这个问题。不需要单独的try-catch。例如:BEGIN TRY insert into x()values(); insert into y()values(); END TRY BEGIN CATCH END CATCH;
猜你喜欢
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
相关资源
最近更新 更多