null安全な比較の書き方“< =>”純粋なSQLで?
質問
Mysqlには、nullセーフである比較演算子< =>があります。次のような準備済みステートメントを作成するときに、Javaプログラムでこれを使用します。
String routerAddress = getSomeValue();
String sql = "SELECT * FROM ROUTERS WHERE ROUTER_ADDRESS <=> ? ";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, routerAddress);
今、H2データベースに切り替えたいと思います。 &lt; =&gt;の書き方純粋なSQLの演算子(たとえば、IS NULLおよびIS NOT NULLを使用)? stmt.setString操作は 1回のみ使用したいです。列名を何度か書いても構いません。
関連する質問は、 SQLでnull == nullを取得です。しかし、その答えは、検索値が2回書き込まれることを必要とします(つまり、PreparedStatementで2つの疑問符)!?
リファレンス: http://dev.mysql.com/ doc / refman / 5.0 / en / comparison-operators.html#operator_equal-to
解決
関連する質問は、SQLでnull == nullを取得することです。しかし、その答えは、検索値が2回書き込まれることを必要とします(つまり、PreparedStatementで2つの疑問符)!?
2番目以降の回答は、検索値を2回バインドせずにこれを行う方法を示しています。
SELECT * FROM ROUTERS
WHERE coalesce(ROUTER_ADDRESS, '') = coalesce( ?, '');
これには、有効な列値にはならないダミー値が必要であることに注意してください(これは「帯域外」です)。空の文字列を使用しています。そのような値がない場合は、値を2回バインドするのを我慢する必要があります。
SELECT * FROM ROUTERS
WHERE ROUTER_ADDRESS = ? or (ROUTER_ADDRESS is null and ? is null);
他のヒント
SQLの標準のNULLセーフな等価演算子は、 IS DISTINCT FROM
および IS NOT DISTINCT FROM
です。
SQLでは、NULLはそれ自体と等しくありません。次のいずれかを実行できます。
1-次のように、ダミー値に置き換えて比較します。
SELECT * FROM ROUTERS WHERE ISNULL(ROUTER_ADDRESS,'xxx') <=> ISNULL(?,'xxx')
または
2-次のように、より複雑な論理テストに置き換えます:
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 <> ?
)
ROUTER_ADDRESSがnullであるROUTERSが必要な場合nullの場合、これはおそらく動作する可能性があります:
SELECT *
FROM ROUTERS
WHERE ROUTER_ADDRESS = (case when ROUTER_ADDRESS is null and ? is null then null
else ? end)