将SQL Server函数的异常抛出到存储过程

Max*_*ion 6 sql sql-server exception-handling

我在SQL Server 2012中有存储过程说spXample和一个定标器值函数说fXample.我从spXample调用函数fXample.我可以在函数中抛出异常并将其捕获到存储过程的Catch块中并重新抛出到调用的C#代码中吗?

更新:

我写的功能如下:

CREATE FUNCTION dbo.fXample(@i INT)
RETURNS TINYINT
AS
BEGIN
  RETURN (SELECT CASE WHEN @i < 10 
    THEN THROW 51000,'Xample Exception',1;
    ELSE (SELECT @i) 
    END);
END
GO
Run Code Online (Sandbox Code Playgroud)

我收到了错误

消息443,级别16,状态14,过程示例,第46行在函数内无效使用副作用运算符'THROW'.

如何编写替代代码以实现上述功能?

Aar*_*and 10

您可以通过在验证失败时强制出现错误条件来执行此操作,前提是这不是可能自然发生的错误.当您知道某个错误只能在验证失败时发生时,您可以通过检查catch块中的error_number以自定义方式处理该错误.tempdb中的示例:

USE tempdb;
GO

CREATE FUNCTION dbo.fXample(@i INT)
RETURNS TINYINT
AS
BEGIN
  RETURN (SELECT CASE WHEN @i < 10 -- change this to your "validation failed" condition
    THEN 1/0         -- something that will generate an error
    ELSE (SELECT @i) -- (you'd have your actual retrieval code here)
    END);
END
GO

CREATE PROCEDURE dbo.spXample
  @i INT
AS
BEGIN
  SET NOCOUNT ON;
  BEGIN TRY
    SELECT dbo.fXample(@i);
  END TRY
  BEGIN CATCH
    IF ERROR_NUMBER() = 8134 -- divide by zero
    BEGIN
      THROW 50001, 'Your custom error message.', 1;
      -- you can throw any number > 50000 here
    END
    ELSE -- something else went wrong
    BEGIN
      THROW; -- throw original error
    END
  END CATCH
END
GO
Run Code Online (Sandbox Code Playgroud)

现在尝试一下:

EXEC dbo.spXample @i = 10;  -- works fine
EXEC dbo.spXample @i = 6;   -- fails validation
EXEC dbo.spXample @i = 256; -- passes validation but overflows return
Run Code Online (Sandbox Code Playgroud)

结果:

----
10
Run Code Online (Sandbox Code Playgroud)

消息50001,级别16,状态1,过程spXample,第12行
您的自定义错误消息.

消息220,级别16,状态2,过程spXample,第7行
数据类型tinyint的算术溢出错误,值= 256.

  • 谢谢,但是我们不得不跳起来做一些如此简单的事情!只是表明SQL是过去的一种语言,它根本就没有继续前进.:( (3认同)
  • 我只是想从Sql Server 2012中添加THROW (2认同)
  • @NickG,您可以使用存储过程代替。函数实际上是一种优雅的方式来表示它们没有副作用。当然,它们仍然会这样做,因为您可能会抛出内置错误 - 因此它们并不完全没有副作用。这是在语言中使用纯函数的一种优雅方式。SQL 是一种远远超前于它的时代的语言,考虑到它的历史,它是相当令人印象深刻的。它基本上是一个用于基于集合的数据的 DSL。相当了不起! (2认同)