【问题标题】:Java string .length() X does not fit into DB2 varchar(X)Java 字符串 .length() X 不适合 DB2 varchar(X)
【发布时间】:2013-10-09 19:03:04
【问题描述】:

我观察到一个问题,我试图在 DB2 数据库中保存一条记录,其中包含在 Java 代码中进行长度检查的字段。我保持长度检查完全等于数据库 varchar 限制。并试图保存但得到 SQL Exception DB2 SQL Error: SQLCODE=-302, SQLSTATE=22001, SQLERRMC=null, DRIVER=3.57.82;

然后我减小长度(截断)长度小于数据库大小。为 varchar(1000) 截断为子字符串 (0, 900) apprx。

请告诉我可能是什么原因。它与字符编码有关吗? 需要如何处理?

应用于字符串的默认字符编码是什么(从文本区域字段的请求参数输入)和对应的编号。字节数?

【问题讨论】:

  • 肯定有字符编码问题。 java中的字符实际上是作为代码点实现的。有些字符需要两个代码点才能准确描述。这意味着即使一个字符串可能只显示 1000 的长度,它实际上可能包含 2000 个代码点。
  • It seems 您可能需要最多 3 倍的字符串长度。

标签: java character-encoding size varchar string-length


【解决方案1】:

DB2 以字节为单位计算字符串长度,而不是字符。因此,您可以存储的字符串的最大长度可以比​​为 varchar 指定的大小短很多。

不幸的是,将字符串截断为多个字节的唯一方法是将其编码为字节,截断并重建字符串。从您所说的听起来像是使用了可变长度编码,例如 UTF-8。困难的部分是最后不产生无效字符,而做到这一点的方法是使用 NIO charset API:

import java.nio.*;
...
CharBuffer in = CharBuffer.wrap(stringToTruncate);
ByteBuffer out = ByteBuffer.allocate(maxLength);
Charset db2charset = Charset.forName("UTF-8");
CharsetEncoder db2encoder = db2charset.newEncoder();
db2encoder.encode(in, out, true);
out.flip();
return db2charset.decode(out).toString();

【讨论】:

  • 非常感谢您提供解决方案。这是对所有应用程序非常常见的检查。那么这是贯穿所有应用程序开发的最佳实践吗?我想知道专家对此的看法:)
  • 我不会称自己为专家,因为我认为必须破坏用户数据以使其适合数据库的情况应该是非常罕见的;相反,数据库应该为用户服务。我不得不这样做一次,以存储从日志文件中读取的错误消息,其中最长的消息可能包括堆栈跟踪和其他冗长的调试信息,但前 200 个字符对于大多数时间的用户来说已经足够了,如果他们需要看到更多他们可以打开原始文件
猜你喜欢
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-24
相关资源
最近更新 更多