Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql ISNULL、IIF、CASE语句中的子查询_Sql_Sql Server_Subquery_Isnull_Iif - Fatal编程技术网

Sql ISNULL、IIF、CASE语句中的子查询

Sql ISNULL、IIF、CASE语句中的子查询,sql,sql-server,subquery,isnull,iif,Sql,Sql Server,Subquery,Isnull,Iif,在ISNULL或IIF或CASE中作为参数提供的子查询将在不考虑条件的情况下执行 为了解释我的意思,请考虑下面的例子。当我运行下面的查询并查看执行计划时,我发现即使变量@Id不为NULL,第二个条件也会始终执行 有人能解释为什么子查询会在查询1、2、3中执行吗 --Create a Temp table IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL DROP TABLE #TempTable CREATE TABLE #TempTable ( ID

在ISNULL或IIF或CASE中作为参数提供的子查询将在不考虑条件的情况下执行

为了解释我的意思,请考虑下面的例子。当我运行下面的查询并查看执行计划时,我发现即使变量@Id不为NULL,第二个条件也会始终执行

有人能解释为什么子查询会在查询1、2、3中执行吗

--Create a Temp table
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL DROP TABLE #TempTable
CREATE TABLE #TempTable
(
ID INT
)

--Insert some data
INSERT INTO #TempTable VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)

DECLARE @Id INT = 1

--Query 1: ISNULL
SET @Id= ISNULL(@Id, (SELECT TOP 1 ID FROM #TempTable TT WHERE TT.ID = 1))
SELECT @Id AS ID

--Query 2: IIF
SET @Id=  IIF(@Id IS NULL,(SELECT TOP 1 ID FROM #TempTable TT WHERE TT.ID = 1),@Id)
SET @Id=  IIF(@Id IS NOT NULL,@Id,(SELECT TOP 1 ID FROM #TempTable TT WHERE TT.ID = 1))

SELECT @Id AS ID

--Query 3: CASE
SET @Id=  CASE WHEN @Id IS NULL THEN (SELECT TOP 1 ID FROM #TempTable TT WHERE TT.ID = 1) ELSE @Id END
SET @Id=  CASE WHEN @Id IS NOT NULL THEN @Id ELSE (SELECT TOP 1 ID FROM #TempTable TT WHERE TT.ID = 1)  END
SELECT @Id AS ID

---Query 4: IF
IF @Id IS NULL
BEGIN
    SET @Id = (SELECT TOP 1 ID FROM #TempTable TT WHERE TT.ID = 1) 
    SELECT @Id AS ID
END
ELSE 
BEGIN
    SELECT @Id AS ID
END

如果希望子查询仅在满足null条件时执行,请使用
If
而不是
ISNULL

if @Id is null
   set @id = (SELECT TOP 1 ID FROM #TempTable TT WHERE TT.ID = 1)
而不是

SET @Id= ISNULL(@Id, (SELECT TOP 1 ID FROM #TempTable TT WHERE TT.ID = 1))

您的查询在这里充满了逻辑错误。你们到处都有top,但一个订单都没有。除非指定一个顺序,否则无法确保返回哪一行……当然,在这种情况下,由于where子句,只能返回一行。是的,执行计划必须确定如何运行。计划不是以数据为条件的,它必须针对任何条件制定计划。简单的答案是SQL Server不会像其他编程语言(c#,vb)等那样进行短路。@SeanLange这只是我想到的一个非常小的例子。。当然还有一个WHERE子句。我认为这些名字是有误导性的,很多人可能不会想到这种行为,我想大多数人甚至不会研究查询计划来进行这样简单的查询,我只是注意到了这一点。