OCP - Oracle9i Database Administrator Fundamentals 1 Exam Prep - Module 13: Maintaining Data Integrity

Practice 31: Implement data integrity constraints.

 

This practice covers the creation of referential integrity constraints.

 

 

INSTRUCTIONS

 

1.      Create the products table and add the constraints to the customers and orders table by running the SQL statements shown below.

 

 

 

SQL> CREATE TABLE products ( prod_code   NUMBER(6),

  2                          description VARCHAR2(30),

  3                          price       NUMBER(8,2)   )

  4      TABLESPACE users;

 

Table created.

SQL> ALTER TABLE customers

2               ADD ( CONSTRAINT customers_cust_code_pk

3               PRIMARY KEY(cust_code) DEFERRABLE INITIALLY IMMEDIATE

  4             USING INDEX TABLESPACE indx,

  5          CONSTRAINT custmoers_region_ck

  6     CHECK (region IN ('East', 'West', 'North', 'South')));

 

Table altered.

 

SQL> ALTER TABLE orders

  2    ADD ( CONSTRAINT orders_ord_id_pk PRIMARY KEY(ord_id)

  3             USING INDEX TABLESPACE indx,

  4    CONSTRAINT orders_cust_code_fk FOREIGN KEY (cust_code)

  5             REFERENCES customers (cust_code)

  6             DEFERRABLE INITIALLY IMMEDIATE,

  7          CONSTRAINT orders_date_of_dely_ck

  8             CHECK (date_of_dely >= ord_date));

 

Table altered.

SQL> ALTER TABLE products

  2   ADD CONSTRAINT products_prod_code_uk UNIQUE (prod_code)

  3       DEFERRABLE DISABLE;

 

Table altered.

 

 

2.      Run the following insert statements to add two rows in the products table.

 

 

SQL> connect system/manager

Connected.

SQL> INSERT INTO system.products

  2    VALUES(4000,'UNIX Monitor',3620);

 

1 row created.

 

SQL> INSERT INTO system.products

  2    VALUES(4000,'NT Monitor', 2400);

 

1 row created.

 

SQL> COMMIT;

 

 

 

3.      Enable the unique constraint on the PRODUCT table. Was it successful?

 

 

SQL> ALTER TABLE system.products

  2     ENABLE CONSTRAINT products_prod_code_uk;

ALTER TABLE system.products

*

ERROR at line 1:

ORA-02299: cannot validate (SYSTEM.PRODUCTS_PROD_CODE_UK) - duplicate keys found

 

 

 

4.      Query the data dictionary to check the names and types of indexes created to validate the constraints.

Hint: The indexes are only created for primary key and unique constraints that are enabled and the indexes will be created with the same name as the constraints.

 

 

SQL> SELECT index_name,table_name,uniqueness

 2  FROM   dba_indexes

 3  WHERE  index_name in

 4    ( SELECT constraint_name

 5      FROM   dba_constraints

 6  WHERE table_name IN ('PRODUCTS','ORDERS', 'CUSTOMERS') 

 7      AND    owner='SYSTEM'

 8      AND    constraint_type in ('P','U')) ;

 

INDEX_NAME                     TABLE_NAME UNIQUENES

------------------------------ ---------- ---------

CUSTOMERS_CUST_CODE_PK         CUSTOMERS  NONUNIQUE

ORDERS_ORD_ID_PK               ORDERS     UNIQUE

 

 

 

 

Practice 32: Maintain integrity constraints and obtaining constraint information from the data dictionary.

 

This practice covers maintaining referential integrity constraints.

 

INSTRUCTIONS

 

1.      Query the data dictionary to check for constraints, whether they are deferrable, and their status.

 

Hint: Use the DBA_CONSTRAINTS view to get this information.

 

 

SQL> COLUMN constraint_name FORMAT a25

SQL> COLUMN table_name      FORMAT a10

SQL> COLUMN constraint_type FORMAT a1

SQL> COLUMN deferrable      FORMAT a15

SQL> COLUMN status          FORMAT a10

SQL> SELECT constraint_name, table_name,

  2    constraint_type, deferrable, status

  3  FROM   dba_constraints

  4  WHERE  table_name IN

  5      ('PRODUCTS','ORDERS','CUSTOMERS')

  6  AND owner='SYSTEM';

 

CONSTRAINT_NAME        TABLE_NAME C DEFERRABLE     STATUS

---------------------- ---------- - -------------- --------

CUSTOMERS_REGION_CK    CUSTOMERS  C NOT DEFERRABLE ENABLED

CUSTOMERS_CUST_CODE_PK CUSTOMERS  P DEFERRABLE     ENABLED

ORDERS_CUST_CODE_FK    ORDERS     R DEFERRABLE     ENABLED

ORDERS_DATE_OF_DELY_CK ORDERS     C NOT DEFERRABLE ENABLED

ORDERS_ORD_ID_PK       ORDERS     P NOT DEFERRABLE ENABLED

PRODUCTS_PROD_CODE_UK  PRODUCTS   U DEFERRABLE     DISABLED

 

6 rows selected.

 

 

 

2.      Enable the constraint on the products table that was created in the previous exercise.  As you recall, there are duplicate primary key values for prod_code 4000 so you must enable the constraint using the  NOVALIDATE clause.  Query the data dictionary to verify the effect of the change .

 

 

SQL> ALTER TABLE system.products

 2  ENABLE NOVALIDATE CONSTRAINT products_prod_code_uk;

 

