获取ORA-12899:Oracle中nvarchar2和varchar2的值太大

时间:2015-12-07 19:03:01

标签: oracle11g varchar2 ora-12899

我创建了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.)非英语字符?

感谢。

1 个答案:

答案 0 :(得分:2)

如果你问为什么"实际"错误消息中的值不同,答案是长度语义。

当您声明nvarchar2(n)时,您隐式使用字符长度语义。 nvarchar2(n)nls_nchar_characterset中的n个字符分配空间,而不管所需的字节数。您尝试在nvarchar2(10)中插入一个14个字符的字符串,这样您就可以得到14作为错误的实际长度。

当您声明varchar2(n)时,您将为n个字节或n个存储字符分配空间,具体取决于您的会话nls_length_semantics。默认情况下,这是byte,因此您可以为10个字节分配空间。您的一些字符在nls_characterset中需要超过1个字节的存储空间,因此您的14个字符的字符串将需要21个字节的存储空间。这就是为什么你得到21作为错误中的实际长度的原因。我希望如果您使用字符长度语义将列声明为varchar2(n char),则报告的实际大小将为14。

如果您的数据库字符集支持Unicode,则很少有理由使用nvarchar2。当您的数据库和国家字符集都是UTF-8时,使用nvarchar2毫无意义。