gpt4 book ai didi

java - Java String.substring() 和 Oracle 11g 列 VARCHAR2 大小之间的字符串长度定义不一致

转载 作者:搜寻专家 更新时间:2023-11-01 01:06:01 27 4
gpt4 key购买 nike

我用这样的表设置我的数据库:

CREATE TABLE t_audit_log
(
description VARCHAR2 (2500)
);

在使用它的 Java 应用程序中,我使用 Hibernate 将数据类映射到它上面并确保我不会生成 SQLExceptions,我将这个截断算法放在属性 getter 中:

private static final int MAX_STRING_LEN_2500 = 2499;

public void setDescription(final String newDescription) {
if (newDescription != null
&& newDescription.length() > MAX_STRING_LEN_2500) {
description = newDescription.substring(0, MAX_STRING_LEN_2500);
} else {
description = newDescription;
}
}

对于数以千计的审计日志条目,这工作正常 - 直到今天。我在日志中发现了这一点:

Nov 09, 2015 7:54:40 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 12899, SQLState: 72000
Nov 09, 2015 7:54:40 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: ORA-12899: value too large for column "BLABLA"."T_AUDIT_LOG"."DESCRIPTION"
(actual: 2501, maximum: 2500)

为什么 substring() 在值中留下了一个额外的字符?

最佳答案

怀疑您的数据库设置设置为使用"byte semantics"对于长度操作(这是 NLS_LENGTH_SEMANTICS 的默认设置),在这种情况下,您是说您希望字段在编码时的长度最多为 2500 个字节,而不是 2500 个字符。假设您的数据库使用 UTF-8 对字符串进行编码 - 如果您的字符串有 2498 个 ASCII 字符和 1 个 U+20A0 字符(欧元符号),则总共有 2501 个字节,但只有 2499 个字符。

Java length()substring() 操作将根据 UTF-16 代码单元进行操作 - 这可能完全 与“字符语义”保持一致。 (您不太可能尝试将字符存储在基本多语言平面之外,在基本多语言平面中,单个字符需要两个 UTF-16 代码单元,但这是可能的。)

您确实需要弄清楚您希望字段长度实际上用什么表示 - 然后您可以弄清楚是否要更改您在 Java 中执行截断的方式。

关于java - Java String.substring() 和 Oracle 11g 列 VARCHAR2 大小之间的字符串长度定义不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33613322/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com