Table altered.

SQL> SELECT constraint_name, table_name,

  2      constraint_type, validated, status

  3      FROM   dba_constraints

  4      WHERE  table_name = 'PRODUCTS'

  5      AND    owner='SYSTEM';

 

CONSTRAINT_NAME       TABLE_NAME  C VALIDATED     STATUS

--------------------- ----------- - ------------- -------

PRODUCTS_PROD_CODE_UK PRODUCTS    U NOT VALIDATED ENABLED

 

 

 

3.      Test that the primary key constraint on the products table disables inserts that violate the change by trying to insert a row with a prod_code of 4000 as shown below.

 

 

SQL> INSERT INTO system.products

  2    VALUES(4000,'Monitor',3000);

INSERT INTO system.products

*

ERROR at line 1:

ORA-00001: unique constraint (SYSTEM.PRODUCTS_PROD_CODE_UK) violated

 

 

4.      Take the necessary steps to identify existing constraint violations in the PRODUCTS table, modify product codes as needed, and guarantee that all existing as well as new data does not violate the constraint. Remember that we used the NOVALIDATE clause when the constraint was enabled above since there were two rows that had prod_code 4000. (Assume that the table has several thousands of rows and it is too time-consuming to verify each row manually.)

 

      Hint: Use the following steps:

      A. Create the EXCEPTIONS table.

.

 

 

SQL> CONNECT system/manager

Connected.

SQL> @?/rdbms/admin/utlexcpt

 

 

 

      B. Run the command to enable the constraint and trap the exceptions.

 

 

SQL> ALTER TABLE system.products

  2      ENABLE CONSTRAINT products_prod_code_uk

  3      EXCEPTIONS INTO system.exceptions;

ALTER TABLE system.products

*

ERROR at line 1:

ORA-02299: cannot validate (SYSTEM.PRODUCTS_PROD_CODE_UK) - duplicate keys Found

 

 

 

      C. Use the ROWID in the EXCEPTIONS table to list the rows in the PRODUCTS table that violate the constraint.  Do not list LOB columns.

 

 

SQL> SELECT rowid, prod_code, description

  2     FROM   system.products

  3     WHERE  rowid IN

  4          ( SELECT row_id

  5       FROM   exceptions

  6           WHERE  table_name='PRODUCTS' ) ;

 

ROWID               PROD_CODE DESCRIPTION

------------------ ---------- ------------------------------

AAAIG0AAIAAACKCAAA       4000 UNIX Monitor

 AAAIG0AAIAAACKCAAB       4000 NT Monitor

 

 

 

      D. Rectify the errors.

 

 

SQL> UPDATE system.products

  2     SET prod_code='4001'

  3     WHERE rowid = ( SELECT max(row_id)

  4                     FROM   exceptions

  5                     WHERE  table_name='PRODUCTS' ) ;

 

1 row updated.

 

 

 

      E. Enable the constraint.

 

 

SQL> ALTER TABLE system.products

  2      ENABLE CONSTRAINT products_prod_code_uk

  3      EXCEPTIONS INTO system.exceptions;

 

Table altered.

 

 

 

5.      Query the data dictionary to check the names and types of indexes created to validate the constraints.  Note this query was run in the previous exercise and the output listed two indexes, one for the orders table and one for the customers table.  Why are two of the indexes created as nonunique?

 

 

SQL> SELECT index_name,table_name,uniqueness

 2     FROM   dba_indexes

 3     WHERE  index_name in

 4       ( SELECT constraint_name

 5         FROM   dba_constraints

 6           WHERE table_name IN

 7           ('PRODUCTS','ORDERS', 'CUSTOMERS') 

 8            AND    owner='SYSTEM'

 9            AND    constraint_type in ('P','U')) ;

 

 

INDEX_NAME              TABLE_NAME         UNIQUENES

----------------------- ------------------ ---------

CUSTOMERS_CUST_CODE_PK  CUSTOMERS          NONUNIQUE

ORDERS_ORD_ID_PK        ORDERS             UNIQUE

 PRODUCTS_PROD_CODE_UK   PRODUCTS           NONUNIQUE

 

 

 

6.      Insert the following rows into the orders and customer tables and observe the errors.  Why did the first insert fail but not the second?  Roll back the changes.

 

 

 

SQL> INSERT INTO system.orders

  2     VALUES (800,'01-JAN-98','J01',NULL);

INSERT INTO system.orders

*

ERROR at line 1:

ORA-02291: integrity constraint (SYSTEM.ORDERS_CUST_CODE_FK) violated – parent key not found

 

SQL> INSERT INTO system.customers

  2      VALUES ('J01','Sports Store', 'East');

 

1 row created.

 

SQL> rollback;

 

Rollback complete.

 

 

 

7.      In the step above, the insert for the customer table should have been executed first so that the order table's foreign key referencing the customer table would not have failed.  Insert the same two rows in the same order once again but first defer the constraints that are deferrable so that the constraints will only be checked at commit.

 

 

SQL> ALTER SESSION SET CONSTRAINTS=deferred;

 

Session altered.

 

SQL> INSERT INTO system.orders

  2     VALUES (800,'01-JAN-98','J01',NULL);

 

1 row created.

 

SQL> INSERT INTO system.customers

  2      VALUES ('J01','Sports Store', 'East');

 

1 row created.

 

SQL> commit;

 Commit complete.

 

 

1