Anda di halaman 1dari 5

www.codeitmagazine.

com

Look It Up! The Oracle Data Dictionary


Christopher Johnson

Oracle is an aptly named software. In ancient Greece, the Oracle of Delphi was the place to go to ask
questions about the future. The Oracle was the center of the navigable world, and people would sail the
world to ask their questions. Likewise, the Oracle software is not just a filing cabinet for storing tables of
data, but it stores a great deal of information about the data itself, and you only need to know how to
ask the question.
The data dictionary houses the metadata for all Oracles objects. There are around 1,000 views in the
dictionary, but a few in particular can give you a great deal of information. The following sample queries
can help you make sense of the madness in your sea of data.

Basics
The best place to get started is the dictionary itself. We can see a list of all tables with the following
query.
Select * from Dictionary;
There are some commonalities to mention. Most tables are not accessed directly, but through views,
and these views come in three versions for each table, and they are differentiated by their prefix. The
prefix User denotes that the results returned only contain those that are owned by the user currently
logged in, the prefix All denotes that the results are for all objects that the users has previliges to, and
the prefix DBA is for all objects in the database.
Prefix
USER_

Description
All objects owned by the user

ALL_
DBA_

All objects in the database to which the


user has privileges
All objects in the database

Having said that, here are a few noteworthy views.


View
ALL_TABLES
ALL_VIEWS
ALL_MVIEWS
ALL_SEQUENCES
ALL_SYNONYNMS
ALL_INDEXES
ALL_CONSTRAINTS

Description
Information about all tables
Information about all views
Information about all materialized views
Information about all sequences
Information about all synonyms
Information about all indexes
Information about all constraints

www.codeitmagazine.com
ALL_PROCEDURES
Information about all procedures
ALL_TAB_COLUMNS
Information about all table columns
ALL_COL_PRIVS_RECD Information about all object privileges
ALL_CONS_COLUMNS

Information about all columns with


constraints

ALL_IND_COLUMNS

Informations about all columns with


indexes

ALL_SOURCE

Sources code for all procedures,


functions, and packages

ALL_OBJECTS

Information about all tables, views,


sequences, synonyms, procedures,
packages, and functions

ALL_CATALOG
ALL_DEPENDENCIES
ALL_USERS

List of all tables, views, indexes,


synonyms, sequences, etc.
List of all object interdependencies
List of all users

Of these, a few are worth special mention. ALL_TABLES and ALL_TAB_COLS are used very frequently.
All_DEPENDENCIES can be used to determine if it is safe to delete a table, or if another process is
depending on it. ALL_OBJECTS can be used to replace many of the more specific views.
All of these can be used to explore the objects in the database and manage the objects owned by the
user as well. Just a quick example of this would be to manage the physical memory used by a users
tables. Consider the following query.
SELECT OWNER,
TABLE_NAME,
NUM_ROWS,
BLOCKS*8/1024 AS SIZE_MB
FROM ALL_TABLES
WHERE OWNER LIKE UPPER('&1')
OR OWNER = USER
ORDER BY 1,2;
This query returns all tables owned by the user, as well as the amount of disk space they take up. If we
chose to delete any of them, we can view the memory they take up in the recycle bin with the following
query.
SELECT * FROM RECYCLEBIN;
Finally, if we are sure that we will not want to Rollback or Flashback any of the tables that we have
dropped, we can empty the recycle bin with this query.
PURGE RECYCLEBIN;

www.codeitmagazine.com
There are a few more view of interest. Oracle has dynamic views of the database named with V$ or V_$
that describe the current state of the system.

View
V$DATABASE
V$VERSION
V$INSTANCE
V$PARAMETER
V$SESSION
V$SQL
V$SESSION_LONGOPS

Description
Database Information
Database Version Information
Current system instance
Current system parameters
Current sessions running
Recent SQL queries submitted
Current long running operations

The SQL table may be of interest, if you would like to retrieve a query that you have lost.
Session_longops may be of interest if you have a query that is running long, or the database is running
slowly.

