Sunday 27 January 2013

Difference between BYTE and CHAR in column data types


SQL> CREATE TABLE CLIENT
  2  (
  3   NAME VARCHAR2(11 BYTE),
  4   ID_CLIENT NUMBER
  5  );

Table created.

SQL> desc client;
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 NAME                                                           VARCHAR2(11)
 ID_CLIENT                                                      NUMBER

SQL> CREATE TABLE CLIENT1
  2  (
  3   NAME VARCHAR2(11 CHAR),
  4   ID_CLIENT NUMBER
  5  );

Table created.

SQL> desc client1;
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 NAME                                                           VARCHAR2(33)
 ID_CLIENT                                                      NUMBER

SQL> CREATE TABLE CLIENT2
  2  (
  3   NAME VARCHAR2(11),
  4   ID_CLIENT NUMBER
  5  );

Table created.

SQL> desc client2;
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 NAME                                                           VARCHAR2(11)
 ID_CLIENT                                                      NUMBER

SQL>

SQL> select TABLE_NAME,CHAR_USED,CHAR_LENGTH,DATA_LENGTH from user_tab_columns where table_name IN (
'CLIENT','CLIENT1','CLIENT2') AND COLUMN_NAME='NAME';

TABLE_NAME                C   CHAR_LENGTH      DATA_LENGTH
--------------------------- -   ----------------        ---------------
CLIENT                         B          11                   11
CLIENT1                       C          11                   33
CLIENT2                       B          11                   11

Let us assume the database character set is UTF-8, it is the default in recent version of Oracle. In this case, some characters take more than 1 byte to store in the database.

If you define the field as VARCHAR2(11 BYTE) or VARCHAR2(11), Oracle will allocate 11 bytes for storage, but you may not actually be able to store 11 charactersin the field, because some of them take more than one byte to store, e.g. non-English characters.

By defining the field as VARCHAR2(11 CHAR) you tell Oracle to allocate enough space to store 11 characters,no matter how many bytes it takes to store each one. In Oracle 10g, 3 bytes per character were used.
The VSIZE function returns the byte size of a String.

Difference between length and vsize functions in oracle


length returns the length of the pased string , vsize function returns the number of bytes used to store tha data.

length returns the length of the string passed. If string is a number, it first converts the number into a string and then returns its length.As Oracle treats an empty string as null, the length of an empty string is also null.

if any non-english characters are there in a column, vsize function gives you howmany bytes used to store that value.

SQL> select length(sysdate) from dual;

LENGTH(SYSDATE)
---------------
              9
               
SQL> select vsize(sysdate) from dual;

VSIZE(SYSDATE)
--------------
             7

SQL> select sysdate from dual;

SYSDATE
---------
28-JAN-13

How to check NLS_LENGTH_SEMANTICS


> NLS_LENGTH_SEMANTICS allows one to specify the length of a column datatype in terms of CHARacters rather than in terms of BYTEs.

> The NLS_LENGTH_SEMANTICS value found in NLS_DATABASE_PARAMETERS is the value at database creation time. This should be BYTE.

SQL> SELECT value FROM NLS_DATABASE_PARAMETERS where parameter='NLS_LENGTH_SEMANTICS';

VALUE
--------------------------------------------------------------------------------------
BYTE

SQL> SELECT value FroM V$PARAMETER WHERE NAME LIKE '%nls_length_semantics%';

VALUE
--------------------------------------------------------------------------------------
BYTE

How to check character set in Oracle



You can either check with your DBA or run the following SQL to determine your database character set.

SQL> SELECT value FROM NLS_DATABASE_PARAMETERS where parameter='NLS_CHARACTERSET';

VALUE
-------------------------------------------------------------------------------------
UTF8

SQL> SELECT value$ FROM sys.props$ WHERE name = 'NLS_CHARACTERSET';

VALUE$
--------------------------------------------------------------------------------------
UTF8

Wednesday 2 January 2013

What is the difference between NOT IN and MINUS


supose you have 2 tables
T1 (code varchar2(5));
T2 (code varchar2(5));

CREATE TABLE T1 (code varchar2(5));
INSERT INTO T1 VALUES('A1');
INSERT INTO T1 VALUES('A2');
INSERT INTO T1 VALUES('A3');
INSERT INTO T1 VALUES('A4');
INSERT INTO T1 VALUES(NULL);

CREATE TABLE T2 (code varchar2(5));
INSERT INTO T2 VALUES('A1');
INSERT INTO T2 VALUES('A2');
INSERT INTO T2 VALUES('B1');
INSERT INTO T2 VALUES(NULL);
INSERT INTO T2 VALUES(NULL);
COMMIT;
/

i made this 2 select :

SQL> select code from T1
     where code not in (select distinct code from t2);

no rows selected

SQL> select code  from T1
    minus
    select code from t2;
    
CODE
----
A3
A4


Case #1
code in t2  has some nulls, it is not KNOWN the values contains nulls.
"NOT IN" is sensible to null values, so a false condition is generated thus, bringing no rows.
Note: Still, the use of NOT IN is not advisable unless the table is very small. Performance is very poor with large tables.

select * from dual where 1 not in ( 2, null );
no rows selected

Case #2

When using MINUS, the query is not "sensible" to this null values. so it is fetching distinct values.

Practice Below:
-----------------

delete from T1 where code is null;

Case1#
----------
select * from t2 where code not in (select * from T1)

CODE
-----
B1

Case2#
--------------
select * from t2
minus
select * from T1

CODE
----
B1
NULL