0

我创建了 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版本。

另外,是否建议NVARCHAR2(NCHAR etc.)在 oracle 中用于非英文字符?

谢谢。

4

1 回答 1

2

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

当你声明一个nvarchar2(n)时,你隐含地使用了字符长度语义。无论需要多少字节,An都会nvarchar2(n)为 in 中的 n 个字符分配空间。nls_nchar_characterset您正在尝试将 14 个字符的字符串插入到 annvarchar2(10)中,因此您得到 14 作为错误的实际长度。

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

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

于 2015-12-07T19:11:30.103 回答