Wie ein Null-Safe vergleichen „<=>“ in reiner SQL schreiben?
Frage
In Mysql gibt es einen Vergleichsoperator, der eine Null sicher ist: <=>. Ich verwende in meinem Java-Programm, wenn vorbereitete Anweisungen wie folgt zu erstellen:
String routerAddress = getSomeValue();
String sql = "SELECT * FROM ROUTERS WHERE ROUTER_ADDRESS <=> ? ";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, routerAddress);
Nun möchte Ich mag auf die H2-Datenbank wechseln. Wie kann ich den Operator <=> in reinen SQL schreiben (zum Beispiel unter Verwendung von IS NULL und IS NOT NULL)? Ich möchte nur den stmt.setString Betrieb verwenden einmal . Es ist in Ordnung, die Spaltennamen mehrmals zu schreiben.
Verwandte Frage ist Get null == null in SQL . Aber diese Antwort erfordert der Suchwert 2 mal geschrieben werden!? (Dh: 2 Fragezeichen in meinem PreparedStatement)
Referenz: http://dev.mysql.com/ doc / refman / 5.0 / de / Vergleich-operators.html # operator_equal-to
Lösung
In Verbindung stehende Frage ist null Get == null in SQL. Aber diese Antwort erfordert der Suchwert 2 mal geschrieben werden!? (Dh: 2 Fragezeichen in meinem PreparedStatement)
Die zweitrangierten und nachfolgende Antworten geben eine Methode, dies zu tun, ohne den Suchwert Bindung zweimal:
SELECT * FROM ROUTERS
WHERE coalesce(ROUTER_ADDRESS, '') = coalesce( ?, '');
Beachten Sie, dass dies einen Dummy-Wert erfordert, die nie gültige Spalten Wert sein kann (das ist „out-of-Band“); Ich bin mit dem leeren String zurück. Wenn Sie nicht über einen solchen Wert, werden Sie mit der Bindung den Wert setzen müssen zweimal:
SELECT * FROM ROUTERS
WHERE ROUTER_ADDRESS = ? or (ROUTER_ADDRESS is null and ? is null);
Andere Tipps
Die Standard-NULL-safe Gleichheitsoperatoren in SQL sind IS DISTINCT FROM
und IS NOT DISTINCT FROM
.
In SQL ist NULL sich nicht gleich. So können Sie entweder:
1 - Setzen Sie einen Dummy-Wert und vergleichen Sie die, wie in:
SELECT * FROM ROUTERS WHERE ISNULL(ROUTER_ADDRESS,'xxx') <=> ISNULL(?,'xxx')
oder
2 - Setzen Sie einen aufwändigere logischen Test, wie 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 <> ?
)
Wenn Sie ROUTER wollen, wo ROUTER_ADDRESS ist null, wenn? möglicherweise ist null, dann könnte dies funktionieren:
SELECT *
FROM ROUTERS
WHERE ROUTER_ADDRESS = (case when ROUTER_ADDRESS is null and ? is null then null
else ? end)