Что это значит, когда размер VARCHAR2 в Oracle объявлен как 1 байт?

Я знаю, что могу объявить varchar2, используя количество символов, которое он должен содержать.

Однако в Oracle базе данных, над которой я работаю, я обнаружил, что поле (с именем PDF) определяется следующим образом:

VARCHAR2(1 BYTE)

Что это значит? Сколько символов он может содержать?

Другой, связанный с этим вопрос: в чем разница между VARCHAR и VARCHAR2?


person AndreaNobili    schedule 16.06.2015    source источник
comment
возможный дубликат В чем разница между varchar и varchar2?   -  person Ian Carpenter    schedule 16.06.2015
comment
и возможный дубликат stackoverflow.com/questions/81448/   -  person Ian Carpenter    schedule 16.06.2015
comment
см. также параметр NLS_LENGTH_SEMANTICS: asktom. oracle.com/pls/asktom/   -  person ibre5041    schedule 16.06.2015
comment
Думаю, в вашем случае разница между BYTE и CHAR бессмысленна. Oracle не поддерживает логический тип, поэтому обычно реализуется как CHAR(1). Имея строку переменной длины с макс. длина одного байта не имеет смысла.   -  person ibre5041    schedule 16.06.2015


Ответы (4)


Вы можете объявить столбцы / переменные как varchar2 (n CHAR) и varchar2 (n byte).

n CHAR означает, что переменная будет содержать n символов. В многобайтовых наборах символов вы не всегда знаете, сколько байтов вы хотите сохранить, но вы хотите гарантировать хранение определенного количества символов.

n байтов означает просто количество байтов, которое вы хотите сохранить.

varchar устарел. Не используйте это. В чем разница между varchar и varchar2?

person Rene    schedule 16.06.2015
comment
Наверное, исторический. Сначала символ был байтом. Затем были введены многобайтовые символы, и значение длины внезапно открылось для множества интерпретаций. - person Rene; 13.12.2017
comment
Мне кажется странным, что при объявлении типа данных для хранения текстовых символов вам предоставляется выбор указать количество байтов для хранения. Базовый размер хранилища должен прозрачно обрабатываться механизмом db на основе соответствующей текстовой кодировки. Если, например, мне как пользователю нужно сохранить X текстовых символов с использованием кодировки UTF-8, движку БД необходимо внутренне выяснить, сколько памяти для этого требуется. Позволить пользователю установить дверь для неприятностей. - person cvacca; 13.12.2017
comment
Об этом заботится параметр базы данных NLS_LENGTH_SEMANTICS. - person Rene; 13.12.2017

VARCHAR тип данных является синонимом типа данных VARCHAR2 . Чтобы избежать возможных изменений в поведении, всегда используйте тип данных VARCHAR2 для хранения символьных строк переменной длины.

Если ваша база данных работает с однобайтовым набором символов (например, US7ASCII, WE8MSWIN1252 или WE8ISO8859P1), не имеет значения, используете ли вы VARCHAR2(x BYTE) или VARCHAR2(x CHAR).

Это имеет значение только тогда, когда ваша БД работает с многобайтовым набором символов (например, AL32UTF8 или AL16UTF16). Вы можете просто увидеть это в этом примере:

CREATE TABLE my_table (
    VARCHAR2_byte VARCHAR2(1 BYTE), 
    VARCHAR2_char VARCHAR2(1 CHAR)
);

INSERT INTO my_table (VARCHAR2_char) VALUES ('€');
1 row created.

INSERT INTO my_table (VARCHAR2_char) VALUES ('ü');
1 row created.

INSERT INTO my_table (VARCHAR2_byte) VALUES ('€');
INSERT INTO my_table (VARCHAR2_byte) VALUES ('€')
Error at line 10
ORA-12899: value too large for column "MY_TABLE"."VARCHAR2_BYTE" (actual: 3, maximum: 1)

INSERT INTO my_table (VARCHAR2_byte) VALUES ('ü')
Error at line 11
ORA-12899: value too large for column "MY_TABLE"."VARCHAR2_BYTE" (actual: 2, maximum: 1)

VARCHAR2(1 CHAR) означает, что вы можете сохранить до 1 символа, независимо от того, сколько в нем байтов. В случае Unicode один символ может занимать до 4 байтов.

