在 where 子句中添加动态条件

Adding dynamic condition in where clause

我想在 'where' 子句中添加条件取决于 'if' 条件,如下所示

  Declare @strSQLClause varchar(50)
  If (@QMasterCompanyId='09' and @State='FL' and (@LOB='HO' or @LOB='HP'))
    Begin
        Declare @strMonthsOccupied char(1)
        select Distinct @strMonthsOccupied=sm.MonthsOccupiedDesc from HOStructureRating sr 
            join HOSeleMonthsOccupied sm on sr.MonthsOccupied=sm.MonthsOccupiedCd
            where AppId=@AppId
        If(CONVERT(int,LTRIM(RTrim(@strMonthsOccupied))) > 9)
        Begin
         set @strSQLClause ='AND QuestionCd!=Q8'
        End 
  Else 
    set @strSQLClause =''
  End

这样在我的查询中将作为

 select * from SHSeleQuestions where  MasterCompanyId='09'  + @strSQLClause 

但是这种方法效果不佳,谁能帮我解决这个问题。

有两种方法可以做到这一点,一种是使用动态sql,另一种是下面提到的:

select * 
from SHSeleQuestions 
where  MasterCompanyId='09'  AND
       1 = CASE WHEN LEN(@strSQLClause) > 0 AND QuestionCd != 'Q8' THEN 1 
                WHEN LEN(@strSQLClause) = 0 THEN 1 END 

使用动态 SQL

EXEC('select * from SHSeleQuestions where  MasterCompanyId=''09'''  + @strSQLClause ')

您需要使用动态 SQL,但为什么不只使用两个执行 SQL 的语句,而不是 set @strSQLClause = 'AND ...',只需使用一个 select 语句这里有你需要的条件

IF (@QMasterCompanyId='09' AND @State='FL' AND (@LOB='HO' OR @LOB='HP'))
BEGIN
    DECLARE @strMonthsOccupied CHAR(1)
    SELECT  DISTINCT @strMonthsOccupied = sm.MonthsOccupiedDesc 
    FROM    HOStructureRating sr 
            INNER JOIN HOSeleMonthsOccupied sm 
                ON sr.MonthsOccupied=sm.MonthsOccupiedCd
    WHERE   AppId=@AppId;

    IF(CONVERT(INT,LTRIM(RTRIM(@strMonthsOccupied))) > 9)
    BEGIN
        SELECT  * 
        FROM    SHSeleQuestions 
        WHERE   MasterCompanyId='09' 
        AND     QuestionCd!='Q8';
        RETURN;
    END
END

SELECT  * 
FROM    SHSeleQuestions 
WHERE   MasterCompanyId='09';

话虽这么说,上面的问题太多了,我真的不知道从哪里开始。您声明您的变量,然后为其分配一个不确定的值:

DECLARE @strMonthsOccupied CHAR(1)

SELECT  DISTINCT @strMonthsOccupied = sm.MonthsOccupiedDesc 
FROM    HOStructureRating sr 
        INNER JOIN HOSeleMonthsOccupied sm 
            ON sr.MonthsOccupied=sm.MonthsOccupiedCd
WHERE   AppId=@AppId;

如果查询 returns 多行,则没有明确的逻辑应该为变量分配哪个值。下一个问题是这个 CHAR(1) 变量显然是一个基于您尝试转换的数字:

IF(CONVERT(INT,LTRIM(RTRIM(@strMonthsOccupied))) > 9)

为什么不去掉中间人并声明一个 INT 开始。下一点是,它是一个 CHAR(1),因此实际上并不足以存储大于 9 的任何内容,因此您的上述条件将 永远不会 成立。

即使 sm.MonthsOccupiedDesc10,变量也会简单地被截断为 1,它小于 9,因此不符合条件,例如

DECLARE @strMonthsOccupied CHAR(1) = '10';
IF(CONVERT(INT,LTRIM(RTRIM(@strMonthsOccupied))) > 9)
    PRINT 'TRUE';
ELSE
    PRINT 'FALSE';