Virtual columns: create table sales(sales_amt number,sales_category varchar(6) generated always as ( case when sales_amt<=1000 then 'LOW' else 'HIGH' end ) virtual ); SQL> desc sales; Name Null? Type ----------------------------------------- -------- -------------------SALES_AMT SALES_CATEGORY NUMBER VARCHAR2(6) SQL> select * from sales; no rows selected SQL> insert into sales values(3456); insert into sales values(3456) * ERROR at line 1: ORA-00947: not enough values SQL> insert into sales(sales_amt) values(2345); 1 row created. SQL> insert into sales(sales_amt) values(345); 1 row created. SQL> select * from sales; SALES_AMT -----------------2345 345 SALE ------HIGH LOW Practise 2: Adding a virtual column to an existing table SQL>create table virt_tab2 (name varchar2(10),marks1 number,marks2 number,marks3 number); Table created. SQL>insert into virt_tab2 values('venkat',34,23,56); 1 row created. SQL>insert into virt_tab2 values('Raj',94,83,36); 1 row created. SQL> alter table virt_tab2 add marks4 number; // adding a normal column Table altered. SQL> select * from virt_tab2; NAME ---------venkat Raj MARKS1 ---------34 94 MARKS2 ---------23 83 MARKS3 ---------56 36 MARKS4 ---------- SQL> alter table virt_tab2 add total number generated always as (marks1+marks2+marks3+marks4) virtual; //adding a virtual column Table altered. SQL> insert into virt_tab2(name, marks1,marks2,marks3,marks4) values('kiran',23, 12,78,90); 1 row created. SQL> insert into virt_tab2(name, marks1,marks2,marks3,marks4) values('venu',90,22,78,90); 1 row created. SQL>select * from virt_tab2; NAME ---------venkat Raj kiran venu MARKS1 ---------34 94 23 90 MARKS2 ---------23 83 12 22 MARKS3 ---------56 36 78 78 MARKS4 ---------- TOTAL ---------- 90 90 203 280 Notes: You can create indexes, partitions on a virtual columns You can’t insert a value into the virtual column (through INSERT command) The difference is that the virtual column is not stored, even though it can be accesses like a normal column. To prove that the virtual column is actually not taking any space Practice 3: SQL>select * from virt_tab2; NAME ---------venkat Raj kiran venu MARKS1 ---------34 94 23 90 MARKS2 ---------23 83 12 22 MARKS3 ---------56 36 78 78 MARKS4 ---------- TOTAL ---------- 90 90 203 280 SQL>analyze table virt_tab2 compute statistics Table analyzed. SQL> select num_rows*avg_row_len from user_tables where table_name='VIRT_TAB2' NUM_ROWS*AVG_ROW_LEN ---------------------------------------76 bytes ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------SQL> select * from virt_tab3; NAME MARKS1 MARKS2 MARKS3 MARKS4 ---------- ---------- ---------- ---------- ---------venkat 34 23 56 Raj 94 83 36 kiran 23 12 78 90 venu 90 22 78 90 SQL> analyze table virt_tab3 compute statistics; Table analyzed. SQL> SQL> SQL> select num_rows*avg_row_len from user_tables where table_name='VIRT_TAB3' NUM_ROWS*AVG_ROW_LEN -------------------76 bytes Even if you exclude the virtual column, the space is same. That means, the virtual column is not actually taking any space. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------To check it in another way. SQL> create table virt_tab5 as (select * from virt_tab2); Table created. SQL> analyze table virt_tab5 compute statistics; Table analyzed. SQL> select * from virt_tab5; NAME ---------venkat Raj kiran venu MARKS1 ---------34 94 23 90 MARKS2 ---------23 83 12 22 MARKS3 ---------56 36 78 78 MARKS4 ---------- TOTAL ---------- 90 90 203 280 SQL> select num_rows*avg_row_len from user_tables where table_name='VIRT_TAB5' NUM_ROWS*AVG_ROW_LEN ---------------------------------------84 bytes If another table with the same content, except a real column in place of the virtual column, it’s taking 84 bytes, which is 8 bytes more than the original table.