阻止 JDBC 从 char 字段中删除空格

Stop JDBC from removing whitespaces from a char field

我在 Informix 数据库中有一个 table 和一组 char(5) 字段。

由于我不知道的原因,后端有一些验证实际上会检查来自 Informix DB 的对象是否包含设置为 " "(五个空格)的字段。

这意味着另一个系统正在存储一个新对象,将此字段留空(非空),因此我检查了数据库,发现该字段包含空格。但是一旦我开始调试 Java 应用程序,从数据库查询中获取对象后,空格就会被删除。

I have a table with a set of char(5) fields in an Informix database.

... 在这种情况下,任何这些列中的每个 non-null 值都恰好包含 5 个字符,不少于此。插入到这些列中的值将根据需要被截断或填充 spaces 以确保。

once I start debugging the Java application, the spaces are removed after getting an object from the DB query.

这无疑是您 JDBC driver 的行为。它可能可配置也可能不可配置,具体取决于 driver。据推测 driver 是 trimming space 的效果几乎完全符合您观察到的效果,但这不是任意的。修剪 spaces 具有反转自动添加的 space 填充的效果,结果是,例如,如果您存储一个空字符串,那么您读回一个空字符串。

char(n) 数据类型的固有特性* 不区分仅尾随 space 数量不同的值,因此无论您是否可以说服 driver 停止 trimming 尾随 space,您的代码都需要以这种或另一种方式处理。最可靠的方法是 手动 trim (或填充)从数据库中读取的值,并对你想要的 otherwise-sourced 值执行相同的操作来和他们比较。例如:

boolean isEqualTrimmed(String s1, String s2) {
    // assumes s1 and s2 are both non-null:
    return s1.stripTrailing().equals(s2.stripTrailing());
}

*区别于varchar(n)数据类型。

您可能需要更新的 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 驱动程序中确实存在一个自动 trim char 列的连接参数,但默认情况下是 OFF

将 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