Category: Database

  • DBA_TAB_COLUMNS vs DBA_TAB_COLS

    Not sure how many DBAs have noticed the difference between DBA_TAB_COLUMNS view and DBA_TAB_COLS view. Both views look pretty identical, if you are not paying too much attention. According to Oracle documentation, DBA_TAB_COLS describes the columns of all tables, views, and clusters in the database. This view differs from “DBA_TAB_COLUMNS” in that system-generated hidden columns and invisible columns, which are user-generated hidden columns, are not filtered out.

    Let me dig a little deep to understand the differences better. First, how the views are built…

    Until 11gR2, DBA_TAB_COLS view is a complex SQL joining multiple internal dictionary tables. The FROM clause is shown here…

    The FROM clause of DBA_TAB_COLS view in 10gR2 is…

    --10gR2 
    SQL> set long 32000 
    SQL> select text from dba_views 
         where view_name = 'DBA_TAB_COLS'; 
     
         from sys.col$ c, sys.obj$ o, sys.hist_head$ h, sys.user$ u, 
              sys.coltype$ ac, sys.obj$ ot, sys.user$ ut 
    

    The FROM clause of DBA_TAB_COLS view in 11gR2 is…

    --11gR2
    SQL> select text from dba_views 
         where view_name = 'DBA_TAB_COLS';
    
         from sys.col$ c, sys."_CURRENT_EDITION_OBJ" o, sys.hist_head$ h, 
         sys.user$ u, sys.coltype$ ac, sys.obj$ ot, 
         sys."_BASE_USER" ut, sys.tab$ t
    

    Because of the increased complexity by introducing new features like invisible columns, I think Oracle decided to create an intermediate view named DBA_TAB_COLS_V$ to make the SQL for DBA_TAB_COLS simpler in 12c. The view SQL for SYS.DBA_TAB_COLS_V$ is similar to the SQL used in DBA_TAB_COLS in 11gR2, but has more lines.

    So, in 12c, the DBA_TAB_COLS view is a straight SELECT of columns from DBA_TAB_COLS_V$ without any WHERE clause.

    In all versions the DBA_TAB_COLUMNS is a query on selected columns from DBA_TAB_COLS with a WHERE clause to filter the hidden columns. In 10g and 11g, the WHERE clause is where HIDDEN_COLUMN = ‘NO’ and in 12c the WHERE clause changed to where USER_GENERATED = ‘YES’.

    Full SQL used for the DBA_TAB_COLUMNS view in 12c is below.

    --12cR1
    SQL> set long 32000
    SQL> select text from dba_views where view_name = 'DBA_TAB_COLUMNS';
    
    TEXT
    ----------------------------------------------------------------------
    select OWNER, TABLE_NAME,
    COLUMN_NAME, DATA_TYPE, DATA_TYPE_MOD, DATA_TYPE_OWNER,
    DATA_LENGTH, DATA_PRECISION, DATA_SCALE, NULLABLE, COLUMN_ID,
    DEFAULT_LENGTH, DATA_DEFAULT, NUM_DISTINCT, LOW_VALUE, HIGH_VALUE,
    DENSITY, NUM_NULLS, NUM_BUCKETS, LAST_ANALYZED, SAMPLE_SIZE,
    CHARACTER_SET_NAME, CHAR_COL_DECL_LENGTH,
    GLOBAL_STATS, USER_STATS, AVG_COL_LEN, CHAR_LENGTH, CHAR_USED,
    V80_FMT_IMAGE, DATA_UPGRADED, HISTOGRAM, DEFAULT_ON_NULL,
    IDENTITY_COLUMN, SENSITIVE_COLUMN,
    EVALUATION_EDITION, UNUSABLE_BEFORE, UNUSABLE_BEGINNING
    from DBA_TAB_COLS
    where USER_GENERATED = 'YES'

    Which columns are available in DBA_TAB_COLS that are not in DBA_TAB_COLUMNS? Following query shows the columns that are additional in DBA_TAB_COLS in 12cR1.

    SQL> select column_name from dba_tab_cols 
         where table_name = 'DBA_TAB_COLS'
         minus
         select column_name from dba_tab_cols 
         where table_name = 'DBA_TAB_COLUMNS';
    
    COLUMN_NAME
    -----------------------------
    HIDDEN_COLUMN
    INTERNAL_COLUMN_ID
    QUALIFIED_COL_NAME
    SEGMENT_COLUMN_ID
    USER_GENERATED
    VIRTUAL_COLUMN

    USER_GENERATED column is new in 12c, all other columns are same in 11gR2/10gR2 as well.

    When you mark a column in table as UNUSED (that is a candidate for drop), it becomes hidden in 11gR2. Is Hidden Column different from Invisible Column in 12c DBA_TAB_COLS?

    Let me create a table with the following characteristics. Columns 1, 4 & 7 are regular columns with no speciality. x2 is invisible, x3 is virtual, x5 is invisible and virtual, x6 is identity.

    SQL> create table hidden_test (
         x1 number,
         x2 number invisible,
         x3 number generated always as (x1/2) virtual,
         x4 number,
         x5 number invisible generated always as (x1/4) virtual,
         x6 number generated always as identity,
         x7 number );
    
    Table created.

    Query the column properties of the table just created.

    SQL> col column_name format a5
    SQL> select column_name, user_generated, virtual_column, hidden_column, 
                identity_column, column_id, segment_column_id, internal_column_id
         from dba_tab_cols
         where table_name = 'HIDDEN_TEST';
    
    COLUM USE VIR HID IDE  COLUMN_ID SEGMENT_COLUMN_ID INTERNAL_COLUMN_ID
    ----- --- --- --- --- ---------- ----------------- ------------------
    X7    YES NO  NO  NO           5                 5                  7
    X6    YES NO  NO  YES          4                 4                  6
    X5    YES YES YES NO                                                5
    X4    YES NO  NO  NO           3                 3                  4
    X3    YES YES NO  NO           2                                    3
    X2    YES NO  YES NO                             2                  2
    X1    YES NO  NO  NO           1                 1                  1
    
    7 rows selected.

    Notice all columns have USER_GENERATED as YES, which means all of these columns will be visible in DBA_TAB_COLUMNS. Remeber, this is the filter condition for DBA_TAB_COLUMNS, so for all subsequent queries on DBA_TAB_COLS, if USER_GENERATED is NO, those columns will not be visible in DBA_TAB_COLUMNS. [[I would have liked to see VIRTUAL_COLUMN (HIDDEN_COLUMN too) as part of DBA_TAB_COLUMNS, they would have added some useful information to DBA_TAB_COLUMNS.]] Virtual column information is included in DBA_TAB_COLUMNS, but does not identify if the column is VIRTUAL or not. The invisible columns are marked as HIDDEN_COLUMN=YES. Now, mark x4 for drop and x2 visible.

    SQL> alter table hidden_test set unused (x4);
    
    Table altered.
    
    SQL> alter table hidden_test modify x2 visible;
    
    Table altered.
    
    SQL>

    Query the properties again…

    SQL> select column_name, user_generated, virtual_column, hidden_column, 
                identity_column, column_id, segment_column_id, internal_column_id
         from dba_tab_cols
         where table_name = 'HIDDEN_TEST';
    
    COLUMN_NAM USE VIR HID IDE  COLUMN_ID SEGMENT_COLUMN_ID INTERNAL_COLUMN_ID
    ---------- --- --- --- --- ---------- ----------------- ------------------
    X7         YES NO  NO  NO           4                 5                  7
    X6         YES NO  NO  YES          3                 4                  6
    X5         YES YES YES NO                                                5
    SYS_C00004 NO  NO  YES NO                             3                  4
    _14060322:
    52:06$
    
    X3         YES YES NO  NO           2                                    3
    X2         YES NO  NO  NO           5                 2                  2
    X1         YES NO  NO  NO           1                 1                  1
    
    7 rows selected.

    The x4 column name marked for drop got renamed, and got a system generated name. The rename is to facilitate adding a column with same name to the table. The column x4 also got property changes – USER_GENERATED became NO and HIDDEN_COLUMN changed to YES. Also, the COLUMN_ID is released, thus the column will not be visilbe in “SELECT *” and “DESCRIBE”. The UNUSED column still maintains the same INTERNAL_COLUMN_ID.

    When x2 column is made VISIBLE, it got a new COLUMN_ID assigned (the highest available, thus the column becomes the last column in “SELECT *” and “DESCRIBE”). Its hidden status changed to NO.

    What happens to the ID columns, when the UNUSED column is dropped.

    SQL> alter table hidden_test drop unused columns;
    
    Table altered.
    
    SQL> select column_name, user_generated, virtual_column, hidden_column, 
                identity_column, column_id, segment_column_id, internal_column_id
         from dba_tab_cols
         where table_name = 'HIDDEN_TEST';
    
    COLUMN_NAM USE VIR HID IDE  COLUMN_ID SEGMENT_COLUMN_ID INTERNAL_COLUMN_ID
    ---------- --- --- --- --- ---------- ----------------- ------------------
    X7         YES NO  NO  NO           4                 4                  6
    X6         YES NO  NO  YES          3                 3                  5
    X5         YES YES YES NO                                                4
    X3         YES YES NO  NO           2                                    3
    X2         YES NO  NO  NO           5                 2                  2
    X1         YES NO  NO  NO           1                 1                  1
    

    The COLUMN_ID got reordered after the unused column is dropped (X4 was dropped, hence X6 and X7 got new column ids – X5 never had a column id assigned as it is INVISIBLE). The internal column id, which includes id for INVISIBLE columns also got adjusted. After the column is dropped, the INTERNAL_COLUMN_ID also got adjusted.

    Well, I started with just difference between DBA_TAB_COLS and DBA_TAB_COLUMNS, but got into investigating column ids… 🙂

    [amazon text=Amazon&template=carousel&asin=111864395X]

  • OracleNotes TidBits – May 2014

    Oracle TidBit
    Oracle TidBit

    According to the dictionary, meaning of “tidbit” is “a small and particularly interesting item of gossip or information“… hope you find the “Oracle TidBits” published at https://www.facebook.com/oraclenotes interesting…

    Here is a compilation of the tidbits published in May 2014. You will also see these tidbits, one tidbit at a time, for each page refresh on the right side of this blog as well…

     

    TidBit Topic
    Oracle Database12c introduced a mandatory process namedLREG – Listener Registration. TheLREG registers information about the database instance and dispatcher processes with the Oracle Net Listener. When an instance starts,LREG polls the listener to determine whether it is running. If the listener is running, thenLREG passes it relevant parameters. If it is not running, thenLREG periodically attempts to contact it.In releases before Oracle Database 12c, PMON performed the listener registration. Listener
    With ALTER DATABASE RENAME FILE …, you can specify only the name of the file as the original file (not file number), whereas in Oracle Database12c ALTER DATABASE MOVE FILE …, you can specify the file number or file name as source file.If you identify the file by number, then file number is the value found in the FILE# column of the V$DATAFILE view (or the FILE_ID column of the DBA_DATA_FILES view). Data File
    In Oracle Database 12c, you can limit the PGA memory using the PGA_AGGREGATE_LIMIT parameter. By default, PGA_AGGREGATE_LIMIT is set to the greater of 2 GB, 200% of PGA_AGGREGATE_TARGET, and 3 MB times the PROCESSES parameter. It will not exceed 120% of the physical memory size minus the total SGA size. Memory
    In Oracle Databse 12c, you can make a column in table as INVISIBLE. When you make it invisible, the COL# column in COL$ dictiionary table is updated to 0, thus is not included in the “SELECT *” or “INSERT INTO VALUES”, unless specifically selected. Administration
    When you make an INVISIBLE column in Oracle 12c database to VISIBLE, the COL# is assigned the highest available. Thus the column becomes the last column in the table (not storage, only display). So, if you accidentally make a column INVISIBLE and correct it by changing to VISIBLE, the column order changes. So, if the application uses “SELECT *” or “INSERT” without column names, they might break! Administration
    The SPARE6 column in SYS.USER$ table keeps track the last successful login time of the user in Oracle Database 12c. This is a very good security feature, without enabling “AUDIT SESSION” to find when the user last used the database. Security
    Datapump import in Oracle Database 12c has option to perform import without generating redo (thus no archive logs). Use option TRANSFORM=DISABLE_ARCHIVE_LOGGING:Y[:TABLE|INDEX]. This sets object to NOLOGGIG before import and reverts to original setting after import. DataPump
    Oracle Database 12c has option to run the Oracle instance on Unix as threads, consolidating multiple processes to one. By setting THREADED_EXECUTION=YES, allows multiple background processes to share a single OS process on Unix, similar to Windows. In default process models, SPID and STID columns of V$PROCESS will have the same values, whereas in multithreaded models, each SPID (process) will have multiple STID (threads) values. Administration
    In Oracle Database 12c, when you move the online data file using ALTER DATABASE MOVE DATAFILE ‘filename’; without the TO clause, the file will be moved to DB_FILE_CREATE_DEST as Oracle Managed File – the DB_FILE_CREATE_DEST location can be ASM diskgroup or file system. Data File
    The SYS.USER$ table has tracking columns. CTIME shows when user was created, PTIME shows when user password was last changed, LTIME shows when the user account was locked. In 12c, SPARE6 columns shows last login time of user. Security
    V$SYSTEM_FIX_CONTROL displays information about Fix Control (enabled/disabled) at the system level. Shows bug number, sql feature, description of bug, etc in this view. Use _FIX_CONTROL initialization parameter to turn on or off specific optimizer patches and bug fixes. More information in MOS note “How to use the _FIX_CONTROL hidden parameter (Doc ID 827984.1)” Administration
    Oracle Database 11gR2 support ends Jan 2015. But, there is good news. The Extended Support fee has been waived for the period of February 2015 – January 2016. Read http://www.oracle.com/us/support/library/057419.pdf Miscellaneous
    Oracle Database 12c has a new command-line upgrade utility to upgrade database to 12c – catctl.pl. This utility replaces the catupgrd.sql script used to upgrade to previous releases of Oracle Database. The new utility enables parallel processing during the database upgrade, resulting in better upgrade performance. Upgrade