Jaka jest różnica między varchar i varchar2 w Oracle?

Odpowiedzi:

336

Na razie są to synonimy.

VARCHARjest zarezerwowane przez w Oraclecelu obsługi rozróżnienia pomiędzy NULLi pustym łańcuchem w przyszłości, jak ANSInakazuje standard.

VARCHAR2nie rozróżnia NULLciągów od pustych i nigdy nie będzie.

Jeśli polegasz na pustym łańcuchu i NULLbędąc tym samym, powinieneś użyć VARCHAR2.

Quassnoi
źródło
40
Nie słyszałem wcześniej tego uzasadnienia, to jest przydatne. Dzięki. Dla przypomnienia, nadal jest całkowicie śmieszne, że głównym typem postaci w Oracle jest „varchar2”. Czy to nie wydaje się nikomu jak okropna kludge? Wygląda na to, jak rozwiązałbym jakiś problem w pierwszym tygodniu nauki programowania.
Ian Varley
7
@Ian: główny typ jest, VARCHAR2ponieważ obecnie nie ma typu, który zachowuje się tak, jak VARCHARpowinien. W rzeczywistości nie powinieneś używać, VARCHARdopóki nie zostanie poprawnie zaimplementowany.
Quassnoi
11
Dzięki, @Quassnoi. Myślę, że głupią częścią jest to, że Oracle nie ma odpowiedniego VARCHARA, jak każda inna baza danych? Dzieje się tu coś głupiego, jestem tego pewien ... :)
Ian Varley
11
@Ian: podczas opracowywania Oracle nie było żadnych standardów. Do czasu pojawienia się standardów było już mnóstwo starszych aplikacji. Wszyscy wiemy, jak to się dzieje.
Quassnoi
5
Niestety, to właściwie @UnKnown napisał niepoprawny komentarz, na który odpowiadałem . Fakt, że where x is NULLzwracane są różne wyniki where x = '', nie oznacza tego NULLi ''są w jakikolwiek inny sposób. Inne zachowanie jest spowodowane przez =operatora.
Dan Lenski
38

Obecnie VARCHAR zachowuje się dokładnie tak samo jak VARCHAR2. Nie VARCHARnależy jednak używać tego typu, ponieważ jest on zarezerwowany do użycia w przyszłości.

Zaczerpnięte z: Różnica między CHAR, VARCHAR, VARCHAR2

Brian
źródło
@PhilipRego VARCHARnie powinien być używany. Zredagowałem to
bugybunny
29

Zaczerpnięte z najnowszej stabilnej wersji produkcyjnej Oracle 12.2: Typy danych

Główną różnicą jest to, że VARCHAR2jest to wewnętrzny typ danych i VARCHARjest to zewnętrzny typ danych . Musimy więc zrozumieć różnicę między wewnętrznym a zewnętrznym typem danych ...

W bazie danych wartości są przechowywane w kolumnach w tabelach. Wewnętrznie Oracle reprezentuje dane w określonych formatach zwanych wewnętrznymi typami danych .

Zasadniczo aplikacje OCI (Oracle Call Interface) nie działają z wewnętrznymi reprezentacjami danych typu danych, ale z typami danych języka hosta, które są predefiniowane przez język, w którym zostały zapisane. Gdy dane są przesyłane między aplikacją kliencką OCI a tabelą bazy danych, biblioteki OCI konwertują dane między wewnętrznymi typami danych a zewnętrznymi typami danych.

Typy zewnętrzne zapewniają programistom wygodę, umożliwiając pracę z typami języka hosta zamiast zastrzeżonych formatów danych. OCI może wykonywać szeroki zakres konwersji typów danych podczas przesyłania danych między bazą danych Oracle a aplikacją OCI. Istnieje więcej zewnętrznych typów danych OCI niż wewnętrznych typów danych Oracle.

Typ VARCHAR2danych to ciąg znaków o zmiennej długości i maksymalnej długości 4000 bajtów. Jeśli parametr init.ora max_string_size jest domyślny, maksymalna długość a VARCHAR2może wynosić 4000 bajtów. Jeśli parametr init.ora max_string_size = rozszerzona, maksymalna długość a VARCHAR2może wynosić 32767 bajtów

Typ VARCHARdanych przechowuje ciągi znaków o różnej długości. Pierwsze 2 bajty zawierają długość ciągu znaków, a pozostałe bajty zawierają ciąg. Podana długość ciągu w powiązaniu lub wywołaniu definicji musi zawierać dwa bajty długości, więc największy VARCHARciąg, który można odebrać lub wysłać, ma długość 65533 bajtów, a nie 65535.

