Как написать безопасное сравнение с нулем “<=>” в чистом SQL?

StackOverflow https://stackoverflow.com/questions/802612

  •  03-07-2019
  •  | 
  •  

Вопрос

В Mysql есть оператор сравнения, который является безопасным с нулевым значением:<=>.Я использую это в своей Java-программе при создании подготовленных операторов, подобных этому:

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

Теперь я хотел бы переключиться на базу данных H2.Как мне написать <=> оператор в чистом SQL (используя, например, значение NULL и НЕ является NULL)?Я бы хотел использовать только операцию stmt.setString однажды.Это нормально - написать название столбца несколько раз.

Связанный с этим вопрос заключается в следующем Получаем null == null в SQL.Но этот ответ требует, чтобы значение поиска было записано 2 раза (то есть:2 вопросительных знака в моем подготовленном заявлении)!?

Ссылка:http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_equal-to

Это было полезно?

Решение

Связанный с этим вопрос - Get null == null в SQL.Но этот ответ требует, чтобы значение поиска было записано 2 раза (то есть:2 вопросительных знака в моем подготовленном заявлении)!?

Ответы со вторым рейтингом и последующие ответы дают способ сделать это без привязки значения поиска дважды:

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

Обратите внимание, что для этого требуется фиктивное значение, которое никогда не может быть допустимым значением столбца (это "вне диапазона").;Я использую пустую строку.Если у вас нет такого значения, вам придется смириться с двойной привязкой значения:

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

Другие советы

Стандартными операторами равенства, защищенными от нуля, в SQL являются 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 равен нулю, когда?равно нулю, тогда, возможно, это могло бы сработать:

SELECT * 
FROM ROUTERS 
WHERE ROUTER_ADDRESS = (case when ROUTER_ADDRESS is null and ? is null then null 
                             else ? end)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top