sql >> Database teknologi >  >> RDS >> Oracle

CHAR semantik og ORA-01461

Dette er sandsynligvis ikke noget, du kan omgås, medmindre du vil bruge en CLOB i stedet for en VARCHAR2.

I Oracle, når du erklærer en kolonne, er standarden at bruge byte-længde semantik. Så en VARCHAR2(100), for eksempel, tildeler 100 bytes lagerplads. Hvis du bruger et enkelt-byte tegnsæt som ISO 8859-1, kræver hvert tegn 1 byte lagerplads, så dette tildeler også plads til 100 tegn. Men hvis du bruger et multi-byte tegnsæt som UFT-8, kan hvert tegn kræve mellem 1 og 4 bytes lagerplads. Afhængigt af dataene kan en VARCHAR2(100) derfor muligvis kun gemme 25 tegn data (engelske tegn kræver generelt 1 byte, europæiske tegn kræver generelt 2 byte, og asiatiske tegn kræver generelt 3 bytes).

Du kan bede Oracle om at bruge tegnlængde semantik, hvilket normalt er, hvad jeg vil foreslå, når du flytter fra en ISO-8859-1-database til en UTF-8-database. Hvis du erklærer en kolonne VARCHAR2(100 CHAR), vil Oracle allokere plads til 100 tegn, uanset om det ender med at blive 100 bytes eller 400 bytes. Du kan også indstille NLS_LENGTH_SEMANTICS parameteren til CHAR for at ændre standarden (for ny DDL), så en VARCHAR2(100) tildeler 100 tegn lager i stedet for 100 bytes.

Desværre for dig er grænsen for størrelsen af ​​en Oracle VARCHAR2 (i sammenhæng med SQL-motoren snarere end PL/SQL-motoren) 4000 bytes. Så selvom du erklærer en kolonne VARCHAR2(4000 CHAR), vil du stadig være begrænset til faktisk at indsætte 4000 bytes data, som kan være så få som 1000 tegn. For eksempel, i en database, der bruger AL32UTF8 tegnsættet, kan jeg erklære en kolonne VARCHAR2(4000 CHAR), men indsættelse af et tegn, der kræver 2 bytes lager, viser, at jeg ikke rigtig kan indsætte 4000 tegn data

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

Hvis du har brug for at gemme 4000 tegn UTF-8-data, har du brug for en datatype, der kan håndtere 16000 bytes, hvilket ville nødvendiggøre flytning til en CLOB.




  1. Tilslutning af Oracle til SQL Server via databaselink

  2. ROUND() Eksempler i SQL Server

  3. UPDATE-sætning med flere joinforbindelser i PostgreSQL

  4. Oracle Data Integrator (ODI)