2014-07-26 68 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

見我對之前的回答發表了評論,我相信你錯過了引號。 –