【问题标题】:Building dynamic where condition in SQL statement在 SQL 语句中构建动态 where 条件
【发布时间】:2013-10-06 02:50:45
【问题描述】:

我想根据存储过程输入构建自定义的 Where 条件,如果不为 null 则我将在语句中使用它们,否则我不会使用它们。

if @Vendor_Name is not null
    begin 

    set @where += 'Upper(vendors.VENDOR_NAME) LIKE "%"+ UPPER(@Vendor_Name) +"%"'

    end
    else if @Entity is not null
    begin
    set @where += 'AND headers.ORG_ID = @Entity'
    end
select * from table_name where @where

但我得到了这个错误

An expression of non-boolean type specified in a context where a condition is expected, near 'set'.

【问题讨论】:

    标签: sql sql-server stored-procedures where-clause dynamic-sql


    【解决方案1】:

    老问题,但想补充一下我刚刚发现的问题

    where CASE WHEN @id = 0 THEN 1 ELSE id END = CASE WHEN @id = 0 THEN 1 ELSE @id END

    这来自以下步骤:

    where id = @id

    检查@id 是否为空(或无效)或具有有效值,因此使用大小写替换@id:

    where id = 
    CASE WHEN @id is null
        THEN 0
        ELSE @id
    END
    

    这最终会是

    where id = 0 -- if @id is null, still affected your query
    where id = @id -- if @id have valid value
    

    因为我们只想在有有效数据的情况下使用这个“where”子句,然后我们也改变 id

    where 
    CASE WHEN @id is null
        THEN 0
        ELSE id
    END 
    = 
    CASE WHEN @id is null
        THEN 0
        ELSE @id
    END
    

    然后会变成

    where 0 = 0 -- if @id is null and it doesn't affect your query
    where id = @id -- if @id have valid value
    

    如果 id 是 varchar,不要忘记,使用 0 作为 '0'

    CASE WHEN @id is null
        THEN '0'
        ELSE id
    END 
    

    我在我的项目中使用它并且运行良好,即使我在一个查询中使用超过 1 个。请让我知道这个查询是否在更大的数据上花费时间

    【讨论】:

      【解决方案2】:

      使用这个:

      Declare @Where NVARCHAR(MAX) 
      
      ...... Create your Where
      
      DECLARE @Command NVARCHAR(MAX) 
      Set @Command = 'Select * From SEM.tblMeasureCatalog AS MC ' ;
      
      If( @Where <> '' )
         Set @Comand = @Command + ' Where ' + @Where
      
      Execute SP_ExecuteSQL  @Command
      

      我对此进行了测试,它有效

      【讨论】:

        【解决方案3】:

        您不能像在这行中那样简单地将变量放在普通 SQL 中:

        select * from table_name where @where;
        

        您需要使用动态 SQL。所以你可能会有类似的东西:

        DECLARE @SQL NVARCHAR(MAX) = 'SELECT * FROM Table_Name WHERE 1 = 1 ';
        DECLARE @Params NVARCHAR(MAX) = '';
        
        IF @Vendor_Name IS NOT NULL
            BEGIN
                SET @SQL += ' AND UPPER(vendors.VENDOR_NAME) LIKE ''%'' + UPPER(@VendorNameParam) + ''%''';
            END
        ELSE IF @Entity IS NOT NULL
            BEGIN
                SET @SQL += ' AND headers.ORG_ID = @EntityParam';
            END;
        
        EXECUTE SP_EXECUTESQL @SQL, N'@VendorNameParam VARCHAR(50), @EntityParam INT', 
                            @VendorNameParam = @Vendor_Name, @EntityParam = @Entity;
        

        我假设您的实际问题更复杂,并且您为此简化了它,但如果您的所有谓词都是使用 IF .. ELSE IF.. ELSE IF 添加的,那么您根本不需要动态 SQL,您可以使用:

        IF @Vendor_Name IS NOT NULL
            BEGIN
                SELECT  * 
                FROM    Table_Name
                WHERE   UPPER(vendors.VENDOR_NAME) LIKE '%' + UPPER(@Vendor_Name) + '%';
            END
        ELSE IF @Entity IS NOT NULL
            BEGIN
                SELECT  * 
                FROM    Table_Name
                WHERE   headers.ORG_ID = @Entity;
            END
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-01-14
          • 2013-03-08
          • 1970-01-01
          • 1970-01-01
          • 2017-05-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多