Oracle 视图详解(view)

1 概述

在这里插入图片描述

-- 查询所有 view
SELECT * FROM dba_views t; -- all_views, user_views

-- 删除视图 
DROP VIEW 视图名;

2 语法

CREATE [OR REPLACE] [FORCE] VIEW [属主.]<view_name>
AS  (
  SELECT 语句
)
[WITH CHECK OPTION]
[WITH READ ONLY];

关键字解释:

1. or replace: 存在就替换原视图
2. force: 强制执行,即使报错。常用来处理执行顺序导致的问题
3. with check option: 插入或修改的数据行必须满足视图定义的约束
4. with read only: 该执行上不能进行任何 dml 操作

基础数据:

CREATE TABLE stu_info (
  id   number(3) not null,
  name varchar2(30) not null,
  sex  varchar2(2) not null
);

INSERT INTO stu_info (id, NAME, sex) VALUES (1, '瑶瑶', '女');

3 示例

3.1 force 强制创建视图

实际应用场景:DB 部署时,顺序是:DDL 语句 -> DML 语句 -> PKG
若 DDL 语句中的 view 调用了 pkg,则部署时会产生报错(因为此时 pkg 还未部署),但此报错在 pkg 部署后会消失,此时便用到了 force。

创建视图语句:

CREATE OR REPLACE VIEW vw_stu_info AS (
 SELECT si.id,
        si.name,
        si.sex,
        f_get_class_no(si.id) class_no -- pkg 中,还未被执行(简单演示,就没写到 pkg 里面,但效果是一样的)
   FROM stu_info SI
);
/

执行结果:
在这里插入图片描述
加上 force 后,执行成功

CREATE OR REPLACE FORCE VIEW vw_stu_info AS (
 SELECT si.id,
        si.name,
        si.sex,
        f_get_class_no(si.id) class_no -- 假如有这个方法
   FROM stu_info SI
);
/
  • 小提示: 此时的 view 是 无效的哦,只有当 f_get_class_no 函数执行后,才是有效的。
SELECT t.status, t.* FROM all_objects t WHERE t.OBJECT_NAME = UPPER('vw_stu_info');
-- INVALID: 无效

按顺序部署 pkg 中的方法:f_get_class_no(实际开发中,函数 是放在 pkg 里面的,此处仅作为测试使用)

CREATE OR REPLACE FUNCTION f_get_class_no(v_id stu_info.id%TYPE)
   RETURN VARCHAR2 AS
   v_class_no VARCHAR2(10);
BEGIN
   IF v_id < 5 THEN
      v_class_no := 'A001';
   ELSIF v_id >= 5 THEN
      v_class_no := 'A002';
   ELSE
      v_class_no := 'A000';
   END IF;
   
   RETURN v_class_no;
END;
/

查询视图:

SELECT * FROM vw_stu_info;

查询结果:
在这里插入图片描述

3.2 dml 操作

通常情况下,我们都只会对视图只会进行查询操作,但是要了解,视图也是可以进行 insert、update、delete 的哦,只是限制条件很多。

  • 符合情况:“简单的视图” -> 视图中仅含一张基表,无其它约束检查

创建视图语句:

CREATE OR REPLACE VIEW vw_stu_info AS 
SELECT si.id,
       si.name,
       si.sex
  FROM stu_info SI;
/

测试语句:(可以理解为向 基表 中插入数据的情况)

-- TRUNCATE TABLE stu_info; 清除历史数据,如果有

INSERT INTO vw_stu_info (id, NAME, sex) VALUES (1, '瑶瑶', '女');

SELECT * FROM vw_stu_info;

测试结果:
在这里插入图片描述

个人理解:

  • 判断的依据:向视图中插入数据情况,可以转化为向基表中插入数据的情况,然后再考虑 dml 操作的可行性
  • 一般情况下,我们只会对视图进行查询,不做 dml 操作,所以此处了解即可。
  • 大致有下列情况(也许你见过别人说的其它情况,但一切要以自己实际动手的案例为主!)
不符合的情况 理解
多个基表连接 规定(扩展:可通过 instead of 触发器进行 dml 操作)
存在虚拟列 基表中没有,通过表达式,rowid、rownum 等计算得到的
存在 not null 列不在视图中 很好理解,若不是,则违反了基表的 非空约束

3.3 with check option

  • 检查选项: 视图中进行 dml 操作时,必须要符合 where 的限制条件

个人理解:

1. 对于 insert,有 with check option 时,要保证 insert 后,数据能被视图查询出来(符合 where 条件) 
2. 对于 update,有 with check option 时,要保证 update 后,数据能被视图查询出来(符合 where 条件)
3. 对于 delete,有无 with check option 都一样
4. 对于没有 where 子句的视图,使用 with check option 是多余的 

基础数据:

TRUNCATE TABLE stu_info; -- 清除历史数据

INSERT INTO stu_info (id, NAME, sex) VALUES (1, '瑶瑶', '女');
INSERT INTO stu_info (id, NAME, sex) VALUES (2, '倩倩', '女');
INSERT INTO stu_info (id, NAME, sex) VALUES (3, '优优', '男');
COMMIT;

视图代码:

CREATE OR REPLACE VIEW vw_stu_info AS (
 SELECT si.id,
        si.name,
        si.sex
   FROM stu_info SI
  WHERE si.id <= 5
) WITH CHECK OPTION;
/

测试语句:

-- id = 6 > 5, 不符合视图中的 where 条件
INSERT INTO vw_stu_info (id, NAME, sex) VALUES (6, '测试66', '男');

测试结果:
在这里插入图片描述

3.4 with read only

  • 检查选项: 只读视图,禁止 dml 操作

创建视图语句:

CREATE OR REPLACE VIEW vw_stu_info AS (
 SELECT si.id,
        si.name,
        si.sex
   FROM stu_info SI
  WHERE si.id <= 5
) WITH READ ONLY;
/

测试语句:

INSERT INTO vw_stu_info (id, NAME, sex) VALUES (6, '测试66', '男');

测试结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_34745941/article/details/106399534