CAS dans la clause MSSQL WHERE – erreur odbc

Dans mon application web PHP, j'essaie de mettre au point une logique qui, une valeur définie par l'user, assemble une requête Transact-SQL qui filter sur cette valeur. La requête est ensuite exécutée à l'aide du pilote ODBC. La complication est que le filtrage ne sera effectué que sur des champs dérivés. Cela fonctionne absolument bien sauf lorsque le champ dérivé est un champ créé en utilisant une expression CASE.

Ainsi, par exemple, j'ai un champ dérivé comme celui-ci:

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

Si j'essaie de filterr ceci en utilisant la valeur "non traité" alors la requête finale assemblée est évidemment quelque chose qui ressemble à ceci:

 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' 

Cependant, lorsque cela fonctionne, je reçois l'erreur suivante:

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

J'ai essayé d'exécuter le profileur SQL et j'ai découvert qu'il semble que l'erreur est levée lors de la préparation de l'instruction initiale et que l'instruction SQL de préparation de l'instruction tronque l'expression du nom du champ. Donc ça ressemble à ceci:

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

Ceci est confirmé lorsque j'exécute l'instruction SQL générée à travers le studio de gestion MSSQL et ça fonctionne très bien!

J'espère que tout a un sens. Si quelqu'un a des conseils quant à savoir si ce problème est résolu ou si c'est juste un bug dans le conducteur ce serait génial!

C'est le PHP que j'utilise pour exécuter la requête assemblée (extraite d'une class):

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

var_dump ($ qry, $ parameters):

 ssortingng '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 => ssortingng 'unprocessed' 

D'abord, vous n'avez pas besoin d'instructions de case nestedes. Vous pouvez juste faire:

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

Une chose que je vois mal avec votre select est le = . Tu peux écrire:

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

ou

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

Mais, en utilisant = , la variable vient en premier.

Ensuite, je ne pense pas que vous pouvez spécifier un alias de colonne en utilisant ? . Vous devez build la string de requête avec le nom de l'alias de la colonne.

Vous avez trop de case jurisprudence:

 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'