Oracle 10g Tutorials- Updating Views

Oracle 10g Free Training - Updating Views

This tutorial teachs you

  • how to use Views in Queries along with Restrictions on DML operations for Views.
  • how to update a join View along with rules for updatable join views.
  • how to use DML Statements on Join Views
  • how to Update Views that Involve Outer Joins

Using Views in Queries

To issue a query or an INSERT, UPDATE, or DELETE statement against a view, you must have the SELECT, INSERT, UPDATE, or DELETE object privilege for the view, respectively, either explicitly or through a role.

Views can be queried in the same manner as tables. For example, to query the Division1_staff view, enter a valid SELECT statement that references the view:

SELECT * FROM Division1_staff;

ENAME

EMPNO

JOB

DNAME

CLARK

7782

MANAGER

ACCOUNTING

KING

7839

PRESIDENT

ACCOUNTING

MILLER

7934

CLERK

ACCOUNTING

ALLEN

7499

SALESMAN

SALES

WARD

7521

SALESMAN

SALES

JAMES

7900

CLERK

SALES

TURNER

7844

SALESMAN

SALES

MARTIN

7654

SALESMAN

SALES

BLAKE

7698

MANAGER

SALES

With some restrictions, rows can be inserted into, updated in, or deleted from a base table using a view. The following statement inserts a new row into the emp_tab table using the sales_staff view:

INSERT INTO Sales_staff
VALUES (7954, 'OSTER', 30);

Restrictions on DML operations for views use the following criteria in the order listed:

1. If a view is defined by a query that contains SET or DISTINCT operators, a GROUP BY clause, or a group function, then rows cannot be inserted into, updated in, or deleted from the base tables using the view.

2. If a view is defined with WITH CHECK OPTION, then a row cannot be inserted into, or updated in, the base table (using the view), if the view cannot select the row from the base table.

3. If a NOT NULL column that does not have a DEFAULT clause is omitted from the view, then a row cannot be inserted into the base table using the view.

4. If the view was created by using an expression, such as DECODE(deptno, 10, "SALES", ...), then rows cannot be inserted into or updated in the base table using the view.

The constraint created by WITH CHECK OPTION of the sales_staff view only allows rows that have a department number of 10 to be inserted into, or updated in, the emp_tab table. Alternatively, assume that the sales_staff view is defined by the following statement (that is, excluding the deptno column):

CREATE VIEW Sales_staff AS
SELECT Empno, Ename
FROM Emp_tab
WHERE Deptno = 10
WITH CHECK OPTION CONSTRAINT Sales_staff_cnst;

Considering this view definition, you can update the empno or ename fields of existing records, but you cannot insert rows into the emp_tab table through the sales_staff view because the view does not let you alter the deptno field. If you had defined a DEFAULT value of 10 on the deptno field, then you could perform inserts.

When a user attempts to reference an invalid view, the database returns an error message to the user:

ORA-04063: view 'view_name' has errors

This error message is returned when a view exists but is unusable due to errors in its query (whether it had errors when originally created or it was created successfully but became unusable later because underlying objects were altered or dropped).

Updating a Join View

An updatable join view (also referred to as a modifiable join view) is a view that contains more than one table in the top-level FROM clause of the SELECT statement, and is not restricted by the WITH READ ONLY clause.

The rules for updatable join views are as follows. Views that meet this criteria are said to be inherently updatable.

Rule

Description

General Rule

Any INSERT, UPDATE, or DELETE operation on a join view can modify only one underlying base table at a time.

UPDATE Rule

All updatable columns of a join view must map to columns of a key-preserved table. If the view is defined with the WITH CHECK OPTION clause, then all join columns and all columns of repeated tables are not updatable.

DELETE Rule

Rows from a join view can be deleted as long as there is exactly one key-preserved table in the join. If the view is defined with the WITH CHECK OPTION clause and the key preserved table is repeated, then the rows cannot be deleted from the view.

