How to Query Constraints from the Data Dictionary

Find every constraint of a table, what each foreign key references, and which tables point to a table, with USER_CONSTRAINTS.

Before changing a table, you often need to know its constraints: which columns form the key, which tables point to it, what a check enforces. USER_CONSTRAINTS and USER_CONS_COLUMNS hold all of that, and a few joins answer questions such as "what does this foreign key reference" and "who references this table".

Code for This Guide

The main examples are in the examples/dictionary folder of the Oracle Database 26ai code repository on GitHub, each with its output. They use NIMBUS, the sample schema of a fictional airline, which you can install with the scripts in the setup/nimbus folder.

They come from Oracle Database 26ai SQL and PL/SQL Book.

The Views

ViewHolds
USER_CONSTRAINTSOne row per constraint: name, table, type, status, and for foreign keys R_CONSTRAINT_NAME, the key it references
USER_CONS_COLUMNSThe columns of each constraint, with their position

CONSTRAINT_TYPE is P for primary key, U for unique, R for foreign key (referential), and C for check, which includes NOT NULL.

All Constraints of a Table

Example:

-- every constraint of TICKETS, with its type and, for checks, the condition
select constraint_name,
       decode(constraint_type, 'P', 'primary key', 'U', 'unique', 'R', 'foreign key',
                               'C', 'check', constraint_type) as kind,
       status, search_condition_vc as condition
from   user_constraints
where  table_name = 'TICKETS'
order  by constraint_type, constraint_name;

Output:

CONSTRAINT_NAME       KIND           STATUS     CONDITION
_____________________ ______________ __________ ___________________________________
SYS_C0016151          check          ENABLED    "TICKET_ID" IS NOT NULL
SYS_C0016152          check          ENABLED    "BOOKING_ID" IS NOT NULL
SYS_C0016153          check          ENABLED    "FLIGHT_ID" IS NOT NULL
SYS_C0016154          check          ENABLED    "CABIN" IS NOT NULL
SYS_C0016155          check          ENABLED    "SEAT_NO" IS NOT NULL
SYS_C0016156          check          ENABLED    "FARE" IS NOT NULL
SYS_C0016157          check          ENABLED    "CHECKED_IN" IS NOT NULL
TICKETS_CABIN_CK      check          ENABLED    cabin in ('BUSINESS', 'ECONOMY')
TICKETS_PK            primary key    ENABLED
TICKETS_BOOKING_FK    foreign key    ENABLED
TICKETS_FLIGHT_FK     foreign key    ENABLED

11 rows selected.

The NOT NULL constraints have system names such as SYS_C0016151, while the others were named when the table was created, which makes their error messages much easier to read. SEARCH_CONDITION_VC shows each check's condition as text.

What a Foreign Key References

Joining a foreign key through R_CONSTRAINT_NAME to the key it references, and both to their columns, shows the full relationship.

Example:

-- the foreign keys of FLIGHTS, and the tables they point to
select c.constraint_name, cc.column_name, p.table_name as references_table,
       pc.column_name as references_column
from   user_constraints c
join   user_cons_columns cc on cc.constraint_name = c.constraint_name
join   user_constraints p   on p.constraint_name  = c.r_constraint_name
join   user_cons_columns pc on pc.constraint_name = p.constraint_name
where  c.table_name = 'FLIGHTS' and c.constraint_type = 'R'
order  by c.constraint_name;

Output:

CONSTRAINT_NAME        COLUMN_NAME    REFERENCES_TABLE    REFERENCES_COLUMN
______________________ ______________ ___________________ ____________________
FLIGHTS_AIRCRAFT_FK    TAIL_NUMBER    AIRCRAFT            TAIL_NUMBER
FLIGHTS_ROUTE_FK       ROUTE_ID       ROUTES              ROUTE_ID

Which Tables Reference a Table

The reverse question, needed before deleting rows or dropping a table, finds the foreign keys whose R_CONSTRAINT_NAME is the table's primary key.

Example:

-- which tables reference FLIGHTS?
select c.table_name, c.constraint_name, c.delete_rule
from   user_constraints c
where  c.r_constraint_name in (select constraint_name from user_constraints
                               where  table_name = 'FLIGHTS' and constraint_type = 'P')
order  by c.table_name;

Output:

TABLE_NAME          CONSTRAINT_NAME      DELETE_RULE
___________________ ____________________ ______________
CREW_ASSIGNMENTS    CREW_FLIGHT_FK       NO ACTION
REVIEWS             REVIEWS_FLIGHT_FK    NO ACTION
TICKETS             TICKETS_FLIGHT_FK    NO ACTION

Three tables reference FLIGHTS, all with DELETE_RULE NO ACTION, so a flight with tickets, crew, or reviews cannot be deleted.

Things to Know

  • ALL_CONSTRAINTS and ALL_CONS_COLUMNS do the same across schemas, with OWNER and R_OWNER columns; join on both name and owner there.
  • STATUS and VALIDATED show whether a constraint is enabled and whether existing rows were checked.
  • Name your constraints when creating tables; system names tell nothing in an error message.

Related Guides

Conclusion

USER_CONSTRAINTS and USER_CONS_COLUMNS describe every constraint of your tables. Join a foreign key to the key it references through R_CONSTRAINT_NAME, find the tables that reference a table the same way in reverse, and read check conditions from SEARCH_CONDITION_VC.

Get more Vinish.dev tutorials on Google

See my articles more often when you search Google.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted