SQL中“IF EXISTS”和“IF NOT EXISTS”之间的区别?

时间:2010-12-13 14:24:16

标签: sql sql-server

我对SQL很新。我想知道当我使用“IF EXISTS”或“IF NOT EXISTS”时会发生什么。 例如:以下两个陈述之间有什么区别:

声明1:(EXISTS)

IF EXISTS( SELECT ORDER_ID FROM DBO.ORDER_DETAILS WHERE ORDER_ID = 11032 )
BEGIN
     DELETE FROM DBO.ORDER_DETAILS WHERE ORDER_ID = 11032
END

声明2:(不是EXISTS)

IF NOT EXISTS( SELECT ORDER_ID FROM DBO.ORDER_DETAILS WHERE ORDER_ID = 11032 )
BEGIN
     DELETE FROM DBO.ORDER_DETAILS WHERE ORDER_ID = 11032
END

IF EXISTSIF NOT EXISTS将返回什么? 这两者中哪个更好? 何时使用IF EXISTS以及何时使用IF NOT EXISTS

7 个答案:

答案 0 :(得分:3)

以下是4个示例,说明何时使用IF EXISTS以及何时使用IF NOT EXISTS:

A)从多个表中删除相关记录:

IF EXISTS (SELECT TOP(1) 1 FROM Table1 WHERE ORDER_ID = 11032) BEGIN
    DELETE FROM Table1 WHERE ORDER_ID = 11032
    DELETE FROM Table2 WHERE ORDER_ID = 11032
    -- possibly more statements following here ...
END

B)如果存在,则更新1个以上表中的记录:

IF EXISTS (SELECT TOP(1) 1 FROM Table1 WHERE ORDER_ID = 11032) BEGIN
    UPDATE Table1 SET Field1='X' WHERE ORDER_ID = 11032
    UPDATE Table2 SET Field2='Y' WHERE ORDER_ID = 11032
    -- possibly more statements following here ...
END

C)如果记录不存在,则在多个表中插入记录:

IF NOT EXISTS (SELECT TOP(1) 1 FROM Table1 WHERE ORDER_ID = 11032) BEGIN
    INSERT INTO Table1(Field1, Field2, ORDER_ID) VALUES ('A', 'B', 11032)
    INSERT INTO Table2(Field3, Field4, ORDER_ID) VALUES ('X', 'Y', 11032)
    -- possibly more statements following here ...
END

D)Upsert(=插入或更新)记录,具体取决于是否存在:

IF EXISTS (SELECT TOP(1) 1 FROM Table1 WHERE ORDER_ID = 11032) BEGIN
    UPDATE Table1 SET Field1='X' WHERE ORDER_ID = 11032
    -- possibly more statements following here ...
END
ELSE BEGIN
    INSERT INTO Table1(Field1, Field2, ORDER_ID) VALUES ('X', 'B', 11032)
    -- possibly more statements following here ...
END

您可以使用新的MERGE statement代替上述陈述(案例D),但我认为使用它有点复杂。

注意:

  • 如果只有一个表受到影响,则除了upsert示例D)之外,您不会在上述任何示例中使用EXIST。
  • SELECT TOP(1)1 FROM ...效率更高,因为它在找到第一个匹配后中止,然后它只返回数字1(这样可以更有效地选择例如NVARCHAR(最大)字段)< / LI>
  • 您可以看到,仅在示例C)中您被迫使用IF NOT EXISTS(...),所有其他示例都使用IF EXISTS(...),效率更高。

答案 1 :(得分:2)

IF EXISTS检查结果集不是为空,IF NOT EXISTS检查结果集 是否为空。

  

这两者中哪个更好?

为您提供适当语义的那个。

  

何时使用“IF EXISTS”以及何时使用“IF NOT EXISTS”

当您需要检查结果集的非空虚或空虚时。

答案 2 :(得分:2)

你需要第一个声明。基本上,如果查询返回1行或更多行,“IF EXISTS”将返回true,因此在您的示例中,它将返回单行(包含值为1的字段),因此将根据需要执行delete语句。

答案 3 :(得分:2)

两个语句都将返回布尔值true / false结果。

如果结果集不为空,则

EXISTS返回true。

NOT EXISTS是否定操作,因此如果结果集为空,则返回true

答案 4 :(得分:2)

如果order_details的order_id等于11032,您的第一个语句将会运行:

DELETE FROM DBO.ORDER_DETAILS WHERE ORDER_ID = 11032

如果没有order_details且order_id等于11032,那么您的第二个语句将会运行。请注意,这是一个空集,因为您刚刚检查过没有带有该order_id的订单。

在这个例子中,实际上更容易运行DELETE - IF EXISTS和IF NOT EXISTS是多余的。

答案 5 :(得分:1)

这当然是使用EXISTS的一种方法。我不确定第二个会做什么。

但是,你可以

DELETE FROM DBO.ORDER_DETAILS WHERE ORDER_ID = 11032

并完全删除EXISTS,除非你想执行

IF EXISTS ( SELECT ORDER_ID FROM ORDERS WHERE ORDER_ID = 11032 ) BEGIN
     DELETE FROM DBO.ORDER_DETAILS WHERE ORDER_ID = 11032
     DELETE FROM DBO.ORDERS WHERE ORDER_ID = 11032
END

或您的实际代码比显示的更复杂。

您的第二个语句永远不会删除任何内容,因为如果 行,它将评估为FALSE而不会执行DELETE,如果不是行,它将评估为TRUE并执行DELETE,因为没有行,所以不会执行任何操作。

就性能而言,在您使用EXISTS的上下文中,没有一个具有更好的性能,因为它实际上只评估SELECT的结果集是NULL还是不

还有EXISTS的另一种用法,其中NOT EXISTS 效率低于EXISTS,并且可以用效果更好的词组有效替换。我指的是你在一个语句的NOT EXISTS条款中使用WHERE的时候。在这个原因中,您最好不要执行LEFT JOIN(而不是您可能拥有的INNER JOIN)并过滤WHERE rightTable.SomeColumn IS NULL

答案 6 :(得分:1)

“EXISTS只测试内部查询是否返回任何行。如果是,则外部查询继续。如果不是,则外部查询不执行,整个SQL语句不返回任何内容。”见here。 NOT EXISTS当然是对EXISTS的否定。

第一个语句的作用是,如果可以找到订单,它将发出DELETE查询。第二个没有任何意义,因为它会在ORDER不存在时发出查询。