Как написать нулевое безопасное сравнение "<=>" в чистом SQL? - PullRequest
7 голосов
/ 29 апреля 2009

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

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

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

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

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

Ответы [ 4 ]

9 голосов
/ 29 апреля 2009

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

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

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

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

SELECT * FROM ROUTERS 
WHERE ROUTER_ADDRESS = ? or (ROUTER_ADDRESS is null and ? is null);
6 голосов
/ 30 марта 2010

Стандартные NULL-безопасные операторы равенства в SQL: IS DISTINCT FROM и IS NOT DISTINCT FROM.

2 голосов
/ 29 апреля 2009

В 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 <> ?
      )
0 голосов
/ 29 апреля 2009

Если вы хотите использовать ROUTERS, где ROUTER_ADDRESS равен нулю, когда? имеет значение null, возможно, это может сработать:

SELECT * 
FROM ROUTERS 
WHERE ROUTER_ADDRESS = (case when ROUTER_ADDRESS is null and ? is null then null 
                             else ? end)
...