需要在Oracle中使用NLS_LENGTH_SEMANTICS进行理解

时间:2017-02-10 04:30:21

标签: oracle character-encoding

我使用以下命令在Oracle 12c中创建数据库和表

CREATE TABLE t
(a VARCHAR2(14 CHAR))

如果我试图放下:MARIE-THÉRÈSE

INSERT INTO t (a) values ('MARIE-THÉRÈSE');

ERROR at line 1:
ORA-12899: value too large for column "T"."A" (actual: 15, maximum:
14)

一些信息:

    SQL> SELECT LENGTH('MARIE-THÉRÈSE') "Length in characters" FROM DUAL;

Length in characters
--------------------
                  15
SQL> SELECT LENGTHB ('MARIE-THÉRÈSE') "Length in bytes" FROM DUAL;

Length in bytes
---------------
             23
SELECT *
   FROM nls_database_parameters
   WHERE parameter = 'NLS_CHARACTERSET';

PARAMETER                      VALUE
------------------------------ --------------------
NLS_CHARACTERSET               AL32UTF8

SELECT value FROM NLS_DATABASE_PARAMETER
WHERE parameter='NLS_LENGTH_SEMANTICS';

VALUE
-----------------------------------
BYTE

如何在不修改此列但仅修改oracle参数的情况下将'MARIE-THÉRÈSE'放在此列VARCHAR2(14 CHAR)中?

2 个答案:

答案 0 :(得分:0)

LENGTH SEMANTICS参数定义默认情况下使用的内容,如果未在DDL中指定它。例如,如果你说

CREATE TABLE T
( a VARCHAR2(14) )

然后LENGTH SEMANTICS参数将确定A列是14 BYTES还是14 CHARACTERS。

因此,在您的示例中,您有一个15个字符的字符串,因此无论长度语义如何,您都无法将其插入到14个字符的列中;您需要修改列定义。

ALTER TABLE T
MODIFY a VARCHAR2(15 CHAR)

答案 1 :(得分:0)

解决方案是:

VARCHAR2(20) : Uses the default length semantics defined by the NLS_LENGTH_SEMANTICS parameter which defaults to BYTE.
VARCHAR2(20 BYTE) : Allows only the specified number of bytes to be stored in the column, regardless of how many characters this represents.
VARCHAR2(20 CHAR) : Allows the specified number of characters to be stored in the column regardless of the number of bytes this equates to.

SQL> CREATE TABLE tab2 (
  2    id           NUMBER(10),
  3    description  VARCHAR2(20 CHAR)
  4  );
Table created.

SQL> DESC tab2
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- -----------------
 ID                                                             NUMBER(10)
 DESCRIPTION                                                    VARCHAR2(20 CHAR)

可以使用NLS_LENGTH_SEMANTICS参数更改数据库或会话的默认字符语义。

ALTER SYSTEM SET NLS_LENGTH_SEMANTICS=CHAR;
ALTER SYSTEM SET NLS_LENGTH_SEMANTICS=BYTE;

ALTER SESSION SET NLS_LENGTH_SEMANTICS=CHAR;
ALTER SESSION SET NLS_LENGTH_SEMANTICS=BYTE;

如果我们将会话长度语义更改为字符并描述表,我们可以看到更改已经通过列定义的显示方式生效。

SQL> ALTER SESSION SET NLS_LENGTH_SEMANTICS=CHAR;

Session altered.

SQL> desc tab1
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- -----------------
 ID                                                             NUMBER(10)
 DESCRIPTION                                                    VARCHAR2(20 BYTE)

SQL> DESC tab2
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- -----------------
 ID                                                             NUMBER(10)
 DESCRIPTION                                                    VARCHAR2(20)

SQL>

无论列定义和字符集如何,INSTR,LENGTH和SUBSTR函数始终处理字符。当您特别需要以字节为单位处理时,Oracle提供了INSTRB,LENGTHB和SUBSTRB函数。