管理视图:
创建视图
可用CREATE VIEW 语句创建视图 每个视图是由参考表的查询物化的视图或其他视图定义的就像所有的子查询 定义视图的查询不能包含FOR UPDATE子句
CREATE VIEW sales_staff AS
SELECT empno, ename, deptno FROM emp WHERE deptno = 10
WITH CHECK OPTION CONSTRAINT sales_staff_cnst;
定义CHECK OPTION视图的查询仅参考部门号为的行此外创建带有约束名字为sales_staff_cnst的视图针对该视图发布的INSERT 和UPDATE 语句不能产生该视图不能选择的行
INSERT INTO sales_staff VALUES (7584, 'OSTER', 10); --可以成功的Insert
INSERT INTO sales_staff VALUES (7591, 'WILLIAMS', 30);
--失败,只能Insert或update用sales_staff 视图where deptno = 10的记录
可选的 可用指定WITH READ ONLY 子句的方式构造视图 从而防止通过视图对表的任何更改 插入或删除 如果没有指定WITH 子句 带有某些限制的视图 自然是可更新的.
联结视图
在FROM 子句中 也可以指定多个基础表或视图来创建视图 这种视图就叫联结视图
CREATE VIEW division1_staff AS SELECT ename, empno, job, dname FROM emp, dept
WHERE emp.deptno IN (10, 30) AND emp.deptno = dept.deptno;
--创建联结emp 表和dept 表中数据的division1_staff 视图
创建带错误视图
要能创建带有错误的视图 必须在CREATE VIEW 语句中包括FORCE 选项
CREATE FORCE VIEW AS select * from employee
--此时的表employee不存在,用FORCE关键字可以先建好视图,后再建表.
更新联结视图
如果在表中明确地定义了主键和外键 或者定义了唯一的索引 下面的例子才能工作
下面是针对emp 和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) );
下面的语句创建例子中所参照的emp_dept 联结视图
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');
键预留表的概念是理解修改联结视图的限制的基础,如果表中的每个键也是联结的结果键,则该表是键预留的,所以一个键预留表通过联结预留它自己的键
注意 不需要将表中一个或多个键选择作为预留键 选择了键就可以了 它们也就作为该联结的结果的键了
表中的键的预留属性不依赖于表中的实际数据 它更是其模式的属性 例如 如果在 emp 表中每个部门最多有一名雇员 那么deptno 在emp 和dept 的联结结果中是唯一的 但 dept 还不是一个键预留表
如果从emp_dept 中SELECT 所有行 结果如下
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.
在此视图中 emp 是键预留表 因为empno 是emp 表的一个键 也是一个联结的结果,键 dept 不是键预留表 因为尽管deptno 是dept 表的一个键 但它不是一个联结的键
DML 语句和联结视图
一般的规则是 联结视图上的任何UPDATE,DELETE 或者INSERT 语句仅能修改一个下层基础表,下面的例子说明了针对UPDATE,DELETE 和INSERT 语句的规则
UPDATE emp_dept SET sal = sal * 1.10 WHERE deptno = 10;
-- 正确修改emp_dept 视图的UPDATE 语句
UPDATE emp_dept SET loc = 'BOSTON' WHERE ename = 'SMITH';
--该语句失败了产生一个错误 ORA-01779 cannot modify a column which maps to a non key-preserved table不能修改映射到非键预留表中的列,因为该语句试图修改基础dept表 但dept 表不是emp_dept 视图中的键预留表
联结视图中的所有可更新的列必须映射到键预留表中列 如果视图是使用WITH CHECK OPTION子句定义的,那么所有联结的列和所有从在视图中参照多次的表中取出的列都是不可修改的
所以 例如 如果emp_dept 视图是使用WITH CHECK OPTION 子句定义的 下面的 UPDATE 语句会失败
UPDATE emp_dept SET deptno = 10 WHERE ename = 'SMITH'--失败是因为试图更新一个联结的列
DELETE 语句能够通过所提供的在联结中有一个而且仅有一个键预留表的联结视图进行删除工作
下面的DELETE 语句在emp_dept 视图上工作
DELETE FROM emp_dept WHERE ename = 'SMITH';
--DELETE 语句是合法的 因为该语句能被转换成在基础emp表上的DELETE 操作 并且emp 表是该联结中的唯一的键预留表
如果假使创建了下面的视图 则在该视图上就不能执行操作 因为 和二者都是键预留表
CREATE VIEW emp_emp AS
SELECT e1.ename, e2.empno, deptno FROM emp e1, emp e2 WHERE e1.empno = e2.empno
如果视图用WITH CHECK OPTION 子句定义的,并且键预留表是重复的那么就不能通过这样的视图来删除行
CREATE VIEW emp_mgr AS
SELECT e1.ename, e2.ename mname FROM emp e1, emp e2 WHERE e1.mgr = e2.empno
WITH CHECK OPTION;
--在该视图上不能执行删除 因为该视图包括了键预留表的自身联结
INSERT INTO emp_dept (ename, empno, deptno) VALUES ('KURODA', 9010, 40);
--这条语句能运行是因为仅修改一个键预留基础表emp 40是dept表中的有效的deptno
( 即满足在emp表上的FOREIGN KEY完整性约束)
INSERT INTO emp_dept (ename, empno, deptno) VALUES ('KURODA', 9010, 77);
--INSERT 语句会失败 失败的原因与UPDATE 在基础emp 表中失败的原因相同违反了emp 表中FOREIGN KEY完整性约束 因为没有deptno 77
-
INSERT INTO emp_dept (empno, ename, loc) VALUES (9010, 'KURODA', 'BOSTON');
--下面的INSTER 语句也会失败 产生一个错误 ORA-01776 cannot modify more than one base table through a view 不能通过视图修改多个基础表
INSERT语句不能隐含地或明确地涉及非键预留表的列如果联结视图是用 WITH CHECK OPTION 子句定义的 那么就不能对该视图执行INSERT 操作
使用UPDATABLE_COLUMNS 视图
当要修改联结视图时 UPDATABLE_COLUMNS 视图表 中所描述的视图对你有帮助
视图名称 | 说明 |
DBA_UPDATABLE_COLUMNS | 显示所有表及视图中的所有可修改的列 |
ALL_UPDATABLE_COLUMNS | 显示用户可访问的所有表及视图中的所有可修改的列 |
USER_UPDATABLE_COLUMNS | 显示用户模式中所有表及视图中的所有可修改的列 |
删除视图
可以删除包含在你的模式中的任何视图 为了删除其他用户模式中的视图 你必须拥有DROP ANY VIEW 系统权限 使用DROP VIEW 语句删除视图
下面的语句删除emp_dept 视图
DROP VIEW emp_dept;
替换视图
要想替换视图 必须拥有删除和创建一个视图所需的所有权限如果必须修改视图的定义 就必须替换视图 而不能修改视图的定义 可用下面的几种方式替换视图
删除并重建视图 警告:当视图被删除时 相应的对象权限的所有授权也被从角色和用户中撤消重新
创建视图之后 必须重新授予权限
可以用包含 OR REPLACE选项的 CREATE VIEW语句重新定义视图 OR REPLACE 选项替换视图的当前定义并且保留当前的安全授权 例如 假设像前面 介绍的那样创建过sales_staff 视图 另外 为角色和其他用户授予过几种对象权限
但是 现在需要重新定义sales_staff 视图来改变在WHERE 子句中指定的部门号 可用下面的语句替换当前版本的sales_staff 视图
CREATE OR REPLACE VIEW sales_staff AS
SELECT empno, ename, deptno FROM emp WHERE deptno = 30
WITH CHECK OPTION CONSTRAINT sales_staff_cnst;
在替换视图之前 要考虑如下几个方面 :
替换视图也就替换了数据字典中视图的定义 并不影响视图所涉及的所有下层对象
如果前面已经定义CHECK OPTION中的约束而新的视图定义中又不包含这种约束该约束就被删除了,依赖于被替换视图的所有视图及PL/SQL 程序单元都变成无效不能使用了
l 同义词
同义词是模式对象的别名 同义词通过屏蔽对象的名称和拥有者 以及通过为分布式数据库的远程对象提供位置透明性来提供一个安全层同义词使用方便 为数据库用户降低了SQL 语句的复杂性
同义词允许重新命名或移动下层对象在那儿仅需要重新定义同义词 而基于同义词的应用无须做任何修改仍能继续工作 ,即能创建公共的也能创建私有的同义词 公共同义词由名为PUBLIC 的特殊用户组所拥有,并且数据库中的每个用户都可访问 私有同义词被包含在特殊用户的模式中 并且仅仅用户和用户的受让人可使用
创建同义词
要想在你拥有的模式中创建私有同义词你必须拥有CREATE SYNONYM 权限,要想在其他用户的模式中创建私有同义词 你必须拥有CREATE ANY SYNONYM 权限要想创建公共同义词 必须拥有CREATE PUBLIC SYNONYM 系统权限
使用CREATE SYNONYM 语句创建同义词 在创建同义词时 下层模式对象不必存在
你也不需要权限以访问对象 下面的语句在包含在jward模式中的emp 表上创建名为public_emp 的公共同义词
CREATE PUBLIC SYNONYM public_emp FOR jward.emp;
a001用户访问Scott.emp
select * from scott.emp
演示建立同义词scemp;
create synonym scemp for scott.emp
演示在a001访问emp:select * from scemp;
删除同义词
使用DROP SYNONYM语句删除不再需要的同义词 要想删除私有同义词 就省略 PUBLIC 关键字 要想删除公共同义词 就要包括PUBLIC 关键字
DROP SYNONYM emp; --删除名为emp 的私有同义词
DROP PUBLIC SYNONYM public_emp; --删除名为public_emp的公有同义词
l 序列
创建序列
要想在你的模式中创建序列 你必须拥有CREATE SEQUENCE系统权限 为了在其他用户的模式中创建序列 必须拥有CREATE ANY SEQUENCE 权限
使用CREATE SEQUENCE 语句创建序列 例如 下面的语句创建一个用于给emp,表中empno 列产生雇员号的序列
CREATE SEQUENCE emp_sequence
INCREMENT BY 1 --步长为1
START WITH 1 --起始为 1
NOMAXVALUE --没有最大值[或Maxvalue 100,Minvalue 1]
NOCYCLE --表示不可循环[或CYCLE 表示到Maxvalue值循环,从minvalue开始]
CACHE 10; -- 预分配一组10个序列号 ,默认为20
例:
Insert into 表名value(emp_sequence.Nextval,’ddd’)
--自增列, emp_sequence.Nextval表示返回当前自增列的号
CACHE选项预分配一组序列号,并且把它们存在内存中,以便更快地访问序列号 当高速缓存中最后一个序列号被使用了 Oracle 就再读入另外一组序列号 并将其放入到高速缓存中.
如果选择用高速缓存存放一组序列号 Oracle 可能跳过序列号 例如 当实例不正常关机时 例如 当实例出现失败或发布了SHUTDOWN ABORT 语句 已经被放在高速缓存中但没有被使用的序列号就会丢失 同样 已经被使用但没有被保存的序列号也会丢失在导入和导出之后 Oracle 也可能跳过已在高速缓存中的序列号
更改序列
要想更改序列 你的模式中必须包含序列或者你必须拥有ALTER ANY SEQUENCE系统权限 能更改序列 以修改定义它是如何产生序列号的任何参数 除序列的起始号以外 为了更改序列的起始点 可以先删除序列 然后再重新创建序列 当在序列号上执行
DDL 时 就会丢失高速缓存中的值
使用ALTER SEQUENCE 语句更改序列 例如 下面的语句改变emp_sequence 序列
ALTER SEQUENCE emp_sequence
INCREMENT BY 10
MAXVALUE 10000
CYCLE
CACHE 20;
删除序列
可以删除你的模式中的任何序列要想删除其他模式中的序列 你必须拥有DROP ANY SEQUENCE 系统权限 如果不再需要某个序列 可用DROP SEQUENCE 语句删除它
例如 下面的语句删除order _ seq 序列
DROP SEQUENCE order_seq;
删除序列时 它的定义就会从数据字典中删除该序列的所有同义词保留下来 但参
照这些同义词时 会返回一个错误