【问题标题】:How to use the AND in a variable in the WHERE clause如何在 WHERE 子句中的变量中使用 AND
【发布时间】:2018-05-23 07:58:34
【问题描述】:

我正在尝试在变量中使用 AND 运算符并在 WHERE 子句中使用它。我试图在不使用动态 SQL 的情况下做到这一点。即没有将整个查询分配给变量。

DECLARE @v_Criteria varchar(500)
DECLARE @jobtype varchar(500) = 'test Job'

    IF @inparam ='Report1'
        BEGIN
            SET @v_Criteria= ''
        END
    ELSE IF @inparam='Report2'
        BEGIN
            SET @v_Criteria= ' AND InvoiceValue IS NOT NULL'
        END


    SELECT *
    FROM tblJobs
    WHERE  JobID NOT IN (63,87,469)    
      AND JobType LIKE '%' + @jobtype + '%' 
      + @v_Criteria

我在 @v_Criteria 之前使用了 + 运算符,然后我没有得到任何结果。如果我在 @v_Criteria 之前使用 & 运算符,我会收到错误消息。任何帮助将不胜感激

【问题讨论】:

    标签: sql sql-server tsql sql-server-2012


    【解决方案1】:

    您不能将“字符串”附加到查询中,它会成为代码的一部分。它仍然只是一个字符串。本质上,您是在尝试使用 Dynamic SQL,但随后又说您不想要 Dynamic SQL?

    一种选择是在 SQL 中为这两种情况构建逻辑...

    SELECT *
    FROM tblJobs
    WHERE JobID NOT IN (63,87,469)    
      AND JobType LIKE '%' + @jobtype + '%'
      AND (
        (@inparam ='Report1')
        OR 
        (@inparam ='Report2' AND InvoiceValue IS NOT NULL)
      )
    

    这意味着查询规划器必须一直处理这两种情况。解决这两种情况的一个计划。这样可以节省您的打字时间,但可能意味着您获得的执行计划不佳并浪费资源或执行时间。

    要解决这个问题,您需要两个查询...

    IF (@inparam = 'Report1')
    BEGIN
      SELECT *
      FROM tblJobs
      WHERE JobID NOT IN (63,87,469)    
        AND JobType LIKE '%' + @jobtype + '%'
    END
    ELSE IF (@inparam = 'Report2')
    BEGIN
      SELECT *
      FROM tblJobs
      WHERE JobID NOT IN (63,87,469)    
        AND JobType LIKE '%' + @jobtype + '%'
        AND InvoiceValue IS NOT NULL
    END
    

    或者只使用动态 SQL...

    SET @sql= 'SELECT *
                 FROM tblJobs
                WHERE JobID NOT IN (63,87,469)    
                  AND JobType LIKE ''%''' + @jobtype + '%''' + @v_Criteria
    
    EXEC sp_executesql @sql
    

    或者……

    SET @sql= 'SELECT *
                 FROM tblJobs
                WHERE JobID NOT IN (63,87,469)    
                  AND JobType LIKE ''%'' + @jobtype_param + ''%''' + @v_Criteria
    
    EXEC sp_executesql
             @sql,
             N'@jobtype_param varchar(500)',
             @jobtype_param = @jobtype
    

    (这里的好处是您不会为每个 @jopbtype 制定一个新的缓存查询计划。相反,它会制定一个参数化的查询计划并重复使用它。)


    编辑:

    基本上您正在调查的是动态搜索。

    如果它比这个例子更复杂,我强烈建议阅读这篇文章:http://www.sommarskog.se/dyn-search.html

    它既复杂又深入,你会学到很多宝贵的经验。

    【讨论】:

    • 非常感谢。答案很有意义
    【解决方案2】:

    在添加“AND”之前,如果您检查@v_Criteria 是否不是空字符串,那么您将不会收到任何错误。

    所以从例如“AND InvoiceValue IS NOT NULL”中拆分 AND 然后根据@v_Criteria的值加与不加

    【讨论】:

    • 所以你的意思是从@v_Criteria中取出AND?
    • 是的,但是在SQL语句中使用它来构建@v_Criteria作为其他字符串来连接
    【解决方案3】:

    这个解决方案怎么样?

    DECLARE @v_Criteria varchar(500)
    DECLARE @jobtype varchar(500) = 'test Job'
    
        IF @inparam ='Report1'
            BEGIN
                SET @v_Criteria= ''
            END
        ELSE IF @inparam='Report2'
            BEGIN
                SET @v_Criteria= ' AND InvoiceValue IS NOT NULL'
            END
    
    
        SELECT *
        FROM tblJobs
        WHERE  JobID NOT IN (63,87,469)    
          AND JobType LIKE '%' + @jobtype + '%' 
          AND ISNULL(InvoiceValue, '') NOT LIKE CASE
                                                     WHEN @inparam = 'Report2'
                                                     THEN ''
                                                     ELSE 'SOMEIMPOSSIBLEVALUE'
                                                     END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      • 1970-01-01
      • 1970-01-01
      • 2022-11-18
      • 1970-01-01
      相关资源
      最近更新 更多