使用连词执行查询时的SQL行为

时间:2011-05-16 19:05:01

标签: sql sql-server

如果我有一个SQL查询正在对三个表执行存在检查:

IF EXISTS(SELECT [KEY] FROM [Table1] WHERE [KEY]='Key1')
    AND EXISTS(SELECT [KEY] FROM [Table2] WHERE [KEY]='Key2')
    AND EXISTS(SELECT [KEY] FROM [Table3] WHERE [KEY]='Key3')
  1. SQL Server是否支持条件语句的“提前退出”,这样如果对[Table1]的初始存在检查返回false,则不执行剩余的两个存在检查?
  2. 假设Microsoft SQL Server作为后端,我希望在三个引用的表上看到什么锁定行为,再次假设针对Table1的初始存在检查将返回false?
  3. 使用函数而不是实际查询的一些基本测试表明支持“早期退出”,但在查询执行期间的锁定分析也表明在所有三个表上获得了与“早期退出”结果相矛盾的锁定。

    SQL Server是否获取了查询中所有表的锁定,以防以后需要它们?

3 个答案:

答案 0 :(得分:2)

SQL Server 执行执行短路评估,但您无法控制它选择评估子句的顺序,除非您通过CASE语句执行此操作。

答案 1 :(得分:2)

编辑:SQL Server中有一个错误,显然偶尔会出现短路现象。请参阅有关RedFilter答案的评论。 如果您想要短路,请使用嵌套的IF。

通常,SQL是声明性的,而不是程序性的,因此您永远不能假设任何表达式或查询将按其编写的顺序进行评估。编辑:除了CASE ......

IF EXISTS(SELECT [KEY] FROM [Table1] WHERE [KEY]='Key1')
BEGIN
    IF EXISTS(SELECT [KEY] FROM [Table2] WHERE [KEY]='Key2')
    BEGIN
        IF EXISTS(SELECT [KEY] FROM [Table3] WHERE [KEY]='Key3')
        BEGIN

这也会改变锁的应用方式:现在,在第一个AND表达式的持续时间内,每个查询都有单独的锁,而不是所有三个表的锁

答案 2 :(得分:0)

SQL Server does not short-curcuit。必须评估语句的所有部分,并在执行查询时采取所有相关锁。