Java “如何编写空安全比较”<=&燃气轮机&引用;在纯SQL中?

Java “如何编写空安全比较”<=&燃气轮机&引用;在纯SQL中?,java,sql,mysql,null,h2,Java,Sql,Mysql,Null,H2,在Mysql中,有一个比较运算符是空安全的:。当我在Java程序中创建这样的准备语句时,我会使用它: String routerAddress = getSomeValue(); String sql = "SELECT * FROM ROUTERS WHERE ROUTER_ADDRESS <=> ? "; PreparedStatement stmt = connection.prepareStatement(sql); stmt.setString(1, routerAddre

在Mysql中,有一个比较运算符是空安全的:。当我在Java程序中创建这样的准备语句时,我会使用它:

String routerAddress = getSomeValue();
String sql = "SELECT * FROM ROUTERS WHERE ROUTER_ADDRESS <=> ? ";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, routerAddress);
String routerAddress=getSomeValue();
String sql=“从路由器地址所在的路由器中选择*”;
PreparedStatement stmt=connection.prepareStatement(sql);
stmt.setString(1,路由地址);
现在我想切换到H2数据库。如何在纯SQL中编写运算符(例如使用IS NULL和IS NOT NULL)?我只想使用stmt.setString操作一次。可以将列名写几次

相关问题是。但这个答案要求搜索值写两次(即:在我准备的声明中有两个问号)

参考:

相关的问题是SQL中的Get null==null。但这个答案要求搜索值写两次(即:在我准备的声明中有两个问号)

排名第二的答案和后续答案提供了一种方法,可以在不绑定搜索值的情况下执行此操作:

SELECT * FROM ROUTERS 
WHERE coalesce(ROUTER_ADDRESS, '') = coalesce( ?, '');
SELECT * FROM ROUTERS 
WHERE ROUTER_ADDRESS = ? or (ROUTER_ADDRESS is null and ? is null);
请注意,这需要一个虚拟值,该值永远不能是有效的列值(即“带外”);我正在使用空字符串。如果您没有任何此类值,则必须忍受将该值绑定两次:

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

在SQL中,NULL不等于它本身。因此,您可以:

1-将其替换为虚拟值并进行比较,如中所示:

SELECT * FROM ROUTERS WHERE ISNULL(ROUTER_ADDRESS,'xxx') <=> ISNULL(?,'xxx')
从ISNULL(路由器地址,'xxx')为null(?,'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 <> ?
      )
选择*
来自路由器
在哪里(
(路由器_地址为空且?不为空)
或
(路由器_地址不为空且?为空)
或
(路由器地址不为空且?不为空且路由器地址?
)

如果您希望路由器的地址为空,则当?为空时,这可能会起作用:

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

SQL中的标准空安全相等运算符是
不同,
不同

在纯SQL中重写的正确答案是

“与”

假设您的数据库引擎支持它(MySQL不支持,但许多其他数据库引擎支持)

如果做不到这一点,许多其他数据库系统都有自己的专有技巧

如果两者都没有,则需要合并到where子句中的无效数据

COALESCE (a, "__NULL__") 
应该适用于字符或文本字段。(我指的是确切的字符串,它永远不会显示在实际数据中)。非文本字段比较棘手,因为sql喜欢进行隐式转换,这使得合并到带外数据非常困难。如果字段只包含过去的日期,则可以将空值合并到遥远的未来。如果字段只包含某个日期之后的日期,则可以合并到遥远的过去。对于无符号数字,可以合并它们到-1(尽管字段不能包含负1,但比较仍然有效)

如果这不是一个选项,你必须做真正愚蠢的长支票


如果您实际上不需要考虑空与空不同,则可以合并到该值,但只适用于text /char。< /p>不确定我完全理解您想做什么。当您将传入的非空参数上的RouthLyLoad匹配并返回行时,该语句能够返回行吗?传入null时路由器地址为null?是的,正是这样!My getSomeValue()可以返回null和非null值。当它返回null时,我需要路由器地址为null的所有行。在纯(=标准)SQL中,将是

a与b不同的
H2现在也支持此语法。并且它支持(较短但非标准)语法
x是y
x不是y