Java字符串长度X无法适应于DB2 varchar(X)。

3
我注意到一个问题,我正在尝试在Java代码中将带有长度检查的字段保存到DB2数据库中。我已经将长度检查设置为与数据库varchar限制完全相等。然后尝试保存,但是出现了SQL Exception DB2 SQL Error: SQLCODE=-302,SQLSTATE=22001,SQLERRMC=null,DRIVER=3.57.82;
然后我缩短了长度(截断),使其小于数据库大小。 Varchar(1000)的子字符串被截断为substring(0, 900)。
请告诉我可能的原因。这是否与字符编码有关?应该如何处理?
从文本区域字段的请求参数输入的String类型采用默认字符编码以及相应的字节数是多少?

2
可能存在字符编码问题。在Java中,字符实际上是以代码点的形式实现的。有些字符需要两个代码点才能准确地表示。这意味着即使一个字符串只显示长度为1000,它实际上可能包含2000个代码点。 - hooknc
看起来你可能需要字符串长度的三倍。 - PM 77-1
1个回答

4

DB2计算字符串长度时是按字节而不是字符计算的。因此,您可以存储的字符串最大长度可能比varchar给出的大小要短得多。

不幸的是,将字符串截断为指定字节数的唯一方法是将其编码为字节,然后进行截断和重构。从您所说的内容来看,使用的是可变长度编码,例如UTF-8。困难的部分不是在末尾产生无效字符,而是使用NIO字符集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();

非常感谢您提供的解决方案。这是所有应用程序的常见检查。那么,这是否是在所有应用程序开发中应该应用的最佳实践?我想知道专家对此的看法 :) - Sandip Bhoi
我不会称自己为专家,但我认为将用户数据搞得支离破碎以适应数据库是非常罕见的情况; 相反,数据库应该服务于用户。虽然我曾经不得不这样做一次,来存储从日志文件读取的错误消息,其中最长的消息可能包括堆栈跟踪和其他冗长的调试信息,但大多数情况下前200个字符对于用户来说已足够了,如果他们需要查看更多,则可以打开原始文件。 - Joni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接