В чем разница между varchar и varchar2 в Oracle?

Ответы:

337

На данный момент они являются синонимами.

VARCHARзарезервировано Oracleдля поддержки различий между NULLпустой строкой в ​​будущем, как это ANSIпредусмотрено стандартом.

VARCHAR2не различает NULLпустую строку и никогда не будет.

Если вы полагаетесь на пустую строку и NULLто же самое, вы должны использовать VARCHAR2.

Quassnoi
источник
40
Не слышал этого обоснования раньше, это полезно. Спасибо. Для справки, все еще совершенно нелепо, что основным типом персонажа в Oracle является «varchar2». Разве это не поражает кого-то еще как ужасный клудж? Похоже, я бы решил какую-то проблему на первой неделе обучения программированию.
Ян Варли
7
@Ian: основной тип, VARCHAR2потому что в настоящее время нет типа, который ведет себя как VARCHARследует. На самом деле, вы не должны использовать VARCHARвообще, пока это не реализовано должным образом.
Кассной
11
Спасибо, @Quassnoi. Так что я думаю, что глупо то, что у Oracle нет правильного VARCHAR, как у любой другой базы данных, тогда? Здесь происходит что-то глупое, я в этом уверен ... :)
Ian Varley
11
@Ian: когда разрабатывался Oracle, стандартов не было. К моменту появления стандартов на нем уже было бремя устаревших приложений. Мы все знаем, как это происходит.
Quassnoi
5
К сожалению, на самом деле @UnKnown написал неправильный комментарий, на который я отвечал . Тот факт , что where x is NULLвозвращает различные результаты where x = ''вовсе не означает , что NULLи ''в любом случае различны. Различное поведение связано с =оператором.
Дэн Ленски
38

В настоящее время VARCHAR ведет себя точно так же, как VARCHAR2. Однако тип VARCHARне должен использоваться, поскольку он зарезервирован для использования в будущем.

Взято из: Разница между CHAR, VARCHAR, VARCHAR2

Брайан
источник
@PhilipRego VARCHARне должен использоваться. Я отредактировал его
Bugybunny
29

Взято из последней стабильной рабочей версии Oracle 12.2: Типы данных

Основное различие заключается в том , что VARCHAR2это внутренний тип данных и VARCHARпредставляет собой внешний тип данных . Итак, нам нужно понять разницу между внутренним и внешним типом данных ...

Внутри базы данных значения хранятся в виде столбцов в таблицах. Внутренне Oracle представляет данные в определенных форматах, известных как внутренние типы данных .

В общем, приложения OCI (Oracle Call Interface) не работают с внутренними представлениями типов данных, но с типами данных на языке хоста, которые предопределены языком, на котором они написаны. Когда данные передаются между клиентским приложением OCI и таблицей базы данных, библиотеки OCI преобразуют данные между внутренними типами данных и внешними типами данных.

Внешние типы обеспечивают программисту удобство, позволяя работать с типами основного языка вместо проприетарных форматов данных. OCI может выполнять широкий спектр преобразований типов данных при передаче данных между базой данных Oracle и приложением OCI. Существует больше внешних типов данных OCI, чем внутренних типов данных Oracle.

Тип VARCHAR2данных - это строка символов переменной длины с максимальной длиной 4000 байтов. Если параметр init.ora max_string_size является значением по умолчанию, максимальная длина a VARCHAR2может быть 4000 байтов. Если параметр init.ora max_string_size = extended, максимальная длина a VARCHAR2может составлять 32767 байт.

Тип VARCHARданных хранит строки символов различной длины. Первые 2 байта содержат длину строки символов, а остальные байты содержат строку. Указанная длина строки в привязке или вызове define должна включать два байта длины, поэтому наибольшая VARCHARстрока, которую можно получить или отправить, имеет длину 65533 байта, а не 65535.

Быстрый тест в базе данных 12.2 предполагает , что в качестве внутреннего типа данных , Oracle все еще лечит VARCHARкак псевдотип для VARCHAR2. Это НЕ SYNONYMфактический тип объекта в Oracle.

