我的查询使用'exists'函数作为过滤器,它内部有标量值函数。标量值的函数包含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))
答案 0 :(得分:2)
EXISTS()运算符
如果子查询包含任何行,则返回TRUE。
(强调添加)
这很重要,因为你的Scalar函数将返回一个值,1或0(正如Damien所指出的,即使NULL也会满足)但是它将返回一个值。
因为它返回一个值,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;
尝试重新编写查询以不使用该函数,因为标量函数通常不是基于设置的,因此通常是性能杀手。
答案 1 :(得分:1)
正如已经说过的那样,exists函数将始终评估为true,因为标量函数返回一个值。存在仅在函数调用最终不返回值时才起作用。
您可以使用交叉申请,例如:
SELECT *
FROM TBL1 as T1
CROSS APPLY (SELECT svf = dbo.SVF(T1.x,T2.y)) c
WHERE svf = 1
编辑: 请记住,标量函数在大多数情况下是性能杀手,因为它们不是可以攻击的。