Szybki test w bazie danych 12.2 sugeruje, że jako wewnętrzny typ danych Oracle nadal traktuje VARCHARjako pseudotyp dla VARCHAR2. NIE SYNONYMjest to rzeczywisty typ obiektu w 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)

Istnieją również pewne implikacje VARCHARdla opcji Prekompilatora ProC / C ++. Zainteresowanym programistom link znajduje się w: Pro * C / C ++ Programmer's Guide

piaskowy człowiek
źródło
1
więc czy to oznacza, że VARCHARnadal to traktuje '' == null?
2
Tak. Omówienie powyższych typów wewnętrznych i zewnętrznych pochodzi z odniesienia OCI. 12.2 Język SQL Reference nadal nosi to samo „nie używać” oświadczenie, że zawsze miał dla VARCHAR.
William Robertson,
Właśnie dlatego omawiałem różnice OCI, w przeciwnym razie jest to raczej zarezerwowane do wykorzystania w przyszłości lub, jak mówią „zmienna długość”, co może sugerować zestawy znaków, takie jak wielobajtowy UTF8 ...
sandman
1
Pokazałeś, że wartości zadeklarowane jako VARCHAR są przechowywane w bazie danych jako VARCHAR2, jednak maksymalna długość VARCHAR (65533 bajtów) jest większa niż maksymalna długość VARCHAR2 (32767 bajtów). Jak baza danych sobie z tym radzi?
Piotr Dobrogost
IIRC, dawno temu (być może Oracle 6?) Istniał typ VARCHAR, który źle zachowywał się w przypadku wypełniania spacji - czy to było obcięcie spacji? AAR, VARCHAR2 było odpowiedzią. Wyrocznia powiedziała, że ​​przyniosą VARCHAR, ale jestem pewien, że zgrzyta zębami, gdy pusty łańcuch NIE JEST NULL.
JMD,
2

Po kilku eksperymentach (patrz poniżej) mogę potwierdzić, że od września 2017 r. Nic się nie zmieniło w odniesieniu do funkcjonalności opisanej w zaakceptowanej odpowiedzi : -

  1. Demo Rextester dla Oracle 11g: Puste łańcuchy są wstawiane jakoNULLs dla obuVARCHAR iVARCHAR2.
  2. Demo LiveSQL dla Oracle 12c: Te same wyniki.

Historyczny powód tych dwóch słów kluczowych został dobrze wyjaśniony w odpowiedzi na inne pytanie .

Steve Chambers
źródło
0
  1. VARCHAR może przechowywać do 2000 bajtów znaków, podczas gdy VARCHAR2 może przechowywać do 4000 bajtów znaków.

  2. Jeśli zadeklarujemy typ danych jako VARCHAR, wówczas zajmie miejsce na wartości NULL. W przypadku typu danych VARCHAR2 nie będzie on zajmował miejsca na wartości NULL. na przykład,

    name varchar(10)

zarezerwuje 6 bajtów pamięci, nawet jeśli nazwa to „Ravi__”, natomiast

name varchar2(10) 

zarezerwuje miejsce zgodnie z długością ciągu wejściowego. np. 4 bajty pamięci dla „Ravi__”.

Tutaj _ oznacza NULL.

UWAGA: varchar zarezerwuje miejsce na wartości null, a varchar2 nie zarezerwuje miejsca na wartości null.

Palak Jain
źródło
2
Myślę, że ta odpowiedź jest niejasna VARCHARz CHAR.
Jon Heller
0

Obecnie są takie same. ale wcześniej

  1. Gdzieś w sieci przeczytałem, że

VARCHARjest zastrzeżone przez Oracle do obsługi rozróżnienia pomiędzy NULLi pustym łańcuchem w przyszłości, jak nakazuje standard ANSI.

VARCHAR2nie rozróżnia NULLciągów od pustych i nigdy nie będzie.

  1. Również,

Emp_name varchar(10)- jeśli wprowadzisz wartość mniejszą niż 10 cyfr, pozostałego miejsca nie będzie można usunąć. wykorzystał w sumie 10 miejsc.

Emp_name varchar2(10) - jeśli wprowadzisz wartość mniejszą niż 10 cyfr, wówczas pozostałe miejsce zostanie automatycznie usunięte

Ramkumar P.
źródło
Ostatnio natknąłem się na ten post. Pamiętaj, że jest on niepoprawny. Wykonaj następujące czynności, a oba pola będą miały 3 znaki: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;
Brian Leach
-1

VARCHAR jest synonimem VARCHAR2. Nie należy jednak używać VARCHAR, ponieważ Oracle może zmienić swoją semantykę w przyszłości.

Premraj
źródło