将函数与 OUTER APPLY 一起使用时,返回值而不是 NULL

2024-01-13

使用内联函数时我得到奇怪的结果。这是代码:

IF EXISTS (
SELECT * FROM sys.objects AS o WHERE name = 'vendor_relation_users'
) DROP FUNCTION dbo.vendor_relation_users;
GO
CREATE FUNCTION [dbo].[vendor_relation_users]
(
    @user_name CHAR(12)
)
RETURNS TABLE
AS
    RETURN (SELECT @user_name AS user_name WHERE @user_name NOT LIKE '06%');
GO

DECLARE @u CHAR(12) = '066BDLER'
SELECT a.user_name, is_v.user_name 
FROM (SELECT @u AS user_name) a
OUTER APPLY [dbo].[vendor_relation_users](@u) AS is_v

SELECT a.user_name, is_v.user_name 
FROM (SELECT @u AS user_name) a
OUTER APPLY (SELECT @u AS user_name WHERE @u NOT LIKE '06%') AS is_v


SELECT * FROM [dbo].[vendor_relation_users](@u)

因此,在第一个 SELECT 语句中,我刚刚在外部应用了该函数,它返回了结果。

在下一个语句中,我从函数中获取代码并将其直接放入 OUTER APPLY 语句中。

最后一条语句只是直接函数调用。

我不明白为什么第一个查询返回值......


这是一个非常有趣的查询。第一个查询的行为取决于您是否使用OPTION (RECOMPILE) or not.

正如您所指出的,这:

DECLARE @u CHAR(12) = '066BDLER'
SELECT a.user_name, is_v.user_name 
FROM (SELECT @u AS user_name) a
OUTER APPLY [dbo].[vendor_relation_users](@u) AS is_v

返回这个:

user_name       user_name
066BDLER        066BDLER

但如果你添加OPTION (RECOMPILE)像这样:

SELECT a.user_name, is_v.user_name 
FROM (SELECT @u AS user_name) a
OUTER APPLY [dbo].[vendor_relation_users](@u) AS is_v
OPTION (RECOMPILE)   

你正确地得到了这个:

user_name       user_name
066BDLER        NULL

我怀疑这是由于查询优化器因基数估计而短路这些内联函数的错误造成的。如果您查看这两个查询的查询计划,您会发现没有 OPTION RECOMPILE 的查询仅返回一个常量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将函数与 OUTER APPLY 一起使用时,返回值而不是 NULL 的相关文章

随机推荐