INSERT Rule

An INSERT statement must not explicitly or implicitly refer to the columns of a non-key-preserved table. If the join view is defined with the WITH CHECK OPTION clause, INSERT statements are not permitted.

There are data dictionary views that indicate whether the columns in a join view are inherently updatable.

Note:

There are some additional restrictions and conditions which can affect whether a join view is inherently updatable.

If a view is not inherently updatable, it can be made updatable by creating an INSTEAD OF trigger on it.

Additionally, if a view is a join on other nested views, then the other nested views must be mergeable into the top level view. For a discussion of mergeable and unmergeable views, and more generally, how the optimizer optimizes statements referencing views.

Examples illustrating the rules for inherently updatable join views, and a discussion of key-preserved tables, are presented in succeeding sections. The examples in these sections work only if you explicitly define the primary and foreign keys in the tables, or define unique indexes. The following statements create the appropriately constrained table definitions for emp and dept.

CREATE TABLE dept (
deptno NUMBER(4) PRIMARY KEY,
dname VARCHAR2(14),
loc VARCHAR2(13));

CREATE TABLE emp (
empno NUMBER(4) PRIMARY KEY,
ename VARCHAR2(10),
job VARCHAR2(9),
mgr NUMBER(4),
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2),
FOREIGN KEY (DEPTNO) REFERENCES DEPT(DEPTNO));

You could also omit the primary and foreign key constraints listed in the preceding example, and create a UNIQUE INDEX on dept (deptno) to make the following examples work.

The following statement created the emp_dept join view which is referenced in the examples:

CREATE VIEW emp_dept AS
SELECT emp.empno, emp.ename, emp.deptno, emp.sal, dept.dname, dept.loc
FROM emp, dept
WHERE emp.deptno = dept.deptno
AND dept.loc IN ('DALLAS', 'NEW YORK', 'BOSTON');

The image cannot be displayed, because it contains errors.

Figure 17. Creating updateable join views

Key-Preserved Tables

The concept of a key-preserved table is fundamental to understanding the restrictions on modifying join views. A table is key preserved if every key of the table can also be a key of the result of the join. So, a key-preserved table has its keys preserved through a join.

Note:
It is not necessary that the key or keys of a table be selected for it to be key preserved. It is sufficient that if the key or keys were selected, then they would also be key(s) of the result of the join.

The key-preserving property of a table does not depend on the actual data in the table. It is, rather, a property of its schema. For example, if in the emp table there was at most one employee in each department, then deptno would be unique in the result of a join of emp and dept, but dept would still not be a key-preserved table.

If you SELECT all rows from emp_dept, the results are:

EMPNO

ENAME

DEPTNO

DNAME

LOC

7782

CLARK

10

ACCOUNTING

NEW YORK

7839

KING

10

ACCOUNTING

NEW YORK

7934

MILLER

10

ACCOUNTING

NEW YORK

7369

SMITH

20

RESEARCH

DALLAS

7876

ADAMS

20

RESEARCH

DALLAS

7902

FORD

20

RESEARCH

DALLAS

7788

SCOTT

20

RESEARCH

DALLAS

7566

JONES

20

RESEARCHDALLAS


8 rows selected.

In this view, emp is a key-preserved table, because empno is a key of the emp table, and also a key of the result of the join. dept is not a key-preserved table, because although deptno is a key of the dept table, it is not a key of the join.

DML Statements and Join Views

The general rule is that any UPDATE, DELETE, or INSERT statement on a join view can modify only one underlying base table. The following examples illustrate rules specific to UPDATE, DELETE, and INSERT statements.

UPDATE Statements

The following example shows an UPDATE statement that successfully modifies the emp_dept view:

UPDATE emp_dept
SET sal = sal * 1.10
WHERE deptno = 10;

The following UPDATE statement would be disallowed on the emp_dept view:

