Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, parker.

Asked: May 19, 2001 - 6:53 pm UTC

Last updated: March 09, 2004 - 4:47 pm UTC

Version: 8.1.7

Viewed 10K+ times! This question is

You Asked


Tom

What is the needs to make a constraint deferred?
Can you also give the mail difference between a immediate and a deferred constraint.

Is there a special syntax to make a constraint immediate or deferred?
what is the default?

Thanks

and Tom said...

The deferrable constraint was introduces for a process that makes a bunch of updates to a lot of tables that temporarily makes the tables "inconsistent" but by the time its done -- every thing will be OK.

Lets say you were writing a batch process. It would process input files that told it to INSERT/UPDATE/DELETE employee and dept records. It is going to do this work in some order (maybe process ALL emp changes and then ALL dept changes for example). During the processing it is told to:

DELETE employee 1 (who is the manager of employee 2)
UPDATE employee 2 setting the manager to employee 3, department to 50
INSERT employee 3 into deptartment 50

INSERT department 50
DELETE department 10 (employee 1 and 2 were the only ones in dept 10)

At the END of the process -- all of the tables are OK. Individually however -- each statement would leave the database in an inconsistent state. If you delete employee 1 -- you have an orphaned foreign key in the employee table UNTIL you create employee 3 but employee 3 is in dept 50 which doesn't exist until you create it.

So, during this process the database is inconsistent -- at the end it is OK. A common use of this might be to do an update cascade. Say you wanted to change dept = 10 to dept = 11. If you update the DEPT table first -- it would normally fail since the emp table has employees in dept 10. If you tried the emp table first, it would fail since dept = 11 doesn't exist. deferrable constraints permit this to take place naturally. the constraints are validates upon COMMIT.



the main difference between an immediate and deferred constraint is quite simple: an immediate constraint is validated after each statement, a deferred constraint is validated upon commit (or upon setting all constraints to immediate).


Search for deferrable on my site to see examples. immediate is the default, you have to define constraints as deferrable in the CREATE or ALTER statement.


Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

PURUSH, May 23, 2001 - 5:23 am UTC

Baisc funda but very useful

Changing NON-DEFERRABLE/DEFERRABLE "type" of constraints

Michal, March 09, 2004 - 4:47 pm UTC

Does it mean that once you created a constraint NON-deferrable you have bad luck and you cannot do such a processing (allow a temporary inconsistant state)?

Indeed, yes it does as I looked it up within Oracle documentation:
------------------
DEFERRABLE Clause
The DEFERRABLE and NOT DEFERRABLE parameters indicate whether or not, in subsequent transactions, constraint checking can be deferred until the end of the transaction using the SET CONSTRAINT(S) statement. If you omit this clause, then the default is NOT DEFERRABLE.

Specify NOT DEFERRABLE to indicate that in subsequent transactions you cannot use the SET CONSTRAINT[S] clause to defer checking of this constraint until the transaction is committed. The checking of a NOT DEFERRABLE constraint can never be deferred to the end of the transaction.

Specify DEFERRABLE to indicate that in subsequent transactions you can use the SET CONSTRAINT[S] clause to defer checking of this constraint until after the transaction is committed. This setting in effect lets you disable the constraint temporarily while making changes to the database that might violate the constraint until all the changes are complete.

You cannot alter a constraint's deferrability. That is, whether you specify either of these parameters, or make the constraint NOT DEFERRABLE implicitly by specifying neither of them, you cannot specify this clause in an ALTER TABLE statement. You must drop the constraint and re-create it.
------------------