Question

In Mysql there is a compare operator that is a null safe: <=>. I use this in my Java program when creating prepared statements like this:

String routerAddress = getSomeValue();
String sql = "SELECT * FROM ROUTERS WHERE ROUTER_ADDRESS <=> ? ";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, routerAddress);

Now I would like to switch to the H2 database. How do I write the <=> operator in pure SQL (using for example IS NULL and IS NOT NULL)? I would like use the stmt.setString operation only once. It is okay to write the column name several times.

Related question is Get null == null in SQL. But that answer requires the search value to be written 2 times (that is: 2 question marks in my PreparedStatement)!?

Reference: http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_equal-to

Was it helpful?

Solution

Related question is Get null == null in SQL. But that answer requires the search value to be written 2 times (that is: 2 question marks in my PreparedStatement)!?

The second-ranked and subsequent answers give a method to do this without binding the search value twice:

SELECT * FROM ROUTERS 
WHERE coalesce(ROUTER_ADDRESS, '') = coalesce( ?, '');

Note that this requires a dummy value that can never be valid column value (that's "out of band"); I'm using the empty string. If you don't have any such value, you'll have to put up with binding the value twice:

SELECT * FROM ROUTERS 
WHERE ROUTER_ADDRESS = ? or (ROUTER_ADDRESS is null and ? is null);

OTHER TIPS

The standard NULL-safe equality operators in SQL are IS DISTINCT FROM and IS NOT DISTINCT FROM.

In SQL, NULL is not equal to itself. So you can either:

1 - Replace it with a dummy value and compare those, as in:

SELECT * FROM ROUTERS WHERE ISNULL(ROUTER_ADDRESS,'xxx') <=> ISNULL(?,'xxx')

or

2 - Replace it with a more elaborate logical test, as 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 <> ?
      )

If you want ROUTERS where ROUTER_ADDRESS is null when ? is null then possibly this could work:

SELECT * 
FROM ROUTERS 
WHERE ROUTER_ADDRESS = (case when ROUTER_ADDRESS is null and ? is null then null 
                             else ? end)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top