SQL> select substr(banner,1,80) from v$version where rownum=1;
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production    

SQL> create table test (my_char varchar(20));
Table created.

SQL> desc test
Name                 Null?    Type
MY_CHAR                       VARCHAR2(20)

Существуют также некоторые значения параметров VARCHARпрекомпилятора ProC / C ++. Для программистов, которые заинтересованы, ссылка на: Pro * C / C ++ Руководство программиста

Дрема
источник
1
так значит ли это, что VARCHARвсе еще лечит '' == null?
2
Да. Обсуждение внутренних и внешних типов выше взято из ссылки OCI. 12.2 Язык SQL Reference все еще несет то же самое «не использовать» заявление он всегда имел для VARCHAR.
Уильям Робертсон
Вот почему я обсуждал различия OCI, иначе они в значительной степени зарезервированы для будущего использования или, как говорится, «переменной длины», которая может указывать на наборы символов, такие как многобайтовый UTF8 ...
sandman
1
Вы показали, что значения, объявленные как VARCHAR, хранятся в базе данных как VARCHAR2, однако максимальная длина VARCHAR (65533 байта) больше максимальной длины VARCHAR2 (32767 байтов). Как база данных справляется с этим?
Петр Доброгост
IIRC, давным-давно (может быть Oracle 6?) Был тип VARCHAR, который плохо себя вел по отношению к пробелам - или это было усечение пробелов? AAR, VARCHAR2 был ответом. Оракул говорил, что они вернут VARCHAR, но, я уверен, будет скрежет зубов, когда пустая строка НЕ ​​ПУСТО.
JMD
2

После некоторых экспериментов (см. Ниже) я могу подтвердить, что по состоянию на сентябрь 2017 года ничего не изменилось в отношении функциональности, описанной в принятом ответе : -

  1. Демонстрация Rextester для Oracle 11g: пустые строки вставляются какNULLs для обоихVARCHAR иVARCHAR2.
  2. Демонстрация LiveSQL для Oracle 12c: те же результаты.

Историческая причина этих двух ключевых слов хорошо объясняется в ответе на другой вопрос .

Стив Чемберс
источник
0
  1. VARCHAR может хранить до 2000 байтов символов, тогда как VARCHAR2 может хранить до 4000 байтов символов.

  2. Если мы объявим тип данных как VARCHAR, он будет занимать пространство для значений NULL. В случае типа данных VARCHAR2 он не будет занимать место для значений NULL. например,

    name varchar(10)

зарезервирует 6 байтов памяти, даже если имя «Ravi__», тогда как

name varchar2(10) 

зарезервирует место в соответствии с длиной входной строки. например, 4 байта памяти для 'Ravi__'.

Здесь _ представляет NULL.

ПРИМЕЧАНИЕ: varchar зарезервирует пространство для нулевых значений, а varchar2 не зарезервирует пространство для нулевых значений.

Палак джайн
источник
2
Я думаю, что этот ответ сбивает VARCHARс толку CHAR.
Джон Хеллер
0

В настоящее время они одинаковы. но ранее

  1. Я где-то читал в сети,

VARCHARзарезервировано Oracle для поддержки различий между NULLпустой строкой и в будущем, как предписывает стандарт ANSI.

VARCHAR2не различает NULLпустую строку и никогда не будет.

  1. Также,

Emp_name varchar(10)- если вы введете значение менее 10 цифр, оставшееся пространство не может быть удалено. он использовал всего 10 пробелов.

Emp_name varchar2(10) - если вы введете значение менее 10 цифр, оставшееся пространство будет автоматически удалено

Рамкумар П
источник
Я недавно наткнулся на этот пост, обратите внимание, что это неправильно. Выполните следующее, и оба поля будут состоять из 3 символов:create table deleteme_table(v varchar(10), v2 varchar2(10)); insert into deleteme_table (v, v2) values ('abc','abc'); select v, length(v), v2, length(v2) from deleteme_table;
Брайан Лич
-1

VARCHAR является синонимом VARCHAR2. Однако вы не должны использовать VARCHAR, потому что Oracle может изменить свою семантику в будущем.

Premraj
источник