2009-03-11 17 views
6

Sto provando a implementare i parametri facoltativi in ​​una procedura memorizzata che ho ma sto correndo in un problema. Ecco una query semplificato per illustrare il problema:SQL Coalesce nella clausola WHERE

SET ANSI_NULLS OFF 

DECLARE @MiddleName VARCHAR(20); 
SET @MiddleName = NULL; 

SELECT * FROM [Customer] 
WHERE [LastName] = 'Torres' 
AND [MiddleName] = COALESCE(@MiddleName, [MiddleName]) 

Quando faccio funzionare questa domanda ho bisogno di ottenere una fila indietro perché uno Torres ha NULL nella colonna [MiddleName]. Ma la query restituisce zero righe. L'uso di IFNULL() produce lo stesso risultato. Dalla ricerca su COALESCE, ho avuto l'impressione che NULL sarebbe stato restituito se tutte le espressioni fossero NULL. Dato che non sono un esperto di SQL, presumo che mi manchi qualcosa, ma che cos'è .....

Grazie in anticipo per qualsiasi aiuto.

+0

sto cercando di interpretare ciò che si sta dicendo in modo corretto. Penso che tu intenda quanto segue: come usi coalescenza per dire tutte le righe se null altrimenti solo le righe che corrispondono. In tal caso, farei qualcosa come COALESCE (@MiddleName, '') = '' OR @ MiddleName = [MiddleName] nella clausola where. – geoffrobinson

risposta

12

Il problema è che in sql, "WHERE Null = Null" non restituirà mai alcuna riga poiché Null non è uguale a se stesso.

quello che dovete fare

SELECT * FROM [Customer] 
WHERE [LastName] = 'Torres' 
AND (@MiddleName IS NULL OR [MiddleName] = @MiddleName) 
+2

Un'altra alternativa è: COALESCE ([MiddleName], '') = COALESCE (@MiddleName, [MiddleName], '') –

+0

utilizzando "@var IS NULL" restituisce una costante che l'ottimizzatore può utilizzare per collegare la condizione. Il suggerimento di Joel richiederebbe '' di essere confrontato con ogni MiddleName. Nell'esempio di David, il MiddleName non deve mai essere confrontato come lo sa l'ottimizzatore TRUE O è sempre vero. – MatBailie

2

Stai provando a farlo?

SELECT * FROM [Customer] 
WHERE [LastName] = 'Torres' 
AND ([MiddleName] = @MiddleName OR @MiddleName IS NULL) 

Da quello che ho capito sembra.

+0

mancano alcune parentesi: AND ([MiddleName] = @MiddleName OPPURE [MiddleName] È NULL) – TrevorD

+0

hmm, potrebbe anche essere necessario inserire [Nome_Middiale] prima NULLO – TrevorD

+0

[Nome_Middiale] è NULL prima? perché? – gcores

2

vostri COALESCE restituisce NULL quando il parametro @MiddleName e la colonna MiddleName sono entrambi NULL, ma il test valuteranno false perché a NULL does not equal any other NULL.

Per risolvere questo si dovrebbe verificare in modo esplicito il parametro @MiddleName di nullità:

SELECT * 
FROM [Customer] 
WHERE [LastName] = 'Torres' 
    AND (@MiddleName IS NULL OR [MiddleName] = @MiddleName) 
+0

in modo sbagliato, sta cercando di far sì che se @MiddleName è NULL viene effettivamente ignorato, rendendo il paramtere pseudo opzionale – MatBailie

3

Lei afferma che si sta cercando per la query per restituire la riga in cui il MiddleName campo è NULL. Sfortunatamente (NULL = NULL) non restituisce true, restituisce NULL.

avete bisogno di qualcosa del genere ...

SELECT * FROM [Customer] 
WHERE [LastName] = 'Torres' 
AND ([MiddleName] = @MiddleName OR @MiddleName IS NULL)