sql >> Base de Datos >  >> RDS >> Oracle

CHAR semántica y ORA-01461

Probablemente esto no sea algo que pueda solucionar a menos que quiera usar un CLOB en lugar de un VARCHAR2.

En Oracle, cuando declara una columna, el valor predeterminado es usar semántica de longitud de byte. Entonces, un VARCHAR2 (100), por ejemplo, asigna 100 bytes de almacenamiento. Si utiliza un conjunto de caracteres de un solo byte como ISO 8859-1, cada carácter requiere 1 byte de almacenamiento, por lo que también asigna espacio para 100 caracteres. Pero si está utilizando un conjunto de caracteres de varios bytes como UFT-8, cada carácter puede requerir entre 1 y 4 bytes de almacenamiento. Dependiendo de los datos, por lo tanto, un VARCHAR2(100) solo puede almacenar 25 caracteres de datos (los caracteres ingleses generalmente requieren 1 byte, los caracteres europeos generalmente requieren 2 bytes y los caracteres asiáticos generalmente requieren 3 bytes).

Puede decirle a Oracle que use la semántica de longitud de caracteres, que normalmente es lo que sugeriría al pasar de una base de datos ISO-8859-1 a una base de datos UTF-8. Si declara una columna VARCHAR2 (100 CHAR), Oracle asignará espacio para 100 caracteres, independientemente de si termina siendo 100 bytes o 400 bytes. También puede establecer el parámetro NLS_LENGTH_SEMANTICS en CHAR para cambiar el valor predeterminado (para el nuevo DDL) de modo que un VARCHAR2(100) asigne 100 caracteres de almacenamiento en lugar de 100 bytes.

Sin embargo, desafortunadamente para usted, el límite en el tamaño de un Oracle VARCHAR2 (en el contexto del motor SQL en lugar del motor PL/SQL) es de 4000 bytes. Entonces, incluso si declara una columna VARCHAR2 (4000 CHAR), todavía estará limitado a insertar 4000 bytes de datos que pueden tener tan solo 1000 caracteres. Por ejemplo, en una base de datos que usa el juego de caracteres AL32UTF8, puedo declarar una columna VARCHAR2 (4000 CARACTERES) pero insertar un carácter que requiere 2 bytes de almacenamiento muestra que realmente no puedo insertar 4000 caracteres de datos

SQL> create table foo (
  2    col1 varchar2(4000 char)
  3  );

Table created.

SQL> insert into foo values( rpad( 'abcde', 4000, unistr('\00f6') ) );

1 row created.

SQL> ed
Wrote file afiedt.buf

  1* insert into foo values( rpad( 'abcde', 6000, unistr('\00f6') ) )
SQL> /

1 row created.

SQL> select length(col1), lengthb(col1)
  2    from foo;

LENGTH(COL1) LENGTHB(COL1)
------------ -------------
        2003          4000
        2003          4000

Si necesita almacenar 4000 caracteres de datos UTF-8, necesitaría un tipo de datos que pudiera manejar 16000 bytes, lo que requeriría pasar a un CLOB.