如何计算 SQL 标量函数中的算术表达式

how evaluate an arithmetic expression within a SQL scalar function

我正在尝试执行这个标量函数,我尝试了很多方法来实现这个,但我卡住了

Create FUNCTION CalculateElementFunc()
RETURNS int
AS
BEGIN
    DECLARE @ResultVar  numeric(18,6)
    DECLARE  @eq nvarchar(MAX)
    set @eq = '7.5/100*1258.236'    

    declare @expression nvarchar(max)
    set @expression = @eq

    declare @result int
    declare @SQLString nvarchar(max)
    Set @SQLString = N'Select @result = @expression'

    exec sp_executesql @SQLString, N'@expression nvarchar(100)', 
           @expression, 
           @result = @result output

    select @ResultVar = @result

    if( @ResultVar <> ROUND( @ResultVar, 2 ,1))
    set @ResultVar =  cast( ROUND( @ResultVar, 2 ,1) + .01 as numeric(18,2))

    RETURN @ResultVar
END

当我尝试执行它时

select dbo.CalculateElementFunc()

我收到这个错误

消息 557,级别 16,状态 2,第 1 行 只能从函数内执行函数和一些扩展存储过程。

请指教

SQL服务器不推荐你想做的事。首先,真的很难。如您所知,SQL 服务器函数无法执行动态 SQL.

这巧妙地在documentation:

EXECUTE statements calling extended stored procedures.

execsp_executesql 不是扩展存储过程。

你能做什么?以下是一些选项:

  1. 是否可以使用存储过程代替 UDF?存储过程可以执行动态SQL.
  2. 你能绕过表达式求值的问题吗?也许动态 SQL 可以在您的代码中使用更高一层。
  3. 可以 执行启动另一个事务并执行动态SQL 的扩展存储过程。想想:演技真差。
  4. 你可以写一个CLR扩展函数。

SQL 用户定义函数的限制:

  1. 非确定性内置函数不能用于用户定义的函数。例如GETDATE() 或 RAND()。
  2. XML 数据类型不受支持。
  3. 不允许动态 SQL 查询。
  4. 用户定义的函数不支持任何 DML 语句(INSERT、UPDATE、DELETE),除非它在 ​​Table 变量上执行。
  5. 我们无法调用存储过程。只能从函数调用扩展存储过程。
  6. 我们无法在 UDF 中创建临时表。
  7. 它不支持 UDF 内部的错误处理。虽然,我们可以处理使用此函数的语句的错误(RAISEERROR、TRY-CATCH)。

看起来您是 using/calling 用户定义函数中的一个存储过程。困扰您的不是表达式,而是存储过程调用。

尝试用一些逻辑替换它以获得您想要的输出。

希望这对您有所帮助。如果对您的问题有帮助,请不要忘记将其标记为答案。