UPDATE emp_dept
SET loc = 'BOSTON'
WHERE ename = 'SMITH';

The image cannot be displayed, because it contains errors.

Figure 18. Updating join views

This statement fails with an error (ORA-01779 cannot modify a column which maps to a non key-preserved table), because it attempts to modify the base dept table, and the dept table is not key preserved in the emp_dept view.

In general, all updatable columns of a join view must map to columns of a key-preserved table. If the view is defined using the WITH CHECK OPTION clause, then all join columns and all columns taken from tables that are referenced more than once in the view are not modifiable.

So, for example, if the emp_dept view were defined using WITH CHECK OPTION, the following UPDATE statement would fail:

UPDATE emp_dept
SET deptno = 10
WHERE ename = 'SMITH';

The statement fails because it is trying to update a join column.

DELETE Statements

You can delete from a join view provided there is one and only one key-preserved table in the join.

The following DELETE statement works on the emp_dept view:

DELETE FROM emp_dept
WHERE ename = 'SMITH';

This DELETE statement on the emp_dept view is legal because it can be translated to a DELETE operation on the base emp table, and because the emp table is the only key-preserved table in the join.

If you were to create the following view, a DELETE operation could not be performed on the view because both e1 and e2 are key-preserved tables:

CREATE VIEW emp_emp AS
SELECT e1.ename, e2.empno, deptno
FROM emp e1, emp e2
WHERE e1.empno = e2.empno;

If a view is defined using the WITH CHECK OPTION clause and the key-preserved table is repeated, then rows cannot be deleted from such a view.

CREATE VIEW emp_mgr AS
SELECT e1.ename, e2.ename mname
FROM emp e1, emp e2
WHERE e1.mgr = e2.empno
WITH CHECK OPTION;

The image cannot be displayed, because it contains errors.

Figure 19. Deleting from views

No deletion can be performed on this view because the view involves a self-join of the table that is key preserved.

INSERT Statements

The following INSERT statement on the emp_dept view succeeds:

INSERT INTO emp_dept (ename, empno, deptno)
VALUES ('KURODA', 9010, 40);

This statement works because only one key-preserved base table is being modified (emp), and 40 is a valid deptno in the dept table (thus satisfying the FOREIGN KEY integrity constraint on the emp table).

An INSERT statement, such as the following, would fail for the same reason that such an UPDATE on the base emp table would fail: the FOREIGN KEY integrity constraint on the emp table is violated (because there is no deptno 77).

INSERT INTO emp_dept (ename, empno, deptno)
VALUES ('KURODA', 9010, 77);

The following INSERT statement would fail with an error (ORA-01776 cannot modify more than one base table through a view):

INSERT INTO emp_dept (empno, ename, loc)
VALUES (9010, 'KURODA', 'BOSTON');

An INSERT cannot implicitly or explicitly refer to columns of a non-key-preserved table. If the join view is defined using the WITH CHECK OPTION clause, then you cannot perform an INSERT to it.

Updating Views that Involve Outer Joins

Views that involve outer joins are modifiable in some cases. For example:

CREATE VIEW Emp_dept_oj1 AS
SELECT Empno, Ename, e.Deptno, Dname, Loc
FROM Emp_tab e, Dept_tab d
WHERE e.Deptno = d.Deptno (+);

The statement:

SELECT * FROM Emp_dept_oj1;

Results in:

EMPNO

ENAME

DEPTNO

DNAME

LOC

7369

SMITH

40

OPERATIONS

BOSTON

7499

ALLEN

30

SALES

CHICAGO

7566

JONES

20

RESEARCH

DALLAS

7654

MARTIN

30

SALES

CHICAGO

7698

BLAKE

30

SALES

CHICAGO

7782

CLARK

10

ACCOUNTING

NEW YORK

7788

SCOTT

20

RESEARCH

DALLAS

7839

KING

10

ACCOUNTING

NEW YORK

7844

TURNER

30

SALES

