字符串的真实长度,如Oracle所见

mar*_*rea 12 java string oracle

所以我试图将数据保存到Oracle数据库.我有一个字符串:

Väste
Run Code Online (Sandbox Code Playgroud)

(某个地方的州名).

当我对它执行.length()时,我得到5,但是当我将它保存到数据库时,我得到:

ORA-12899: value too large for column "dude"."POST_ADR"."STATE_CD" (actual: 6, maximum: 5)
Run Code Online (Sandbox Code Playgroud)

那么如何获得"oracle"长度呢?

Den*_*ret 9

Oracle为您提供字节长度,"ä"UTF-8为2字节(c3 a4).

更多信息在这里.

您可以使用以字节为单位获取长度 str.getBytes("UTF-8").length


Jus*_*ave 9

正如其他人所示,您可以使用Oracle数据库的字符集将Java字符串转换为字节数组,然后从中获取字节长度.但是,这依赖于知道数据库的字符集是什么 - 不同的数据库将具有不同的字符集,这将导致不同字符集中相同字符串的不同字节长度.

假设您的数据库使用的是像UTF-8(NLS_CHARACTERSETAL32UTF8)这样的可变宽度字符集,您还可以根据字符长度而不是字节长度在Oracle中声明列.这可以简化您的代码,因为您只需检查字符串的字符长度.它还简化了用户的通信.用户通常很难理解为什么字段有时可以存储5个字符,而有时它会拒绝2个字符的字符串,具体取决于字符串中的字符(UTF-8字符集中的1个字符最多需要3个字节)存储).

默认情况下,声明列时

CREATE TABLE foo (
  col_name VARCHAR2(5)
);
Run Code Online (Sandbox Code Playgroud)

告诉Oracle允许最多5个字节的数据.但是,如果要允许5个字符的数据而不管字节数,则可以使用字符长度语义

CREATE TABLE foo (
  col_name VARCHAR2(5 CHAR)
);
Run Code Online (Sandbox Code Playgroud)

假设您想在运行DDL时为所有表执行此操作,还可以nls_length_semantics在运行DDL之前设置会话级别

ALTER SESSION SET nls_length_semantics = CHAR;

CREATE TABLE foo (
  col_name VARCHAR2(5)
);
Run Code Online (Sandbox Code Playgroud)

创建一个包含一列的表,该列最多允许包含5个字符的数据.


Jer*_*vel 7

因为您正在使用组合字符,所以应该获取基础字节数组,然后获取该长度:

"Väste".getBytes(java.nio.charset.StandardCharsets.UTF_8).length
Run Code Online (Sandbox Code Playgroud)

将打印6.

  • 使用getBytes()时需要指定编码,否则getBytes()将依赖于默认的系统编码. (4认同)