如何在标量函数中使用 WITH?

How does one use WITH within a Scalar Function?

我正在尝试将 WITH 子句添加到标量函数内的语句中,但是当我这样做时,出现以下语法错误:

SQL80001: Incorrect syntax near 'WITH'

SQL80001: Incorrect syntax near ')'

最后一个错误是指最后一个右括号。

这里是 SQL 的一个大大简化的例子,它也因为同样的原因失败了:

CREATE FUNCTION IsSumEqualToTen
(
    @number1 INT,
    @number2 INT
)
RETURNS BIT
AS
BEGIN
    RETURN
    (
        WITH AddNumbers AS
        (
            SELECT @number1 + @number2
        )
        SELECT CASE WHEN AddNumbers = 10
        THEN 1
        ELSE 0
        END
    )
END

我知道改成这样,没有语法错误:

CREATE FUNCTION IsSumEqualToTen
(
    @number1 INT,
    @number2 INT
)
RETURNS BIT
AS
BEGIN
    RETURN
    (
        CASE WHEN (@number1 + @number2) = 10
        THEN 1
        ELSE 0
        END
    )
END

但对于我实际正在做的事情,我需要一个递归 CTE 来展平层次结构,因此 WITH 是必不可少的。

首先,我必须说我同意 Larnu 在这一点上的观点 - 使用标量函数可能不是您可以采取的最佳行动方案。
但是,我想向您展示在用户定义的函数中使用常见的 table 表达式没有问题 - table 值或标量。

您显示的代码存在一些语法错误和一些概念错误。该函数的固定版本(仍然使用 cte)是这样的:

CREATE FUNCTION IsSumEqualToTen
(
    @number1 INT,
    @number2 INT
)
RETURNS BIT
AS
BEGIN
    DECLARE @Result bit;

        WITH AddNumbers(AddNumbers) AS
        (
            SELECT @number1 + @number2 
        )
        SELECT @Result = CASE WHEN MAX(AddNumbers) = 10
            THEN 1
            ELSE 0
            END
        FROM AddNumberes;

    RETURN @Result;
END

备注:

  1. cte 结果集中的每一列都必须命名。
  2. cte 被视为table,您必须考虑到它可能包含多行(即使它只能包含一行,编译器也无法知道)。
  3. 标量函数未内联,这意味着您不执行 return (body here),而是执行 body...; return scalarValue。事实上,这就是 official documentation 的样子:
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
( [ { @parameter_name [ AS ][ type_schema_name. ] parameter_data_type   
    [ = default ] [ READONLY ] }   
    [ ,...n ]  
  ]  
)  
RETURNS return_data_type  
    [ WITH <function_option> [ ,...n ] ]  
    [ AS ]  
    BEGIN   
        function_body   
        RETURN scalar_expression  
    END  
[ ; ]