【发布时间】:2021-06-12 00:10:20
【问题描述】:
我在 Informix 数据库中有一个包含一组 char(5) 字段的表。
由于我不知道的原因,后端有一些验证将实际检查来自 Informix DB 的对象是否包含设置为 " " 的字段(五个空格)。
这意味着另一个系统正在存储一个新对象,将该字段留空(非空),所以我检查了数据库,该字段包含空格。但是一旦我开始调试 Java 应用程序,在从 DB 查询中获取对象后,空格就会被删除。
【问题讨论】:
我在 Informix 数据库中有一个包含一组 char(5) 字段的表。
由于我不知道的原因,后端有一些验证将实际检查来自 Informix DB 的对象是否包含设置为 " " 的字段(五个空格)。
这意味着另一个系统正在存储一个新对象,将该字段留空(非空),所以我检查了数据库,该字段包含空格。但是一旦我开始调试 Java 应用程序,在从 DB 查询中获取对象后,空格就会被删除。
【问题讨论】:
将 jdbc 参数添加到您的 url:;IFX_TRIMTRAILINGSPACES=0
例如:jdbc:informix-sqli://dbhost:service/database:INFORMIXSERVER=ifxserver;IFX_TRIMTRAILINGSPACES=0
你可以像这样添加额外的参数:
jdbc:informix-sqli://dbhost:service/database:INFORMIXSERVER=ifxserver;IFX_TRIMTRAILINGSPACES=0;IFX_LOCK_MODE_WAIT=1
【讨论】:
您可能需要更新的 JDBC 驱动程序?我使用 Informix 4.50.JC5 JDBC 驱动程序进行了测试,它似乎可以正确保留空格。
try(Statement s = c.createStatement()) {
s.execute("CREATE TABLE IF NOT EXISTS foo( a1 char(5))");
s.execute("INSERT INTO foo (a1) VALUES(' ')");
s.execute("INSERT INTO foo (a1) VALUES('')");
s.execute("INSERT INTO foo (a1) VALUES(null)");
try(ResultSet rs = s.executeQuery("SELECT a1 FROM foo")) {
while(rs.next()) {
System.out.println("Output: '" + rs.getString(1) + "'");
}
}
}
产生我期望的结果
Output: ' '
Output: ' '
Output: 'null'
在 JDBC 驱动程序中确实存在一个会自动修剪 char 列的连接参数,但默认为OFF。
【讨论】:
我在 Informix 数据库中有一个包含一组
char(5)字段的表。
... 在这种情况下,任何这些列中的每个非空值都恰好包含 5 个字符,不少于。插入到这些列中的值将根据需要被截断或填充空格以确保这一点。
一旦我开始调试 Java 应用程序,空格就会被删除 从数据库查询中获取对象后。
这无疑是您的 JDBC 驱动程序的行为。它可能是可配置的,也可能是不可配置的,具体取决于驱动程序。据推测,驱动程序正在修剪空间以几乎完全达到您观察到的效果,但这不是任意的。修剪空格具有反转自动添加的空格填充的效果,例如,如果您存储一个空字符串,那么您会读回一个空字符串。
char(n) 数据类型的固有特征*它们不区分仅在尾随空格数量上不同的值,因此您的代码需要以一种方式处理或另一个不管你是否可以说服司机停止修剪尾随空格。执行此操作的最可靠方法是手动修剪(或填充)从数据库读取的值,并对要与它们进行比较的其他来源的值执行相同操作。例如:
boolean isEqualTrimmed(String s1, String s2) {
// assumes s1 and s2 are both non-null:
return s1.stripTrailing().equals(s2.stripTrailing());
}
*区别于varchar(n)数据类型。
【讨论】: