A view is a logical representation of another table or combination of tables. A view derives its data from the tables on which it is based. These tables are called base tables. Base tables might in turn be actual tables or might be views themselves. All operations performed on a view actually affect the base table of the view. You can use views in almost the same way as tables. You can query, update, insert into, and delete from views, just as you can standard tables.
Views can provide a different representation (such as subsets or supersets) of the data that resides within other tables and views. Views are very powerful because they allow you to tailor the presentation of data to different types of users.
See Also:
Oracle Database Concepts for a more complete description of views
Creating Views
To create a view, you must meet the following requirements:
To create a view in your schema, you must have the CREATE VIEWprivilege. To create a view in another user's schema, you must have the CREATE ANY VIEW system privilege. You can acquire these privileges explicitly or through a role.
The owner of the view (whether it is you or another user) must have been explicitly granted privileges to access all objects referenced in the view definition. The owner cannot have obtained these privileges through roles. Also, the functionality of the view depends on the privileges of the view owner. For example, if the owner of the view has only the INSERT privilege for Scott's emp table, then the view can be used only to insert new rows into the emp table, not to SELECT, UPDATE, or DELETE rows.
If the owner of the view intends to grant access to the view to other users, the owner must have received the object privileges to the base objects with the GRANT OPTION or the system privileges with the ADMIN OPTION.
You can create views using the CREATE VIEW statement. Each view is defined by a query that references tables, materialized views, or other views. As with all subqueries, the query that defines a view cannot contain the FOR UPDATE clause.
SQL> conn scott/tiger;
Connected.
SQL> CREATE VIEW sales_staff AS
2 SELECT empno, ename, deptno
3 FROM emp
4 WHERE deptno = 10
5 WITH CHECK OPTION CONSTRAINT sales_staff_cnst;
View created.
SQL> select * from sales_staff;
EMPNO ENAME DEPTNO
---------- ---------- ----------
7782 CLARK 10
7839 KING 10
7934 MILLER 10
SQL> INSERT INTO sales_staff VALUES (7584, 'OSTER', 10);
1 row created.
SQL> INSERT INTO sales_staff VALUES (7591, 'WILLIAMS', 30);
INSERT INTO sales_staff VALUES (7591, 'WILLIAMS', 30)
*
ERROR at line 1:
ORA-01402: 视图 WITH CHECK OPTION where 子句违规
基本表多了一条记录
SQL> select count(*) from emp;
COUNT(*)
----------
15
The view could have been constructed specifying the WITH READ ONLY clause, which prevents any updates, inserts, or deletes from being done to the base table through the view. If no WITH clause is specified, the view, with some restrictions, is inherently updatable.
See Also:
Oracle Database SQL Reference for syntax and semantics of the CREATE VIEW statement
Join Views
You can also create views that specify more than one base table or view in the FROM clause. These are called join views. The following statement creates the division1_staff view that joins data from the emp and dept tables:
CREATE VIEW division1_staff AS
SELECT ename, empno, job, dname
FROM emp, dept
WHERE emp.deptno IN (10, 30)
AND emp.deptno = dept.deptno;
An updatable join view is a join view where UPDATE, INSERT, and DELETE operations are allowed. See "Updating a Join View" for further discussion.Expansion of Defining Queries at View Creation Time
When a view is created, Oracle Database expands any wildcard (*) in a top-level view query into a column list. The resulting query is stored in the data dictionary; any subqueries are left intact. The column names in an expanded column list are enclosed in quote marks to account for the possibility that the columns of the base object were originally entered with quotes and require them for the query to be syntactically correct.
As an example, assume that the dept view is created as follows:
CREATE VIEW dept AS SELECT * FROM scott.dept;
The database stores the defining query of the dept view as:
SELECT "DEPTNO", "DNAME", "LOC" FROM scott.dept;
Views created with errors do not have wildcards expanded. However, if the view is eventually compiled without errors, wildcards in the defining query are expanded.
Creating Views with Errors
If there are no syntax errors in a CREATE VIEW statement, the database can create the view even if the defining query of the view cannot be executed. In this case, the view is considered "created with errors." For example, when a view is created that refers to a nonexistent table or an invalid column of an existing table, or when the view owner does not have the required privileges, the view can be created anyway and entered into the data dictionary. However, the view is not yet usable.
Oracle视图非常强大的功能之一在于其可以创建一个带有错误的视图。比如说视图里的字段在基表里不存在,该视图仍然可以创建成功,但是非法的且无法执行。当基表里加入了该字段,或者说某个字段修改成视图里的该字段名称,那么视图马上就可以成为合法的。
To create a view with errors, you must include the FORCE clause of the CREATE VIEW statement.
CREATE FORCE VIEW AS ...;
By default, views with errors are created as INVALID. When you try to create such a view, the database returns a message indicating the view was created with errors. If conditions later change so that the query of an invalid view can be executed, the view can be recompiled and be made valid (usable). For information changing conditions and their impact on views, see "Managing Object Dependencies".
Replacing Views
To replace a view, you must have all of the privileges required to drop and create a view. If the definition of a view must change, the view must be replaced; you cannot use an ALTER VIEW statement to change the definition of a view. You can replace views in the following ways:
You can drop and re-create the view.
Caution:
When a view is dropped, all grants of corresponding object privileges are revoked from roles and users. After the view is re-created, privileges must be regranted.
You can redefine the view with a CREATE VIEW statement that contains the OR REPLACE clause. The OR REPLACE clause replaces the current definition of a view and preserves the current security authorizations. For example, assume that you created the sales_staff view as shown earlier, and, in addition, you granted several object privileges to roles and other users. However, now you need to redefine the sales_staff view to change the department number specified in the WHERE clause. You can replace the current version of the sales_staff view with the following statement:
CREATE OR REPLACE VIEW sales_staff AS
SELECT empno, ename, deptno
FROM emp
WHERE deptno = 30
WITH CHECK OPTION CONSTRAINT sales_staff_cnst;
Before replacing a view, consider the following effects:
Replacing a view replaces the view definition in the data dictionary. All underlying objects referenced by the view are not affected.
If a constraint in the CHECK OPTION was previously defined but not included in the new view definition, the constraint is dropped.
All views dependent on a replaced view become invalid (not usable). In addition, dependent PL/SQL program units may become invalid, depending on what was changed in the new version of the view. For example, if only the WHERE clause of the view changes, dependent PL/SQL program units remain valid. However, if any changes are made to the number of view columns or to the view column names or data types, dependent PL/SQL program units are invalidated. See "Managing Object Dependencies" for more information on how the database manages such dependencies.
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 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:
基于视图上的DML操作的条件限制
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.
视图定义包含SET或 DISTINCT等操作符,group by字句,或者组函数,那么就不能通过该视图对基本表做DML的操作。
2.If a view is defined with WITH CHECK OPTION, 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.视图定义时含有WITH CHECK OPTION字句,如果插入或更新的行不能满足视图创建时的条件,不能插入或更新。
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 30 to be inserted into, or updated in, the emp table. Alternatively, assume that the sales_staff view is defined by the following statement (that is, excluding the deptno column):
假设视图创建时去掉deptno字段。
CREATE VIEW sales_staff AS
SELECT empno, ename
FROM emp
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 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 shown in the following table. Views that meet these criteria are said to be inherently updatable.
Rule Description
General RuleAny INSERT, UPDATE, or DELETE operation on a join view can modify only one underlying base table at a time.一次只修改一个基表。
UPDATE RuleAll updatable columns of a join view must map to columns of a key-preserved table. See "Key-Preserved Tables" for a discussion of key-preserved tables. If the view is defined with the WITH CHECK OPTION clause, then all join columns and all columns of repeated tables are not updatable.
连接视图中所有课更新的列都可以映射到key-preserved table。如果视图定义时指定了WITH CHECK OPTION 字句,所有重复的列都不可更新。
DELETE RuleRows from a join view can be deleted as long as there is exactly one key-preserved table in the join. The key preserved table can be repeated in the FROM clause. 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 RuleAn 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. See "Using the UPDATABLE_ COLUMNS Views" for descriptions of these views.
Note:
There are some additional restrictions and conditions that can affect whether a join view is inherently updatable. Specifics are listed in the description of the CREATE VIEW statement in the Oracle Database SQL Reference.
If a view is not inherently updatable, it can be made updatable by creating an INSTEAD OF trigger on it. This is described in Oracle Database Application Developer's Guide - Fundamentals.
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 that reference views, see the Oracle Database Performance Tuning Guide.
Examples illustrating the rules for inherently updatable join views, and a discussion of key-preserved tables, are presented in following 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');
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 keys 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 RESEARCH DALLAS
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';
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.
See Also:
Oracle Database SQL Reference for syntax and additional information about the UPDATE statement
DELETE Statements
You can delete from a join view provided there is one and only one key-preserved table in the join. The key-preserved table can be repeated in the FROM clause.
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.
In the following view, a DELETE operation is permitted, because although there are two key-preserved tables, they are the same table. That is, the key-preserved table is repeated. In this case, the delete statement operates on the first table in the FROM list (e1, in this example):
CREATE VIEW emp_emp AS
SELECT e1.ename, e2.empno, e2.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, 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;
See Also:
Oracle Database SQL Reference for syntax and additional information about the DELETE statement
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 join 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.
See Also:
Oracle Database SQL Reference for syntax and additional information about the INSERT statement
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 e, dept 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 table of emp_dept_oj1 are modifiable through the view, because emp 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 e, dept d
WHERE e.deptno (+) = d.deptno;
The following 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 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;
CREATE VIEW emp_dept_oj1 AS
SELECT e.*, Loc, d.dname
FROM emp_v e, dept 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 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
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 is no longer a key-preserved table.
If you are in doubt whether a view is modifiable, then you can select from the USER_UPDATABLE_COLUMNS view to see if it is. For example:
SELECT owner, table_name, column_name, updatable FROM USER_UPDATABLE_COLUMNS
WHERE TABLE_NAME = 'EMP_DEPT_VIEW';
This returns output similar to the following:
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.
Using the UPDATABLE_ COLUMNS Views
The views described in the following table can assist you to identify inherently updatable join views.
View Description
DBA_UPDATABLE_COLUMNS Shows all columns in all tables and views that are modifiable.
ALL_UPDATABLE_COLUMNS Shows all columns in all tables and views accessible to the user that are modifiable.
USER_UPDATABLE_COLUMNS Shows all columns in all tables and views in the user's schema that are modifiable.
The updatable columns in view emp_dept are shown below.
SELECT COLUMN_NAME, UPDATABLE
FROM USER_UPDATABLE_COLUMNS
WHERE TABLE_NAME = 'EMP_DEPT';
COLUMN_NAME UPD
------------------------------ ---
EMPNO YES
ENAME YES
DEPTNO YES
SAL YES
DNAME NO
LOC NO
6 rows selected.
See Also:
Oracle Database Reference for complete descriptions of the updatable column views
Altering Views
You use the ALTER VIEW statement only to explicitly recompile a view that is invalid. If you want to change the definition of a view, see "Replacing Views".
The ALTER VIEW statement lets you locate recompilation errors before run time. To ensure that the alteration does not affect the view or other objects that depend on it, you can explicitly recompile a view after altering one of its base tables.
To use the ALTER VIEW statement, the view must be in your schema, or you must have the ALTER ANY TABLE system privilege.
See Also:
Oracle Database SQL Reference for syntax and additional information about the ALTER VIEW statement
Dropping Views
You can drop any view contained in your schema. To drop a view in another user's schema, you must have the DROP ANY VIEW system privilege. Drop a view using the DROP VIEW statement. For example, the following statement drops the emp_dept view:
DROP VIEW emp_dept;
See Also:
Oracle Database SQL Reference for syntax and additional information about the DROP VIEW statement