在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 操作一次。 列名多写几次就可以了。
相关问题是Get null == null in SQL。 但是这个答案需要将搜索值写入2次(即:我的PreparedStatement中的2个问号)!?
参考:
http://dev.mysql.com/ doc/refman/5.0/en/comparison-operators.html#operator_equal-to
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
发布评论
评论(5)
排名第二和后续的答案给出了一种方法来执行此操作,而无需两次绑定搜索值:
请注意,这需要一个永远不能是有效列值的虚拟值(即“带外”); 我正在使用空字符串。 如果你没有任何这样的值,你将不得不忍受两次绑定该值:
The second-ranked and subsequent answers give a method to do this without binding the search value twice:
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:
SQL 中标准的 NULL 安全相等运算符是
IS DISTINCT FROM
和IS NOT DISTINCT FROM
。The standard NULL-safe equality operators in SQL are
IS DISTINCT FROM
andIS NOT DISTINCT FROM
.在 SQL 中,NULL 不等于其自身。 因此,您可以:
1 - 将其替换为虚拟值并比较它们,如:
或
2 - 将其替换为更复杂的逻辑测试,如:
In SQL, NULL is not equal to itself. So you can either:
1 - Replace it with a dummy value and compare those, as in:
or
2 - Replace it with a more elaborate logical test, as in:
如果您想要 ROUTERS,其中 ROUTER_ADDRESS 何时为空? 为 null 那么这可能有效:
If you want ROUTERS where ROUTER_ADDRESS is null when ? is null then possibly this could work:
重写<=>的正确答案是 在纯 SQL 中(因为您没有使用 MySQL)是
“IS NOT DISTINCT FROM”,
假设您的数据库引擎支持它。 (MySQL 没有,但许多其他数据库系统有)
如果做不到这一点,许多其他数据库系统都有自己的专有技巧。
如果两者都没有,则需要合并到 where 子句内的无效数据。
应该适用于字符或文本字段。 (我的意思是确切的字符串,它永远不应该显示在真实数据中)。 非文本字段比较棘手,因为 sql 喜欢进行隐式转换,这使得合并到带外数据变得非常困难。 如果字段仅包含过去的日期,您可以将空值合并到遥远的未来。 如果字段仅包含特定日期之后的日期,则可以合并到遥远的过去。 对于无符号数字,您可以将它们合并为 -1(即使该字段不能包含负 1,该比较仍然有效)。
如果这不是一个选择,你就必须进行非常愚蠢的长检查。
如果您实际上不需要将 null 与空不同地考虑,您可以合并到它,但这仅适用于文本/字符。
The correct answer for rewriting <=> in pure SQL (because you aren't using MySQL) is
"IS NOT DISTINCT FROM"
assuming that your database engine supports it. (MySQL does NOT, but many others do)
Failing that, many other database systems have their own proprietary tricks.
If you have neither, you need to coalesce to invalid data inside of the where clause.
should work for char or text fields. (and i mean that exact string, which should never show in real data). non text fields are trickier, because sql likes to do implicit conversions, which make it very difficult to coalesce to out of band data. if a field contains only past dates, you can coalesce nulls to the far future. if a field contains only dates after a certain one, you can coalesce to the far past. For unsigned numbers, you can coalesce them to -1 (the comparison will still work, even though the field can't contain negative 1).
If that's not an option, you have to make really stupidly long checks.
If you don't actually need to consider null differently from empty, you can coalesce to that instead, but that only works for text/char.