MSSQL WHERE子句中的CASE - odbc错误

时间:2014-07-26 17:15:00

标签: php sql sql-server odbc case

在我的PHP Web应用程序中,我试图完善逻辑,即用户定义的值,组装一个Transact-SQL查询,该查询过滤该值。然后使用ODBC驱动程序执行查询。复杂的是,过滤仅在派生字段上完成。除了派生字段是使用CASE表达式创建的字段时,这一点工作得非常好。

因此,例如,我有一个派生字段,如下所示:

CASE WHEN [text_result] IS NOT NULL THEN [text_result] ELSE
    CASE WHEN [last_event] = 1 THEN 'processed' ELSE 'unprocessed' END
END

如果我尝试使用值“unprocessed”过滤它,那么最终的汇编查询显然类似于以下内容:

SELECT * FROM table WHERE 
    CASE WHEN [text_result] IS NOT NULL THEN [text_result] ELSE
        CASE WHEN [last_event] = 1 THEN 'processed' ELSE 'unprocessed' END
    END = 'unprocessed'

然而,当这次运行时,我收到以下错误:

Warning: odbc_execute(): SQL error: [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near the keyword 'from'., SQL state 37000 in SQLDescribeParameter in 

我已经尝试运行SQL分析器,发现在初始语句准备期间似乎抛出了错误,并且语句准备SQL似乎是从字段名中截断表达式。所以它看起来像这样:

SET FMTONLY ON select  CASE WHEN [text_result] from table where 1=2 SET FMTONLY OFF go

当我通过MSSQL管理工作室运行生成的SQL语句时,这已得到确认,并且工作正常!

我希望一切都有道理。如果有人有任何建议,如果这个问题是可以解决的,或者它只是驱动程序中的一个错误,那就太好了!

这是我用来运行汇编查询的PHP(从类中提取):

$link = odbc_connect($strConnectionString,$username,$password);
$rResult = odbc_prepare($link,$qry);
$success = odbc_execute($rResult,$parameters);

的var_dump($ QRY,$参数):

string 'SELECT * FROM table WHERE 
        CASE WHEN [text_result] IS NOT NULL THEN [text_result] ELSE
            CASE WHEN [last_event] = 1 THEN 'processed' ELSE 'unprocessed' END
        END = ?'
array (size=1)
  0 => string 'unprocessed'

2 个答案:

答案 0 :(得分:4)

首先,您不需要嵌套的case语句。你可以这样做:

CASE WHEN [text_result] IS NOT NULL THEN [text_result] 
     WHEN [last_event] = 1 THEN 'processed' 
     ELSE 'unprocessed'
END

我发现select错误的一件事是=。你可以写:

SELECT unprocessed = (CASE WHEN [text_result] IS NOT NULL THEN [text_result] 
                           WHEN [last_event] = 1 THEN 'processed' 
                           ELSE 'unprocessed'
                      END)

SELECT (CASE WHEN [text_result] IS NOT NULL THEN [text_result] 
             WHEN [last_event] = 1 THEN 'processed' 
             ELSE 'unprocessed'
        END) as unprocessed

但是,当使用=时,变量首先出现。

然后,我认为您不能使用?指定列别名。您必须构造其中包含列别名的查询字符串。

答案 1 :(得分:0)

您有太多case个符号:

DECLARE  @tableA Table
(
    text_result varchar(20),
    last_event int
)

INSERT INTO @tableA
VALUES
    (null, 1),
    (null, 2),
    ('xxxx', 3)

SELECT *
FROM @tableA
WHERE 
    CASE WHEN text_result IS NOT NULL THEN text_result  
         WHEN last_event = 1 THEN 'processed' 
    ELSE 'unprocessed' END = 'unprocessed'