2014-07-26 39 views
5

在我的PHP Web应用程序中,我试图完善逻辑,即一个用户定义的值,组装一个Transact-SQL查询,该查询对该值进行过滤。该查询然后使用ODBC驱动程序执行。并发症是过滤只能在派生字段上完成。除非派生字段是使用CASE表达式创建的字段,否则这是工作绝对正常的。MSSQL WHERE子句中的CASE - odbc错误

因此,举例来说,我有一个派生领域,如下列:

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

如果我尝试和筛选此使用值“未处理”,那么最终组装查询显然是一个类似于以下:

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' 
+0

显示你的PHP blahblah。 – Mihai

+0

当然,PHP添加。 – Raiden616

+0

请在你共享的代码之前运行'var_dump($ qry,$ parameters)'。 –

回答

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 

但是,使用=时,变量是第一位的。

然后,我不认为你可以使用?指定列别名。您必须构造带有列别名名称的查询字符串。

+0

?用户输入的占位符是通过预处理语句传入的,而不是列别名?那么应该如何?先来(使结果“...未处理'=(CASE ..)”)? – Raiden616

+0

@ user1014679。 。 。这就是我的意思。我不认为你可以指定一个列别名作为准备语句中的参数。 –

+0

“未处理”不是列别名,它是值... – Raiden616

0

你有太多case stataments:

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' 
+0

如果我删除嵌套case语句(例如'... WHERE CASE WHEN text_result不为NULL, ?') – Raiden616

+0

这工作:'QRY =新MSSQLQuery( “选择 '你好' WHERE '富'= ( \t CASE WHEN 1 = 1 THEN '富' ELSE '酒吧' END )”);'。这不:'QRY =新MSSQLQuery( “?选择 '你好' WHERE ( \t CASE WHEN 1 = 1,那么 '富' ELSE '酒吧' END )=”, “富”);' – Raiden616

+0

见我对之前的回答发表了评论,我相信你错过了引号。 –