VARCHAR2(1 BYTE) означает, что вы можете сохранить символ, занимающий макс. 1 байт.

Если вы не укажете BYTE или CHAR, тогда значение по умолчанию будет взято из NLS_LENGTH_SEMANTICS параметра сеанса.

Если у вас нет Oracle 12c, где вы можете установить MAX_STRING_SIZE=EXTENDED, ограничение составляет VARCHAR2(4000 CHAR)

Однако VARCHAR2(4000 CHAR) не означает, что вы гарантированно храните до 4000 символов. Предел по-прежнему составляет 4000 байтов, поэтому в худшем случае вы можете сохранить в таком поле не более 1000 символов.

См. Этот пример ( в UTF-8 занимает 3 байта):

CREATE TABLE my_table2(VARCHAR2_char VARCHAR2(4000 CHAR));

BEGIN
    INSERT INTO my_table2 VALUES ('€€€€€€€€€€');
    FOR i IN 1..7 LOOP
        UPDATE my_table2 SET VARCHAR2_char = VARCHAR2_char ||VARCHAR2_char;
    END LOOP;
END;
/

SELECT LENGTHB(VARCHAR2_char) , LENGTHC(VARCHAR2_char) FROM my_table2;

LENGTHB(VARCHAR2_CHAR) LENGTHC(VARCHAR2_CHAR)
---------------------- ----------------------
                  3840                   1280
1 row selected.


UPDATE my_table2 SET VARCHAR2_char = VARCHAR2_char ||VARCHAR2_char;

UPDATE my_table2 SET VARCHAR2_char = VARCHAR2_char ||VARCHAR2_char
Error at line 1
ORA-01489: result of string concatenation is too long

См. Также Примеры и ограничения использования семантики BYTE и CHAR (NLS_LENGTH_SEMANTICS) (ID документа 144808.1)

person Wernfried Domscheit    schedule 16.06.2015

Чтобы ответить на ваш первый вопрос:
Да, это означает, что 1 байт выделяется для 1 символа. Взгляните на этот пример

SQL> conn / as sysdba
Connected.
SQL> create table test (id number(10), v_char varchar2(10));

Table created.

SQL> insert into test values(11111111111,'darshan');
insert into test values(11111111111,'darshan')
*
ERROR at line 1:
ORA-01438: value larger than specified precision allows for this column


SQL> insert into test values(11111,'darshandarsh');
insert into test values(11111,'darshandarsh')
*
ERROR at line 1:
ORA-12899: value too large for column "SYS"."TEST"."V_CHAR" (actual: 12,
maximum: 10)


SQL> insert into test values(111,'Darshan');

1 row created.

SQL> 

И чтобы ответить на ваш следующий: разница между varchar2 и varchar:

  1. VARCHAR может хранить до 2000 bytes символов, а VARCHAR2 может хранить до 4000 bytes символов.
  2. Если мы объявим тип данных как VARCHAR, тогда он будет занимать место для NULL values. В случае типа данных VARCHAR2 он будет not занимать любое пространство.
person Darshan Lila    schedule 16.06.2015

это означает, что для каждого символа будет выделен ТОЛЬКО один байт, поэтому, если вы используете многобайтовые кодировки, ваш 1 символ не подходит

если вы знаете, что у вас должно быть как минимум место для 1 символа, не используйте синтаксис BYTE, если вы точно не знаете, сколько места вам понадобится для хранения этого байта

в случае сомнений используйте VARCHAR2 (1 CHAR)

то же самое, что и здесь Разница между BYTE и CHAR в типах данных столбца

Кроме того, в 12c максимальное значение для varchar2 теперь составляет 32 КБ, а не 4000. Если вам нужно больше, используйте CLOB.

в Oracle не используйте VARCHAR

person thatjeffsmith    schedule 16.06.2015
comment
Кроме того, в 12c максимальное значение для varchar2 теперь составляет 32 КБ, а не 4000. Да, но его нужно явно настроить на уровне SYSTEM, сделав MAX_STRING_SIZE на EXTENDED, иначе по умолчанию это будет 4000. - person Lalit Kumar B; 16.06.2015
comment
Спасибо за помощь + Лалит - person thatjeffsmith; 16.06.2015
comment
Он работает также для многобайтовых кодировок, если символ использует только один байт, например до CHR(127) в UTF-8 - person Wernfried Domscheit; 16.06.2015