Oracle má tři datové typy pro ukládání řetězců. – CHAR, VARCHAR a VARCHAR2. Jak se od sebe liší? Kdy byste měli který použít?
Odpovědi se dozvíte v tomto článku.
Nejdříve to nejjednodušší z cesty: VARCHAR a VARCHAR2 je totéž. Ale že to dnes – to se může změnit. Podívejte se do dokumentace Oracle 10G Release 2:
Nepoužívejte datový typ
VARCHAR
. Místo toho použijte datový typVARCHAR2
. Přestože datový typVARCHAR
je v současné době synonymem proVARCHAR2
, plánuje se předefinování datového typuVARCHAR
jako samostatného datového typu používaného pro porovnávání znakových řetězců proměnné délky s odlišnou sémantikou porovnávání.
V tomto článku se VARCHAR2 používá pro označení VARCHAR i VARCHAR2, protože jsou dnes ekvivalentní.
Jak se tedy liší CHAR a VARCHAR2?
Rozdíl je v tom, že CHAR(n) bude VŽDY dlouhý n bajtů. Pokud je délka řetězce <n, bude při vložení prázdný, aby byla zajištěna délka n. Naproti tomu VARCHAR2(n) bude mít délku 1 až n bajtů. Kratší řetězec uložený jako VARCHAR2 NEBUDE prázdně vyplněn.
Předpokládejme například, že řetězec „ORATABLE“ uložíte do pole CHAR(20) a VARCHAR2(20). Pole CHAR využije 22 bajtů (2 bajty pro počáteční délku). Pole VARCHAR2 použije pouze 10 bajtů (8 pro řetězec, 2 bajty pro počáteční délku).
Shrneme-li to, CHAR je VARCHAR2 doplněný na maximální délku.
Jak tento rozdíl ovlivňuje SQL?
Změní se způsob porovnávání řetězců CHAR vs VARCHAR2. Podívejte se na to v akci:
SQL> create table strings 2 (colchar char (20) 3 , colvarchar varchar2 (20));Table created.SQL>SQL> insert into strings 2 (colchar, colvarchar) 3 values 4 ('ORATABLE', 'ORATABLE');1 row created.SQL> -- Define a string variableSQL> var str varchar2(20)SQL> -- Give it a value with length < 20SQL> exec :str := 'ORATABLE'PL/SQL procedure successfully completed.SQL> -- Exact string match with CHARSQL> -- No result found!SQL> select 'found' found_flag 2 from strings 3 where colchar = :str;no rows selectedSQL> -- Padded string match with CHARSQL> -- Now it finds itSQL> select 'found' found_flag 2 from strings 3 where colchar = rpad(:str,20);FOUND-----found
Takže vidíte, že vyplnění mezerami má vliv na to, zda se řetězec CHAR porovná s parametrem proměnné délky. Chcete-li získat shodu, musíte buď hodnotu rpad, nebo sloupec rtrim.
U VARCHAR2 takový požadavek není:
SQL> -- Exact string match with VARCHAR2SQL> -- Result found!SQL> select 'found' found_flag 2 from strings 3 where colvarchar = :str;FOUND-----found
Kdy máme použít CHAR, kdy VARCHAR2?“
Pokud budete vždy používat pouze VARCHAR2 a CHAR budete ignorovat, výrazně si zjednodušíte život. Mezi nimi není žádný rozdíl, kromě toho, že CHAR spotřebuje více místa, když vaše řetězce nemají vždy pevně stanovenou maximální délku. Navíc CHAR vede k většímu zmatku při psaní dotazů.
Já používám CHAR jako databázové sloupce pouze pro hodnoty typu Y/N. V případě, že se jedná o sloupce typu CHAR, je to pro mě obtížné. (Neexistuje datový typ sloupce BOOLEAN, pamatujete?) Funguje to jako značka pro sloupec typu „příznak“ nebo „přepínač“ – ale stejně dobře by to mohl být VARCHAR2.
Pro všechny ostatní řetězce je to VARCHAR2.
Shrnutí
Při zvažování datových typů Oracle CHAR, VARCHAR a VARCHAR2 pamatujte, že:
- VARCHAR a VARCHAR2 jsou stejné, ale funkce VARCHAR se může v budoucnu změnit. Používejte VARCHAR2.
- CHAR a VARCHAR2 se liší tím, že CHAR prázdný řetězec vyplňuje tak, aby měl maximální délku. VARCHAR2 prázdné pole nevyplňuje.
- Vzhledem k výše uvedenému vyžadují dotazy, které zahrnují porovnávání řetězců ve sloupci CHAR, větší opatrnost – VARCHAR2 v porovnání s CHAR musí být rpad-ded, aby se trefil.
- Je třeba zopakovat: používejte VARCHAR2!