标量 UDF 内联是否损坏?

jer*_*ech 5 t-sql sql-server-2019

此 SQL 代码返回“a”而不是“asdfg”:

CREATE FUNCTION [dbo].[GetPayload2] (@ID int) RETURNS VARCHAR(300) AS
BEGIN
IF @ID = 1
RETURN 'asdfg'
RETURN ''
END
GO
SELECT dbo.GetPayload2(1)
Run Code Online (Sandbox Code Playgroud)

转载于 15.0.2000.5 和 15.0.2070.41。在 SQL Server 2017 中工作正常。解决方法是使用 WITH INLINE = OFF。

编辑:如果您同意这是一个错误,请在此处投票:https : //feedback.azure.com/forums/908035-sql-server/suggestions/39190126-sql-server-2019-scalar-functions-with-inline-are -b

编辑 2:用于 MS SQL Server 2019 的 CU2 正在解决这个问题:-)

Mic*_*een 3

这就是问题出现的地方。该计划包含定义输出的恒定扫描。

CASE WHEN CASE WHEN (1) = (1) THEN (1) ELSE (0) END = (0) THEN '' ELSE CONVERT_IMPLICIT (varchar(1),CASE WHEN (1) = (1) THEN 'asdfg' ELSE NULL结束,0) 结束

为什么它会向下转换为 varchar(1)?我猜想它需要优化期间遇到的第一个字符串的长度(大概是空字符串),下限为 1。如果我将失败结果更改为return 'yy'隐式转换,则变为varchar(2).

我认为最好的解决方法是明确地转换结果:

RETURN convert(varchar(300), '')
Run Code Online (Sandbox Code Playgroud)

奇怪的是,它也被纠正了:

declare @x sql_variant;
SELECT @x = dbo.GetPayload2(1);

select Result = @x, Property = SQL_VARIANT_PROPERTY(@x, 'MaxLength');

Result    Property
--------  --------
asdfg     300
Run Code Online (Sandbox Code Playgroud)