显示从SQL Server引发的错误消息

时间:2013-05-04 09:51:45

标签: sql-server-2008 delphi delphi-xe2

我使用" Adoconnection"连接到SQL Server并在ADOQuery中使用下面的代码:

BEGIN TRY
...
END TRY
BEGIN CATCH
  RAISERROR(LTrim(str(ERROR_NUMBER())))
END CATCH

当我通过以下方式调用错误消息时:" AdoConnection.Errors [0] .NativeError" 它总是返回" 5000"

当我通过以下方式调用错误消息时:" AdoConnection.Errors [0] .Number" 它返回一个负数!

如何从SQL SERVER中获取正确的错误号?

1 个答案:

答案 0 :(得分:2)

来自MSSQL的所有错误都将有ERROR_NUMBER 50000.您可以使用sp_addmessage注册自己的消息,但使用它们很笨拙。

MSSQL 2012有新的关键字THROW,它可以完全满足您的需求。

那么你可以在2008年做些什么,假设你从CATCH块中的故障中恢复过来:

  1. 您可以构建自己的错误消息,该消息将在Exception.Message
  2. ERROR_NUMBER毫无价值
  3. ERROR_SEVERITY严重性用于不同目的
  4. 嘿,有ERROR_STATE,您可以使用:)
  5. 对于存储过程,可以使用RETURN值或OUTPUT参数传递有关成功或失败的信息
  6. BEGIN TRY
    
      BEGIN TRAN
    
      --
      -- some code
      --
    
      IF @@ROWCOUNT = 0 OR @SomeYourValue <> @SomeOtherValue
        RAISERROR('Your own error message', 16, 1);
    
      --
      -- some code
      --
    
      IF @@ROWCOUNT > 10 OR @SomeYourValue = @SomeOtherValue
        RAISERROR('Your own error message', 16, 2);
    
      COMMIT
    
    END TRY
    BEGIN CATCH
    
      DECLARE
        @ErrorMessage NVARCHAR(2048) = ERROR_MESSAGE(),
        @ErrorNumber INT = ERROR_NUMBER(),
        @ErrorSeverity INT = ERROR_SEVERITY(),
        @ErrorState INT = ERROR_STATE(),
        @ErrorProcedure NVARCHAR(126) = ERROR_PROCEDURE(),
        @ErrorLine INT = ERROR_LINE()
    
      ROLLBACK
    
      -- construct your own awesome message
      SET @ErrorMessage =
        LEFT(
            'Error ' + CAST(@ErrorNumber AS VARCHAR(10)) + ': '
            + @ErrorMessage
            + ' Line: ' + CAST(@ErrorLine AS VARCHAR(10))
            + ISNULL(' ' + @ErrorProcedure, ''), 2044)
    
      -- pass error
      RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState)
    
      -- or use return value if you want numbers instead Error messages from SQL
      IF @ErrorNumber < 50000
        RETURN @ErrorNumber
      ELSE
        RETURN -@ErrorState
      -- In Delphi: AdoProc.Parameters.ParamByName('@RETURN_VALUE').AsInteger:
      -- 0 = all OK
      -- > 0 - some SQL error number
      -- < 0 - hey, my own errors!
    
      -- or declare @ErrorMessage, @ErrorNumber and @ErrorState as
      -- procedure's OUTPUT parameters
    END CATCH