获取 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.

毫无意义