Navigating From A to B
Most Oracle installations will have hundreds or thousands of tables, and they may be in third normal
form. If so, you may have a great deal of difficulty in extracting information from the raw data. You may
find youself needing to combine information from two different tables, and having no idea how to link
the two. This is no simle task. However, like a map and compass, there are a few queries against the
data dictionary that can provide some clues as to how to get there.
Lets say for a moment that you have a column in mind, and you would like to find all of the tables that
contain that column. The following query will get you there.
SELECT OWNER, TABLE_NAME
FROM ALL_TAB_COLS
WHERE COLUMN_NAME = 'colname';
If you only know part of the columnname, it can be modified as follows:
SELECT OWNER, TABLE_NAME
FROM ALL_TAB_COLS
WHERE COLUMN_NAME like '%partialcolname%';
Now consider that you would like to find all of the tables that have two columns in common.
SELECT TABLE_NAME FROM ALL_TAB_COLS WHERE COLUMN_NAME = 'column1'
INTERSECT
SELECT TABLE_NAME FROM ALL_TAB_COLS WHERE COLUMN_NAME = 'column2';
Likewise, we can find all of the columns that two tables have in common.
SELECT COLUMN_NAME FROM ALL_TAB_COLS WHERE TABLE_NAME = 'table1'

www.codeitmagazine.com
INTERSECT
SELECT COLUMN_NAME FROM ALL_TAB_COLS WHERE TABLE_NAME = 'table2';
Finally, we have a little more robust query that can take a table and find all of the tables that can
possibly join to it, assuming that any tables that can join to it have id fields with common names. You
may want to exclude common column names such as void columns from the search.
WITH LOOKUP AS (SELECT 'tablename' AS TABLE_NAME FROM DUAL)
SELECT LOOKUP.TABLE_NAME TABLE_1,
A.TABLE_NAME TABLE_2,
A.COLUMN_NAME LINK_COLUMN
FROM ALL_TAB_COLS A,
LOOKUP
WHERE A.COLUMN_NAME IN (SELECT B.COLUMN_NAME
FROM ALL_TAB_COLS B,
LOOKUP
WHERE B.TABLE_NAME = LOOKUP.TABLE_NAME)
AND COLUMN_NAME NOT IN (excludedlist);

Flashback
Not surprisingly, for a period of time called the Undo Retention Period, Oracle even stores the
transactions needed to undo committed transactions. These are stored to fascilitate the Flashback
functionality in Oracle, such as the following Flashback Query:
SELECT *
FROM TESTME
AS OF TIMESTAMP SYSTIMESTAMP - INTERVAL '0 0:01:30' DAY TO SECOND;
Or the following Flashback Version Query:
SELECT *
FROM TESTME
VERSIONS BETWEEN TIMESTAMP TO_TIMESTAMP('07DEC2015 12.15.00 PM') AND
TO_TIMESTAMP('07DEC2015 12.20.00 PM');
But we can actually query the table these views are based on and pick out only the transactions that we
want.
SELECT UNDO_SQL
FROM FLASHBACK_TRANSACTION_QUERY
WHERE XID = (SELECT VERSIONS_XID
FROM TESTME
VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE
WHERE ID = 4);

www.codeitmagazine.com

A Few Other Uses


While were using the data dictionary, there are so many other things we can do. Lets say we have
created a vast array of our own tables, and a new user comes along that we would like to share our data
with. Rather than write out grants on every table, this can be automated like this.
SELECT 'GRANT SELECT ON grantor.' || TABLE_NAME || ' TO grantee;' COMMAND FROM
ALL_TABLES WHERE OWNER = grantor
UNION
SELECT 'GRANT SELECT ON grantor.' || VIEW_NAME || ' TO grantee;' COMMAND FROM
ALL_VIEWS WHERE OWNER = grantor
UNION
SELECT 'GRANT SELECT ON grantor.' || VIEW_NAME || ' TO grantee;' COMMAND FROM
ALL_MVIEWS WHERE OWNER = grantor
UNION
SELECT 'GRANT EXECUTE ON grantor.' || OBJECT_NAME || ' TO grantee;' COMMAND FROM
ALL_PROCEDURES WHERE OWNER = grantor;
Lets say we want to delete a table, but we want to make sure that we arent going to take away
something that someone else is using. A dictionary table exists for that.
SELECT * FROM ALL_DEPENDENCIES WHERE REFERENCED_OWNER = 'owner' AND
REFERENCED_NAME = 'tablename';
Lastely, lets say we would like to determine what our privileges are in the system or what previleges we
have granted others.
SELECT * FROM ALL _TAB_PRIVS WHERE GRANTOR = 'user';
SELECT * FROM ALL_TAB_PRIVS WHERE GRANTEE = 'user';
This is really just the beginning. Again, for a look at all that the dictionary contains, run:
SELECT * FROM DICTIONARY;