Cómo escribir una comparación nula segura & # 8220; < = > & # 8221; en SQL puro?
Pregunta
En Mysql hay un operador de comparación que es seguro para nulos: < = > ;. Utilizo esto en mi programa Java cuando creo declaraciones preparadas como esta:
String routerAddress = getSomeValue();
String sql = "SELECT * FROM ROUTERS WHERE ROUTER_ADDRESS <=> ? ";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, routerAddress);
Ahora me gustaría cambiar a la base de datos H2. ¿Cómo escribo el < = > operador en SQL puro (usando, por ejemplo, IS NULL e IS NOT NULL)? Me gustaría usar la operación stmt.setString solo una vez . Está bien escribir el nombre de la columna varias veces.
La pregunta relacionada es Get null == null in SQL . Pero esa respuesta requiere que el valor de la búsqueda se escriba 2 veces (es decir: ¡2 signos de interrogación en mi estado de preparación)?
Referencia: http://dev.mysql.com/ doc / refman / 5.0 / es / comparación-operadores.html # operator_equal-to
Solución
La pregunta relacionada es Obtener nulo == nulo en SQL. Pero esa respuesta requiere que el valor de la búsqueda se escriba 2 veces (es decir: ¡2 signos de interrogación en mi estado de preparación)?
Las respuestas de segundo rango y posteriores proporcionan un método para hacer esto sin vincular el valor de búsqueda dos veces:
SELECT * FROM ROUTERS
WHERE coalesce(ROUTER_ADDRESS, '') = coalesce( ?, '');
Tenga en cuenta que esto requiere un valor ficticio que nunca puede ser un valor de columna válido (que está " fuera de banda "); Estoy usando la cadena vacía. Si no tiene tal valor, tendrá que aguantar la vinculación del valor dos veces:
SELECT * FROM ROUTERS
WHERE ROUTER_ADDRESS = ? or (ROUTER_ADDRESS is null and ? is null);
Otros consejos
Los operadores de igualdad estándar seguros en NULL en SQL son SE DISTINTA DE
y NO SE DISTINTA DE
.
En SQL, NULL no es igual a sí mismo. Así que puedes:
1 - Reemplácelo con un valor ficticio y compárelos, como en:
SELECT * FROM ROUTERS WHERE ISNULL(ROUTER_ADDRESS,'xxx') <=> ISNULL(?,'xxx')
o
2 - Reemplácelo con una prueba lógica más elaborada, como en:
SELECT *
FROM ROUTERS
WHERE (
(ROUTER_ADDRESS IS NULL AND ? IS NOT NULL)
OR
(ROUTER_ADDRESS IS NOT NULL AND ? IS NULL)
OR
(ROUTER_ADDRESS IS NOT NULL AND ? IS NOT NULL AND ROUTER_ADDRESS <> ?
)
Si quieres ROUTERS donde ROUTER_ADDRESS es nulo, ¿cuándo? es nulo, entonces posiblemente esto podría funcionar:
SELECT *
FROM ROUTERS
WHERE ROUTER_ADDRESS = (case when ROUTER_ADDRESS is null and ? is null then null
else ? end)