【问题标题】:SQL Sub Query NO execute if nullSQL 子查询 NO 如果为空则执行
【发布时间】:2009-07-23 16:52:11
【问题描述】:

我想知道如果我的@ID1 为NULL,是否有办法不执行我的子查询?

CREATE PROCEDURE [dbo].[TestTable_Search]
    @Col1 int,
    @Col2 uniqueidentifier,
    @Col3 datetime,
    @Col4 datetime,
    @ID1 varchar(10)
AS

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SELECT *

FROM
    [dbo].[TestTable]
WHERE
    [Col1] = COALESCE(@Col1, Col1) AND
    [Col2] = COALESCE(@Col2, Col2) AND
    [Col3] >= COALESCE(@Col3 + "00:00:00", Col3) AND
    [Col4] <= COALESCE(@Col4 + "23:59:59", Col4) AND
    [Col5] IN (SELECT [ID2] FROM [dbo].[TestTable2] WHERE [ID1] =  @ID1)

【问题讨论】:

    标签: asp.net sql stored-procedures


    【解决方案1】:

    不确定你的意思,但也许这就是你要找的:

    SELECT *
    FROM
        [dbo].[TestTable]
    WHERE
        [Col1] = COALESCE(@Col1, Col1) AND
        [Col2] = COALESCE(@Col2, Col2) AND
        [Col3] >= COALESCE(@Col3 + "00:00:00", Col3) AND
        [Col4] <= COALESCE(@Col4 + "23:59:59", Col4) AND (
        @ID1 IS NULL 
            OR [Col5] IN (SELECT [ID2] FROM [dbo].[TestTable2] WHERE [ID1] =  @ID1))
    

    【讨论】:

    • 优秀的正是我想要的...... +1
    【解决方案2】:

    SQL Server 在处理OR 条件方面不是很好,尤其是在变量方面,这就是为什么这可能是最好的决定:

    SELECT  *
    FROM    [dbo].[TestTable]
    WHERE   [Col1] = COALESCE(@Col1, Col1) AND
            [Col2] = COALESCE(@Col2, Col2) AND
            [Col3] >= COALESCE(@Col3 + "00:00:00", Col3) AND
            [Col4] <= COALESCE(@Col4 + "23:59:59", Col4) AND
            AND @id1 IS NULL
    UNION ALL
    SELECT  *
    FROM    [dbo].[TestTable]
    WHERE   [Col1] = COALESCE(@Col1, Col1) AND
            [Col2] = COALESCE(@Col2, Col2) AND
            [Col3] >= COALESCE(@Col3 + "00:00:00", Col3) AND
            [Col4] <= COALESCE(@Col4 + "23:59:59", Col4) AND
            [Col5] IN (SELECT [ID2] FROM [dbo].[TestTable2] WHERE [ID1] =  @ID1)
    

    如果@id 不是NULL,则第一个子查询将因为过滤器而不返回任何内容。

    如果@idNULL,则第二个子查询将不返回任何内容,因为与NULL 的比较永远不会匹配,内部子查询将返回一个空集,并且col5 IN (SELECT …) 将永远不会满足。

    SQL Server 可以在运行时有效地检测到这些东西,这就是为什么第二个子查询中的第一个几乎会立即被优化的原因。

    ORUNION ALL 的性能比较请参阅我的博客中的这篇文章:

    【讨论】:

      【解决方案3】:

      如果您不执行子查询,则无论如何都不会返回任何行。因此,只需像这样使用单独的 SELECT 来处理这种情况:

      IF @ID1 IS NULL
      BEGIN
      
          SELECT *
          FROM dbo.[TestTable]
          WHERE 1 = 0
      
      END
      ELSE
      BEGIN
      
          SELECT *
      
          FROM
              [dbo].[TestTable]
          WHERE
              [Col1] = COALESCE(@Col1, Col1) AND
              [Col2] = COALESCE(@Col2, Col2) AND
              [Col3] >= COALESCE(@Col3 + "00:00:00", Col3) AND
              [Col4] <= COALESCE(@Col4 + "23:59:59", Col4) AND
              [Col5] IN (SELECT [ID2] FROM [dbo].[TestTable2] WHERE [ID1] =  @ID1)
      
      END
      

      【讨论】:

        猜你喜欢
        • 2018-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多