获取 ORA-12899:Oracle 中 nvarchar2 和 varchar2 的值太大错误
Getting ORA-12899: Value too large error for nvarchar2 and varchar2 in Oracle
我创建了 2 个表并插入数据如下---
SQL> create table t (aa nvarchar2(10));
Table created.
SQL> create table t1 (aa varchar2(10));
Table created.
现在,插入一些法语字符,如下所示--
SQL> insert into t values ('Éé, Eè, Eê, Eë');
insert into t values ('Éé, Eè, Eê, Eë')
*
ERROR at line 1:
ORA-12899: value too large for column "CDUREFDB"."T"."AA" (actual: 14, maximum:
10)
SQL> insert into t1 values ('Éé, Eè, Eê, Eë');
insert into t1 values ('Éé, Eè, Eê, Eë')
*
ERROR at line 1:
ORA-12899: value too large for column "CDUREFDB"."T1"."AA" (actual: 21,
maximum: 10)
问题是为什么两个插入的错误消息不同。
以下为 NLS 参数详情:
SQL> SELECT *
2 FROM v$nls_parameters
3 WHERE parameter LIKE '%CHARACTERSET'
4 ;
PARAMETER
----------------------------------------------------------------
VALUE
----------------------------------------------------------------
NLS_CHARACTERSET
AL32UTF8
NLS_NCHAR_CHARACTERSET
UTF8
我用的是Oracle 11g
版本。
另外,oracle中非英文字符是否推荐使用NVARCHAR2(NCHAR etc.)
?
谢谢。
如果您问为什么错误消息中的 "actual" 值不同,答案是长度语义。
当您声明 nvarchar2(n)
时,您是在隐式使用字符长度语义。 nvarchar2(n)
为 nls_nchar_characterset
中的 n 个字符分配 space,而不考虑需要的字节数。您试图将 14 个字符的字符串插入到 nvarchar2(10)
中,因此您得到 14 作为错误的实际长度。
当您声明 varchar2(n)
时,您将分配 space 用于 n 个字节或 n 个字符的存储,具体取决于您的会话 nls_length_semantics
。默认情况下,即 byte
,因此您将为 10 个字节分配 space。您的某些字符在 nls_characterset
中需要超过 1 个字节的存储空间,因此您的 14 个字符的字符串将需要 21 个字节的存储空间。这就是错误中实际长度为 21 的原因。我希望如果您使用字符长度语义将该列声明为 varchar2(n char)
,则报告的实际大小将为 14.
如果您的数据库字符集支持 Unicode,则很少有理由使用 nvarchar2
。当您的数据库和国家字符集都是 UTF-8 时,使用 nvarchar2
.
毫无意义
我创建了 2 个表并插入数据如下---
SQL> create table t (aa nvarchar2(10));
Table created.
SQL> create table t1 (aa varchar2(10));
Table created.
现在,插入一些法语字符,如下所示--
SQL> insert into t values ('Éé, Eè, Eê, Eë');
insert into t values ('Éé, Eè, Eê, Eë')
*
ERROR at line 1:
ORA-12899: value too large for column "CDUREFDB"."T"."AA" (actual: 14, maximum:
10)
SQL> insert into t1 values ('Éé, Eè, Eê, Eë');
insert into t1 values ('Éé, Eè, Eê, Eë')
*
ERROR at line 1:
ORA-12899: value too large for column "CDUREFDB"."T1"."AA" (actual: 21,
maximum: 10)
问题是为什么两个插入的错误消息不同。
以下为 NLS 参数详情:
SQL> SELECT *
2 FROM v$nls_parameters
3 WHERE parameter LIKE '%CHARACTERSET'
4 ;
PARAMETER
----------------------------------------------------------------
VALUE
----------------------------------------------------------------
NLS_CHARACTERSET
AL32UTF8
NLS_NCHAR_CHARACTERSET
UTF8
我用的是Oracle 11g
版本。
另外,oracle中非英文字符是否推荐使用NVARCHAR2(NCHAR etc.)
?
谢谢。
如果您问为什么错误消息中的 "actual" 值不同,答案是长度语义。
当您声明 nvarchar2(n)
时,您是在隐式使用字符长度语义。 nvarchar2(n)
为 nls_nchar_characterset
中的 n 个字符分配 space,而不考虑需要的字节数。您试图将 14 个字符的字符串插入到 nvarchar2(10)
中,因此您得到 14 作为错误的实际长度。
当您声明 varchar2(n)
时,您将分配 space 用于 n 个字节或 n 个字符的存储,具体取决于您的会话 nls_length_semantics
。默认情况下,即 byte
,因此您将为 10 个字节分配 space。您的某些字符在 nls_characterset
中需要超过 1 个字节的存储空间,因此您的 14 个字符的字符串将需要 21 个字节的存储空间。这就是错误中实际长度为 21 的原因。我希望如果您使用字符长度语义将该列声明为 varchar2(n char)
,则报告的实际大小将为 14.
如果您的数据库字符集支持 Unicode,则很少有理由使用 nvarchar2
。当您的数据库和国家字符集都是 UTF-8 时,使用 nvarchar2
.