Oracle
 sql >> Datenbank >  >> RDS >> Oracle

CHAR-Semantik und ORA-01461

Dies ist wahrscheinlich nicht etwas, das Sie umgehen können, es sei denn, Sie möchten ein CLOB anstelle eines VARCHAR2 verwenden.

Wenn Sie in Oracle eine Spalte deklarieren, wird standardmäßig die Bytelängensemantik verwendet. Ein VARCHAR2(100) weist also beispielsweise 100 Byte Speicherplatz zu. Wenn Sie einen Single-Byte-Zeichensatz wie ISO 8859-1 verwenden, benötigt jedes Zeichen 1 Byte Speicherplatz, sodass auch Platz für 100 Zeichen zugewiesen wird. Wenn Sie jedoch einen Multi-Byte-Zeichensatz wie UFT-8 verwenden, kann jedes Zeichen zwischen 1 und 4 Byte Speicherplatz benötigen. Abhängig von den Daten kann ein VARCHAR2(100) daher möglicherweise nur 25 Datenzeichen speichern (englische Zeichen erfordern im Allgemeinen 1 Byte, europäische Zeichen erfordern im Allgemeinen 2 Bytes und asiatische Zeichen erfordern im Allgemeinen 3 Bytes).

Sie können Oracle anweisen, die Zeichenlängensemantik zu verwenden, was ich normalerweise vorschlagen würde, wenn Sie von einer ISO-8859-1-Datenbank zu einer UTF-8-Datenbank wechseln. Wenn Sie eine Spalte VARCHAR2(100 CHAR) deklarieren, weist Oracle Platz für 100 Zeichen zu, unabhängig davon, ob dies letztendlich 100 Bytes oder 400 Bytes sind. Sie können den Parameter NLS_LENGTH_SEMANTICS auch auf CHAR setzen, um den Standardwert (für neue DDL) zu ändern, sodass ein VARCHAR2(100) 100 Zeichen Speicherplatz statt 100 Byte zuweist.

Unglücklicherweise liegt die Größenbeschränkung einer Oracle-VARCHAR2-Datei (im Kontext der SQL-Engine und nicht der PL/SQL-Engine) bei 4000 Byte. Selbst wenn Sie also eine Spalte VARCHAR2(4000 CHAR) deklarieren, sind Sie immer noch darauf beschränkt, tatsächlich 4000 Byte Daten einzufügen, die nur 1000 Zeichen umfassen können. Beispielsweise kann ich in einer Datenbank mit dem Zeichensatz AL32UTF8 eine Spalte VARCHAR2(4000 CHAR) deklarieren, aber das Einfügen eines Zeichens, das 2 Byte Speicherplatz erfordert, zeigt, dass ich nicht wirklich 4000 Zeichen Daten einfügen kann

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

Wenn Sie 4000 Zeichen UTF-8-Daten speichern müssen, benötigen Sie einen Datentyp, der 16000 Bytes verarbeiten kann, was die Umstellung auf ein CLOB erforderlich machen würde.