CHICAGO

7876

ADAMS

20

RESEARCH

DALLAS

7900

JAMES

30

SALES

CHICAGO

7902

FORD

20

RESEARCH

DALLAS

7934

MILLER

10

ACCOUNTING

NEW YORK

7521

WARD

30

SALES

CHICAGO

14 rows selected.

Columns in the base emp_tab table of emp_dept_oj1 are modifiable through the view, because emp_tab is a key-preserved table in the join.

The following view also contains an outer join:

CREATE VIEW Emp_dept_oj2 AS
SELECT e.Empno, e.Ename, e.Deptno, d.Dname, d.Loc
FROM Emp_tab e, Dept_tab d
WHERE e.Deptno (+) = d.Deptno;

The statement:

SELECT * FROM Emp_dept_oj2;

Results in:

EMPNO

ENAME

DEPTNO

DNAME

LOC

7782

CLARK

10

ACCOUNTING

NEW YORK

7839

KING

10

ACCOUNTING

NEW YORK

7934

MILLER

10

ACCOUNTING

NEW YORK

7369

SMITH

20

RESEARCH

DALLAS

7876

ADAMS

20

RESEARCH

DALLAS

7902

FORD

20

RESEARCH

DALLAS

7788

SCOTT

20

RESEARCH

DALLAS

7566

JONES

20

RESEARCH

DALLAS

7499

ALLEN

30

SALES

CHICAGO

7698

BLAKE

30

SALES

CHICAGO

7654

MARTIN

30

SALES

CHICAGO

7900

JAMES

30

SALES

CHICAGO

7844

TURNER

30

SALES

CHICAGO

7521

WARD

30

SALES

CHICAGO




OPERATIONS

BOSTON

15 rows selected.

In this view, emp_tab is no longer a key-preserved table, because the empno column in the result of the join can have nulls (the last row in the preceding SELECT statement). So, UPDATE, DELETE, and INSERT operations cannot be performed on this view.

In the case of views containing an outer join on other nested views, a table is key preserved if the view or views containing the table are merged into their outer views, all the way to the top. A view which is being outer-joined is currently merged only if it is "simple." For example:

SELECT Col1, Col2, ... FROM T;

The select list of the view has no expressions, and there is no WHERE clause.

Consider the following set of views:

CREATE VIEW Emp_v AS
SELECT Empno, Ename, Deptno
FROM Emp_tab;

CREATE VIEW Emp_dept_oj1 AS
SELECT e.*, Loc, d.Dname
FROM Emp_v e, Dept_tab d
WHERE e.Deptno = d.Deptno (+);

In these examples, emp_v is merged into emp_dept_oj1 because emp_v is a simple view, and so emp_tab is a key-preserved table. But if emp_v is changed as follows:

CREATE VIEW Emp_v_2 AS
SELECT Empno, Ename, Deptno
FROM Emp_tab
WHERE Sal > 1000;

Then, because of the presence of the WHERE clause, emp_v_2 cannot be merged into emp_dept_oj1, and hence emp_tab is no longer a key-preserved table.

If you are in doubt whether a view is modifiable, then you can SELECT from the view USER_UPDATABLE_COLUMNS to see if it is. For example

SELECT * FROM USER_UPDATABLE_COLUMNS WHERE TABLE_NAME = 'EMP_DEPT_VIEW';

This might return:

OWNER
TABLE_NAME
COLUMN_NAM
UPD
SCOTT
EMP_DEPT_V
EMPNO
NO
SCOTT
EMP_DEPT_V
ENAME
NO
SCOTT
EMP_DEPT_V
DEPTNO
NO
SCOTT
EMP_DEPT_V
DNAME
NO
SCOTT
EMP_DEPT_V
LOC
NO

5 rows selected.


Recent Tutorials

Subscribe to oracle tutorials

Enter your email address:

Delivered by FeedBurner

Blog Archive

Visitors

DigNow.org