Come scrivere un confronto sicuro nullo "< = >" in SQL puro?
Domanda
In Mysql c'è un operatore di confronto che è un sicuro nulla: < = > ;. Lo uso nel mio programma Java durante la creazione di istruzioni preparate come questa:
String routerAddress = getSomeValue();
String sql = "SELECT * FROM ROUTERS WHERE ROUTER_ADDRESS <=> ? ";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, routerAddress);
Ora vorrei passare al database H2. Come scrivo < = > operatore in SQL puro (utilizzando ad esempio IS NULL e IS NOT NULL)? Vorrei utilizzare l'operazione stmt.setString solo una volta . Va bene scrivere più volte il nome della colonna.
La domanda correlata è Ottieni null == null in SQL . Ma quella risposta richiede che il valore di ricerca sia scritto 2 volte (ovvero: 2 punti interrogativi nel mio PreparedStatement) !?
Riferimento: http://dev.mysql.com/ doc / refman / 5.0 / it / confronto-operators.html # operator_equal-to
Soluzione
La domanda correlata è Ottieni null == null in SQL. Ma quella risposta richiede che il valore di ricerca sia scritto 2 volte (ovvero: 2 punti interrogativi nel mio PreparedStatement) !?
Le risposte del secondo classificato e successive forniscono un metodo per eseguire questa operazione senza associare due volte il valore di ricerca:
SELECT * FROM ROUTERS
WHERE coalesce(ROUTER_ADDRESS, '') = coalesce( ?, '');
Nota che questo richiede un valore fittizio che non può mai essere un valore di colonna valido (che è "fuori banda"); Sto usando la stringa vuota. Se non si dispone di tale valore, è necessario tollerare il valore due volte:
SELECT * FROM ROUTERS
WHERE ROUTER_ADDRESS = ? or (ROUTER_ADDRESS is null and ? is null);
Altri suggerimenti
Gli operatori di uguaglianza NULL sicuri in SQL sono IS DISTINCT FROM
e IS DISTINCT FROM
.
In SQL, NULL non è uguale a se stesso. Quindi puoi:
1 - Sostituiscilo con un valore fittizio e confronta quelli, come in:
SELECT * FROM ROUTERS WHERE ISNULL(ROUTER_ADDRESS,'xxx') <=> ISNULL(?,'xxx')
o
2 - Sostituiscilo con un test logico più elaborato, come in:
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 <> ?
)
Se vuoi ROUTERS dove ROUTER_ADDRESS è null quando? è nullo quindi probabilmente questo potrebbe funzionare:
SELECT *
FROM ROUTERS
WHERE ROUTER_ADDRESS = (case when ROUTER_ADDRESS is null and ? is null then null
else ? end)