如何在标量函数中使用 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
备注:
- cte 结果集中的每一列都必须命名。
- cte 被视为table,您必须考虑到它可能包含多行(即使它只能包含一行,编译器也无法知道)。
- 标量函数未内联,这意味着您不执行
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
[ ; ]
我正在尝试将 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
备注:
- cte 结果集中的每一列都必须命名。
- cte 被视为table,您必须考虑到它可能包含多行(即使它只能包含一行,编译器也无法知道)。
- 标量函数未内联,这意味着您不执行
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 [ ; ]