Logan.47
Logan.47

Reputation: 11

Query column with char data type in oracle

I have the following case:

Sample code:

        create table abc(aa char(10));
        insert into abc values('ABC'); 
        --ABC will be padded with 7 blank spaces
        Issue:
        Select * from abc where aa in ('ABC'); 
        --This above statement returns one row with value ABC
        Declare
        v_temp varchar2(10);
        v_aa varchar2(10) := 'ABC';
        Begin
        select aa into v_temp from abc where aa in (v_aa);
        dbms_output.put_line(v_temp);
        end;

--The above pl/sql block one execution prints nothing but if i replace the select inside that block with "select aa into v_temp from abc where aa in ('ABC');" the value will be printed.

Please advice me on the behaviour.

Upvotes: 1

Views: 4044

Answers (4)

crisu
crisu

Reputation: 150

If a VARCHAR2 value is compared to a CHAR value, non-blank-padding semantics are used. But, remember, when you assign a character value to a CHAR variable, if the value is shorter than the declared length of the variable, PL/SQL blank-pads the value to the declared length. Given the declarations

v_aa1 VARCHAR2(10) := 'ABC';
v_aa2 CHAR(10)     := 'ABC';  -- PL/SQL blank-pads value

the following IF condition is false because the value of v_aa2 includes five trailing blanks:

IF v_aa1 = v_aa2 THEN ...

All string literals have datatype CHAR. If both values in a comparison are literals, blank-padding semantics are used. If one value is a literal, blank-padding semantics are used only if the other value has datatype CHAR.

Upvotes: 0

René Nyffenegger
René Nyffenegger

Reputation: 40563

Declare the table with a varchar2:

create table abc (
   aa varchar2(10)
);

Alternatively, declare v_aa as char(10). But I would strongly assume that you should go the varchar2 route.

Update

So, I understand your chars stem back from a migration and you're ok to switch them to varchar2. You might want to run

select 
  'alter table ' || table_name  || 
  ' modify '     || column_name || 
  ' varchar2('   || char_length ||');' stmt
from
  user_tab_columns
where
  data_type = 'CHAR';

This will produce alter table statements (like so:)

alter table ABC modify AA varchar2(10);

which you can then run to change the definitions.

Of course, it (almost) goes without saying that you want to thoroughly test that before you apply it on your production database.

Upvotes: 0

Justin Cave
Justin Cave

Reputation: 231791

The issue comes down to whether you use char or varchar2 comparison semantics in your queries. If you have a hard-coded string literal or a char(10) variable, Oracle uses the char comparison semantics which are to ignore the trailing white space. If you have a varchar2(10) variable, Oracle uses the varchar2 comparison semantics which includes the trailing white space. Thus

 select aa 
   into v_temp 
   from abc 
  where aa in (v_aa);

will return a row if v_aa is defined as a char(10) (or if it is replace with a string literal) but not if it is defined as a varchar(10).

This is one of the (many) reasons that most people avoid char data types entirely. Personally, I don't mind the occasional char for truly fixed-width data (i.e. char(1) for flags and char(2) for state codes) even though there is no benefit to using char over varchar2 in those scenarios. For anything that is not fixed-width, however, using a char makes no sense. You're just forcing Oracle to consume more space than it needs to and creating more work for yourself dealing with two sets of string comparison semantics (among other issues).

Upvotes: 2

void
void

Reputation: 7890

even if you use select aa from abc where aa in (cast('ABC' as varchar2(10))); you will get no data because:

with varcha2(10) the length of the value of the field is 3 but with char(10) it is is 10

you need to define the v_aa as char(10):

    Declare
    v_temp varchar2(10);
    v_aa char(10) := 'ABC';
    Begin
    select aa into v_temp from abc where aa in (v_aa);
    dbms_output.put_line(v_temp);
    end;

OUTPUT: ABC

Upvotes: 0

Related Questions