0

我的查询使用“存在”函数作为过滤器,并且其中包含标量值函数。标量值函数包含 cte 和“(select top 1 1)”。当我使用存在时,它根本不会过滤。相反,当我使用“where 1 =(svf)”时,它似乎有效。我在存在查询中错过了什么或任何错误吗?


SELECT * FROM TBL1
WHERE EXISTS (SELECT SVF(1,2))
--where SVF is my scalar valued from which returns bit and looks like as shown below.

CREATE FUNCTION SVF ( @x int, @y int ) RETURNS bit AS BEGIN declare @result bit ;WITH T1 AS ( SELECT * from tbl2 ) SELECT @result= (select top 1 1 FROM t1 ) return isnull(@result,0) END GO

--the following query works SELECT * FROM TBL1 WHERE 1=(SELECT SVF(1,2))

4

2 回答 2

2

EXISTS()运算符

如果子查询包含任何行,则返回 TRUE。

重点补充

这很重要,因为您的 Scalar 函数将返回一个值,1 或 0(正如 Damien 指出的那样,即使 NULL 也会满足),但它会返回一个 value

因为它返回一个值,所以EXISTS总是会返回 TRUE。

您基本上是在询问 SQL Server:

-- Doesn't matter what my function returns as it's always going to return a row...
BEGIN 
-- then run this query
SELECT * FROM TBL1;
END;

尝试重新编写查询以不使用该函数,因为标量函数通常不是基于集合的,因此通常是性能杀手。

于 2016-05-11T13:46:00.797 回答
1

如前所述,exists 函数将始终评估为 true,因为您的标量函数返回一个值。Exists 只有在函数调用最终没有返回值时才起作用。

例如,您可以使用交叉应用:

SELECT * 
FROM TBL1 as T1
CROSS APPLY (SELECT svf = dbo.SVF(T1.x,T2.y)) c
WHERE svf = 1

编辑:请记住,标量函数在大多数情况下都是性能杀手,因为它们是不可预测的。

于 2016-05-11T14:09:52.193 回答