Creating Table:
CREATE TABLE test (
charcol CHAR(10),
varcharcol VARCHAR2(10));
SELECT LENGTH(charcol), LENGTH(varcharcol) FROM test;
>
Although there are already several answers correctly describing the behaviour of char
, I think it needs to be said that you should not use it except in two specific situations:
char
avoids the need to code an rpad()
expression. For example, if firstname
and lastname
are both defined as char(20)
, then firstname || lastname
is a shorter way of writing rpad(firstname,20) || rpad(lastname,20)
.''
and null
. Normally they are the same thing in Oracle, but assigning ''
to a char
value will trigger its blank-padding behaviour while null
will not, so if it's important to tell the difference, and I can't really think of a reason why it would be, then you have a way to do that.There is really no reason to use char
just because some length is fixed (e.g. a Y/N
flag or an ISO currency code such as 'USD'
). It's not more efficient, it doesn't save space (there's no mythical length indicator for a varchar2
, there's just a blank padding overhead for char
), and it doesn't stop anyone entering shorter values. (If you enter 'ZZ'
in your char(3)
currency column, it will just get stored as 'ZZ '
.) It's not even backward-compatible with some ancient version of Oracle that once relied on it, because there never was one.
And the contagion can spread, as (following best practice) you might anchor a variable declaration using something like sales.currency%type
. Now your l_sale_currency
variable is a stealth char
which will get invisibly blank-padded for shorter values (or ''
), opening the door to obscure bugs where l_sale_currency
does not equal l_refund_currency
even though you assigned 'ZZ'
to both of them.
CHAR
was introduced in Oracle 6 for, I'm sure, ANSI compatibility reasons. Probably there are potential customers deciding which database product to purchase and ANSI compatibility is on their checklist (or used to be back then), and CHAR
with blank-padding is defined in the ANSI standard, so Oracle needs to provide it. You are not supposed to actually use it.