Oracle
 sql >> база данни >  >> RDS >> Oracle

CHAR семантика и ORA-01461

Това вероятно не е нещо, което можете да заобиколите, освен ако не искате да използвате CLOB вместо VARCHAR2.

В Oracle, когато декларирате колона, по подразбиране се използва семантика с дължина на байта. Така VARCHAR2(100), например, разпределя 100 байта за съхранение. Ако използвате еднобайтов набор от знаци като ISO 8859-1, всеки знак изисква 1 байт място за съхранение, така че това също отделя място за 100 знака. Но ако използвате многобайтов набор от знаци като UFT-8, всеки знак може да изисква между 1 и 4 байта място за съхранение. Следователно в зависимост от данните VARCHAR2(100) може да съхрани само 25 знака данни (английските знаци обикновено изискват 1 байт, европейските знаци обикновено изискват 2 байта, а азиатските знаци обикновено изискват 3 байта).

Можете да кажете на Oracle да използва семантика на дължината на знаците, което обикновено е това, което бих предложил при преминаване от база данни ISO-8859-1 към база данни UTF-8. Ако декларирате колона VARCHAR2(100 CHAR), Oracle ще разпредели място за 100 знака, независимо дали това ще бъде 100 байта или 400 байта. Можете също да зададете параметъра NLS_LENGTH_SEMANTICS на CHAR, за да промените стойността по подразбиране (за нов DDL), така че VARCHAR2(100) да разпределя 100 знака за съхранение вместо 100 байта.

За ваше съжаление обаче ограничението за размера на Oracle VARCHAR2 (в контекста на SQL машината, а не на PL/SQL машината) е 4000 байта. Така че дори ако декларирате колона VARCHAR2(4000 CHAR), пак ще бъдете ограничени до реално вмъкване на 4000 байта данни, които може да са само 1000 знака. Например, в база данни, използваща набора от знаци AL32UTF8, мога да декларирам колона VARCHAR2(4000 CHAR), но вмъкването на знак, който изисква 2 байта място за съхранение, показва, че наистина не мога да вмъкна 4000 знака данни

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

Ако трябва да съхранявате 4000 знака UTF-8 данни, ще ви трябва тип данни, който може да обработва 16000 байта, което ще наложи преместване в CLOB.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle:Възможно ли е да се създаде роля в тригер?

  2. Как да убия всички активни и неактивни сесии на оракул за потребителя

  3. разпределение на sql плащания

  4. Кой е най-добрият начин за свързване между android и oracle база данни?

  5. Алтернатива на sql сървър TOP в oracle