2012-02-01 17 views
7

Dada la siguiente tabla:¿Cómo hacer que = NULL funcione en SQLite?

 
Table: Comedians 
================= 

Id First Middle Last 
--- ------- -------- ------- 
1  Bob  NULL  Sagat 
2 Jerry  Kal  Seinfeld  

quiero hacer la siguiente consulta preparada:

 
SELECT * FROM Comedians WHERE Middle=? 

trabajo para todos los casos. Actualmente no funciona para el caso en que paso NULL a través del sqlite3_bind_null. Me doy cuenta de que la consulta para buscar realmente valores NULL usa IS NULL, pero eso significa que no puedo usar la consulta preparada para todos los casos. De hecho, tendría que cambiar la consulta en función de la entrada, lo que en gran medida frustra el propósito de la consulta preparada. ¿Cómo hago esto? ¡Gracias!

+0

¿Cómo lo haría un usuario buscar un comediante sin un segundo nombre? – Mithrandir

+0

@Mithrandir Esta no es una función para el usuario, es para uso interno. Esencialmente, paso un puntero (char *) a la función. Si el puntero es NULL, uso 'sqlite3_bind_null' pero si es la cadena 'NULL' uso la función de cadena. – chacham15

Respuesta

7

Puede usar el IS operator en lugar de =.

SELECT * FROM Comedians WHERE Middle IS ? 
+2

maldita sea, ¿es solo en SQLite? Eso sería tan útil en otros SQL ... – dotjoe

+0

¡increíble! ¡justo lo que estaba buscando! – chacham15

+2

@dotje: en PostgreSQL puede usar 'a IS NOT DISTINCT FROM b'. Un poco más caro que 'a = b'. –

4

Nada coincide con = NULL. La única manera de verificar esto es con IS NULL.

Se puede hacer una variedad de cosas, pero la de proa recta es ...

WHERE 
    middle = ? 
    OR (middle IS NULL and ? IS NULL) 

Si hay un valor que no aparece nunca sabe, usted puede cambiar eso a ...

WHERE 
    COALESCE(middle, '-') = COALESCE(?, '-') 

Pero necesita un valor que literalmente NUNCA aparece. Además, ofusca el uso de índices, pero la versión OR a menudo también puede ser una mierda (no sé qué tan bien lo trata SQLite).

Todo lo demás igual, recomiendo la primera versión.

2

NULL no es un valor, sino un atributo de un campo. En su lugar utilizar

SELECT * FROM Comedians WHERE Middle IS NULL 
+0

esto no es una solución genérica ya que no me permite probar la igualdad con algo que no sea nulo – chacham15

+0

@ chacham15: No hay una solución genérica que use NULL, ya que no es un valor. Tal vez deberías usar un [valor centinela] (http://en.wikipedia.org/wiki/Sentinel_value) en su lugar. – wallyk

+0

ver respuesta aceptada – chacham15

0

Si desea igualar todo en NULL

SELECT * FROM Comedians WHERE Middle=IfNull(?, Middle) 

si desea que coincida con ninguno en NULL

SELECT * FROM Comedians WHERE Middle=IfNull(?, 'DUMMY'+Middle) 

Ver esta respuesta: https://stackoverflow.com/a/799406/30225

Cuestiones relacionadas