【问题标题】:SQL Server dynamic where clause with variables on both sidesSQL Server 动态 where 子句,两边都有变量
【发布时间】:2016-12-06 23:51:48
【问题描述】:

也许这无法完成(除了执行 SQL 字符串),我尝试了许多不同的方法,但基本上我想构建一个动态 where 子句,将条件的两侧作为变量。

我需要类似的东西(但可以):

WHERE 0 = 0
  AND (
        (CASE @dateCondition
             WHEN 'DateCreated' THEN DateCreated
             WHEN 'DueDate' THEN DateCreated
             WHEN 'CompletionDate' THEN DateCreated
         END) = @dateFrom)

或本质上

WHERE @dateCondition = @dateFrom

【问题讨论】:

  • 我会根据@dateCondition 的值在IF-ELSE 语句中将where 子句的值设置在第三个变量中,然后我会构建动态sql。换句话说,分两步完成。
  • Where 1=1 可以工作

标签: sql-server dynamic where clause


【解决方案1】:

我在前端查询方面已经有几年的时间了,但通常(嗯,从历史上看)我会做这样的事情:

WHERE 1 = 1
    AND (
           (@dateCondition = 'DateCreated'    AND DateCreated = @dateFrom)
        OR (@dateCondition = 'DueDate'        AND DueDate = @dateFrom)
        OR (@dateCondition = 'CompletionDate' AND CompletionDate = @dateFrom)
    )

虽然取决于我的应用程序,但我可能会在代码中动态构建查询。

一如既往,小心 NULL 参数。

【讨论】:

    【解决方案2】:

    当然,只要我发布问题,我就会明白。

    这是我正在使用的。如果您有更好更有效的解决方案,请告诉我。

    其实有两种解决方案:

    1.

        AND 
           CASE 
              WHEN @dateCondition = 'DateCreated' AND DateCreated >=  @dateFrom
                 THEN 1
              WHEN @dateCondition = 'DueDate' AND DateCreated >=  @dateFrom
                 THEN 1
              WHEN @dateCondition = 'CompletionDate' AND DateCreated >=  @dateFrom
                 THEN 1
              ELSE 0  
           END = 1
    

    2.

        AND DateCreated >= CASE 
                              WHEN @dateCondition = 'DateCreated'  
                                 THEN @dateFrom 
                              ELSE DateCreated 
                           END
    

    等等……

    【讨论】:

      【解决方案3】:

      假设变量是提前设置好的,一个简单的方法是编写一个动态查询。

      DECLARE @date DATE = SELECT 
                                  CASE @dateCondition
                                      WHEN  'DateCreated' THEN DateCreated
                                      WHEN  'DueDate' THEN DateCreated
                                      WHEN  'CompletionDate' THEN DateCreated
                                  END
                           FROM [ . . . ]
      
      DECLARE @sql NVARCHAR(MAX) = 
           'SELECT *
            FROM [. . .]
            WHERE
                @date = @dateFrom
           '
      
      EXEC sp_executesql @sql, N'@date DATE, @dateFrom DATE', @date, @dateFrom
      

      不过,这有安全漏洞,所以如果没有明确设置变量,那么这不是要走的路。

      【讨论】:

        【解决方案4】:

        您不需要动态 SQL

        CASE WHEN @dateCondition ='DateCreated' AND DateCreated = @dateFrom THEN 1 ELSE 0 END = 1
        OR
        CASE WHEN @dateCondition ='DueDate' AND DueDate= @dateFrom THEN 1 ELSE 0 END = 1
        OR 
        CASE WHEN @dateCondition ='CompletionDate' AND CompletionDate= @dateFrom THEN 1 ELSE 0 END = 1
        

        或者这样

        CASE WHEN @dateCondition ='DateCreated' THEN DateCreated ELSE @dateFrom END = @dateFrom 
        AND 
        CASE WHEN @dateCondition ='DueDate' THEN DueDate ELSE @dateFrom END = @dateFrom
        AND
        CASE WHEN @dateCondition ='CompletionDate' THEN CompletionDate ELSE @dateFrom END = @dateFrom 
        

        取决于你是用 OR 思考还是用 AND 思考

        我个人认为是 AND。

        【讨论】:

          猜你喜欢
          • 2010-09-13
          • 1970-01-01
          • 2014-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-17
          相关资源
          最近更新 更多