为什么在UDF中不允许TRY-CATCH阻塞?

Fed*_*jdu 23 t-sql user-defined-functions

为什么SQL Server不支持UDF中的TRY-CATCH块?

如果我们讨论的是主要用于计算和对话的标量UDF,那么应该大量使用这个块,但我们没有.

另外,您使用了哪些变通方法?

Pon*_*ife 13

MSSQL中的UDF不允许有副作用,BOL将其定义为"更改数据库状态".这是一个相当含糊的描述,但是MSSQL显然认为错误会改变数据库状态 - 这个UDF不能编译:

create function dbo.foo()
returns int
as
begin
    raiserror('Foo', 16, 1)
    return 1
end
go
Run Code Online (Sandbox Code Playgroud)

错误消息是:

消息443,级别16,状态14,过程foo,行5在函数内无效使用副作用运算符'RAISERROR'.

如果提出错误被认为是改变数据库状态,那么陷阱和处理可能也是假设.我承认,这不是一个很好的解释.

但实际上,通常最好让调用者决定如何处理错误.假设你写了这样一个函数:

create function dbo.divide (@x int, @y int)
returns float
as
begin
return @x / cast(@y as float)
end
Run Code Online (Sandbox Code Playgroud)

你如何处理应用程序为@y传递零的情况?如果你得到除以零的异常,你接下来要做什么?您可以从对调用者有意义的函数返回什么值,请记住您甚至不知道哪个应用程序正在调用您的函数?

您可能会想到返回NULL,但使用您的函数的应用程序开发人员会同意吗?他们的所有应用程序是否都认为除以零误差具有相同的影响或重要性?更不用说某些地方的NULL可以完全改变查询的结果,可能是应用程序开发人员根本不想要的方式.

如果你是唯一的开发者,也许这不是一个问题,但随着更多的人,它很快就会成为一个问题.

  • 我想通过编写自己的UDF重现TRY_CAST的行为: (2认同)