Como escrever um cofre nula comparar “<=>” em SQL puro?
Pergunta
Em Mysql há um operador de comparação que é uma forma segura nulo: <=>. Eu uso isso no meu programa Java ao criar instruções preparadas como esta:
String routerAddress = getSomeValue();
String sql = "SELECT * FROM ROUTERS WHERE ROUTER_ADDRESS <=> ? ";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, routerAddress);
Agora eu gostaria de mudar para o banco de dados H2. Como faço para escrever o <=> operador em SQL puro (usando, por exemplo IS NULL e IS NOT NULL)? Eu gostaria utilizar apenas a operação stmt.setString uma vez . Não há problema em escrever o nome da coluna várias vezes.
questão relacionada é Get nula == null em SQL . Mas essa resposta exige que o valor de pesquisa a ser escrito 2 vezes!? (Isto é: 2 pontos de interrogação na minha PreparedStatement)
Referência: http://dev.mysql.com/ doc / refman / 5.0 / en / comparison-operators.html # operator_equal-to
Solução
questão relacionada é se nula == null em SQL. Mas essa resposta exige que o valor de pesquisa a ser escrito 2 vezes!? (Isto é: 2 pontos de interrogação na minha PreparedStatement)
A segunda-classificados e subsequentes respostas dar um método de fazer isso sem ligação do valor de pesquisa duas vezes:
SELECT * FROM ROUTERS
WHERE coalesce(ROUTER_ADDRESS, '') = coalesce( ?, '');
Note que isso requer um valor fictício que nunca pode ser valor de coluna válidos (ou de "fora da banda"); Eu estou usando a cadeia vazia. Se você não tem qualquer valor, você vai ter que colocar-se com a ligação do valor duas vezes:
SELECT * FROM ROUTERS
WHERE ROUTER_ADDRESS = ? or (ROUTER_ADDRESS is null and ? is null);
Outras dicas
Os operadores de igualdade NULL-safe padrão em SQL são IS DISTINCT FROM
e IS NOT DISTINCT FROM
.
No SQL, NULL não é igual a si mesmo. Então você pode:
1 - Substitua-o por um valor fictício e comparar aqueles, como em:
SELECT * FROM ROUTERS WHERE ISNULL(ROUTER_ADDRESS,'xxx') <=> ISNULL(?,'xxx')
ou
2 - Substitua-o por um teste lógico mais elaborado, como em:
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 <> ?
)
Se você quiser ROTEADORES onde router_address é nulo quando? é nula, em seguida, possivelmente, isso poderia funcionar:
SELECT *
FROM ROUTERS
WHERE ROUTER_ADDRESS = (case when ROUTER_ADDRESS is null and ? is null then null
else ? end)