Oracle 普通视图 (Oracle Standard Views)

     视图(views)是一种基于表的"逻辑抽象"对象,由于它是从表衍生出来的,因此和表有许多相同点,我们可以和对待表一样对其进行查询/更新操作。但视图本身并不存储数据,也不分配存储空间。

    本文只讨论普通的视图(Standard Views)。Oracle的视图类型还有对象视图(Object Views)物化视图(Materiallized Views)和分析视图(Analytic Views)等。

目录

一、视图的作用

二、视图创建语法

三、基础视图

3.1 基础视图创建

3.2 自定义视图列名

3.3 强行建立视图

3.4 通过视图更新基表数据

3.5 通过with check option限制数据插入

3.6 通过with read only选项限制视图只读

四、连接视图

4.1 连接视图的更新规则

4.1.1 键值保留表(key-preserved table)

4.1.2 通过视图判断连接视图中可更新的列

4.2 with check option的影响


一、视图的作用

视图本质是存储的在数据字典中的"查询",其底层有一系列“基表”(Base Tables)或其他视图。因此视图是基表的逻辑抽象,其最基本的作用就是隐藏底层的复杂的数据结构。

Oracle本身就提供了很多数据字典和性能视图(v$视图),通过这些视图我们可以很方便的查询某一类信息,而根本不需要知道底层真实的数据结构。

视图的主要功能有:

  • 简化逻辑,通过视图对数据进行归纳后,可以隐藏底层数据的复杂性
  • 访问控制,通过视图可以限制用户仅访问表的一部分
  • 数据抽象,用户可以对视图的列重名或增加自己的逻辑,而不影响基表
  • 应用隔离,当应用通过视图访问数据时,我们对基表增加列等维护操作时,不会影响应用程序

二、视图创建语法

视图是通过 create view 语句创建的,基础语法为(方括号代表可以忽略的选项,斜线代表选择):

create [or repalce] [force/noforce] view [schema.]view_name [(column_alias ….)]
as
query_definition
[with read only/check option]

主要选项解释:

  • or replace: 当视图已存在时,使用此选项可以重建,通常在修改视图定义时使用。
  • force: 强行建立视图定义,即使视图的基表不存在或者没有权限,默认是noforce。
  • schema: 可以在别人的schema中定义视图,但必须有create any view权限,省略时视图创建在自己的schema。
  • column_alias: 建立视图时,可以重命名列。
  • with read only: 视图不可更新。
  • with check option: 无法通过视图更新或插入视图看不到的数据。

注:上面仅包含了最常用的视图创建选项,更完整的视图定义语法请参阅官方文档。

三、基础视图

通过示例可以更好的理解视图各选项的含义,下面以Oracle自带的sample_schema中的hr.employees作为基表演示视图的创建。

3.1 基础视图创建

创建一个基础视图(仅包含一张基表),仅包含employee_id, first_name, last_name, salary列

create view v_emp as
select employee_id, first_name, last_name, salary from employees;

desc v_emp;

3.2 自定义视图列名

更新刚才的视图,列名重命名为a,b,c,d:

create or replace view v_emp(a, b, c, d) as
select employee_id, first_name, last_name, salary from employees;

desc v_emp;

3.3 强行建立视图

通过force选项创建一个基表不存在的视图:

create force view v_not_exist as select * from employeesssssss;

这里我们基于一个不存在的表强行建立了一个视图,因此有一个警告。在视图基表存在之前,该视图无法使用。

3.4 通过视图更新基表数据

更新v_emp视图,限制仅显示employee_id>=200的数据

create or replace view v_emp as
select employee_id, first_name, last_name, salary from employees where employee_id>=200;

select * from v_emp;

通过视图将employee_id为206的数据更新为99999:

update v_emp set salary=99999 where employee_id=206;

select * from v_emp;

通过视图对基表的更新会受到基表的约束(例如视图看不到的列如果有非空约束,那么会阻止通过视图插入数据),同时如果用户对基表没有DML权限,那么也无法通过视图更新基表。

3.5 通过with check option限制数据插入

通过v_emp视图虽然只能看到employee_id>=200的数据,我们却可以通过它插入employee_id<200的数据,但是视图自己是无法看到该数据的:

insert into v_emp values(20,'Vincent','Chen',12345);    -- 通过视图插入employee_id=20的数据

select employee_id, salary from employees where employee_id=20;  -- 查询基表,数据插入成功

select * from v_emp;  -- 而视图自己是看不到数据的

更新视图,新增with check option选项,限制其无法插入视图看不到的数据(报错:违反视图定义中的where子句):

create or replace view v_emp as
select employee_id, first_name, last_name, salary from employees where employee_id>=200 with check option;

insert into v_emp values(21,'Vincent','Chen',12345);   -- 通过视图插入employee_id=21的数据

3.6 通过with read only选项限制视图只读

如果视图创建时增加的with read only选项,那么禁止通过视图插入或更新数据(报错:只读视图无法更新):

create or replace view v_emp as
select employee_id, first_name, last_name, salary from employees where employee_id>=200 with read only;

update v_emp set salary=99999 where employee_id=206;

四、连接视图

如果视图的查询定义中包含多张表连接,那么就是连接视图(Join Views)。下面建立基于hr.departments和hr.employees的连接视图,两个基表的表结构如下,两张表可以通过department_id进行连接:

4.1 连接视图创建

create view v_dept_emp as
select d.department_id, d.department_name, e.employee_id, e.first_name, e.salary
from departments d, employees e
where d.department_id = e.department_id
and d.department_id = 20;

4.1 可更新连接视图(updatable join views)

如果连接视图没有通过 with read only 选项约束,那么就是可更新连接视图(updatable join views)。虽然可以更新,但对其更新受到一定的规则约束。

通用约束:对于可更新视图的更新,每次最多涉及一张基表。即通过连接视图更新时,每次只能更新来自同一张基表中的列,不能涉及多张基表。

4.1.1 键值保留表(key-preserved table

除了每次只能影响一张基表的约束,可更新视图也并不是所有的列都可以更新。

这里我们先要了解一个概念:保留键值表(Key-preserved table),如果某张基表的键连接后,其键值也可以作为最终连接结果的键,那么它就是键值保留表。

定义比较晦涩,我们通过上面视图定义来解释。在视图的两张基表employees(雇员 别名e)和departments(部门 别名d)中,两张表的主键分别是employee_id和department_id,我们的连接条件是 d.department_id=e.department_id,这里employees去连接departments表的主键(d.department_id),那么employees就是键值保留表。在最终的结果中,employees表连接其他表的主键或唯一键,会保证自己的每行在连接结果中最多出现一次,而departments表是通过主键(或唯一键)进行连接的。

键值保留表会去连接别人的主键(或唯一键),由于连接的是别人的主键/唯一键,所以连接后,自己的行在最终结果中不会重复,因此可以保持唯一(键值保留)。从视图查询结果上我们也可以看到:employees表去连接departments表的主键/唯一键,那么最终结果一定不会导致employees表的记录重复,那么employees的记录可以在最终视图中保持唯一。而departments表的记录可以看到在最终结果中出现了重复(这里就算结果不重复,departments表也不是键值保留表,因为它无法保证不重复)。

select * from v_dept_emp;

理解了键值保留表(key-preserved table),可更新视图的另一个约束就是:可以更新的列要来自键值保留表。

上面示例中,departments表不是键值保留表,我们去更新来自departments表的列时就会报错:不能更改来自非键值保留表的列(ORA-01779)

update v_dept_emp set department_name='abc' where department_id=20;

而employees是键值保留表,来自它的列可以更新成功(这里我们只是把更新的列从department_name换成了first_name,where条件保持相同):

update v_dept_emp set first_name='abc' where department_id=20;

4.1.2 通过视图判断连接视图中可更新的列

如果通过键值保留表的概念判断连接视图中哪些列可以更新比较困难,那么Oracle也提供了更简便的方式,直接通过视图dba/all/user_updatable_columns查询连接视图中的可更新列:

select table_name, column_name, updatable from user_updatable_columns where table_name='V_DEPT_EMP';

通过updatable列我们也可以看到来自employees表(key-preserved table)的三列是可以更新的。

4.2 with check option的影响

如果连接视图在定义时增加了with check option,那么所有连接条件中的列都不可以更新(即使其来自键值保留表)

我们将上面v_dept_emp视图中的department_id列来源从departments表修改为employees表(d.department_id => e.department_id),由于employees是键值保留表,因此从视图user_updatable_columns我们可以看到department_id是可以更新的。

create or replace view v_dept_emp as
select e.department_id, d.department_name, e.employee_id, e.first_name, e.salary
from departments d, employees e
where d.department_id = e.department_id
and d.department_id = 20;

select table_name, column_name, updatable from user_updatable_columns where table_name='V_DEPT_EMP';

我们将视图查询保持不变,仅增加一个with check option选项,department_id依然来自键值保留表employees,我们再次查询视图,发现department_id变为不可更新(因为它是连接条件 d.department_id = e.department_id 中的列)。

create or replace view v_dept_emp as
select e.department_id, d.department_name, e.employee_id, e.first_name, e.salary
from departments d, employees e
where d.department_id = e.department_id
and d.department_id = 20
with check option;

select table_name, column_name, updatable from user_updatable_columns where table_name='V_DEPT_EMP';

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/43472.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络安全(零基础)自学

一、网络安全基础知识 1.计算机基础知识 了解了计算机的硬件、软件、操作系统和网络结构等基础知识&#xff0c;可以帮助您更好地理解网络安全的概念和技术。 2.网络基础知识 了解了网络的结构、协议、服务和安全问题&#xff0c;可以帮助您更好地解决网络安全的原理和技术…

【C++进阶】1. 继承

1. 继承的概念及定义 1.1继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象程序设计的层…

机器学习之主成分分析(Principal Component Analysis)

1 主成分分析介绍 1.1 什么是主成分分析 主成分分析&#xff08;Principal Component Analysis&#xff09;简称PCA&#xff0c;是一个非监督学习的机器学习算法&#xff0c;主要用于数据的降维&#xff0c;对于高维数据&#xff0c;通过降维&#xff0c;可以发现更便于人类理…

【stable diffusion】保姆级入门课程01-Stable diffusion(SD)文生图究竟是怎么一回事

目录 学前视频 0.本章素材 1.什么是文生图 2.界面介绍 2.1切换模型的地方 2.2切换VAE 2.3功能栏 2.4提示词 1.提示词的词性 2.提示词的语法 3.提示词的组成 4.提示词的权重调整 2.5参数调整栏 1.采样方法 2.采样迭代步数 3.面部修复 4.平铺图 5.高清修复 6.…

Linux系统入门之-系统编程【open、close函数】

继上一篇环境配置后就正式开始系统编程 RK3568开发板入门之-tftp&nfs的配置 open的使用&#xff0c;使用之前可以先在Ubuntu下查看帮助&#xff0c;了解open的使用和语法&#xff0c;如下&#xff1a; man 2 open对于open函数 *pathname&#xff1a;要打开的文件路径 f…

Linux安装JDK、Redis、MySQL、RabbitMQ、Minio、Nginx.......

文章目录 一、环境准备二、安装JDK三、安装MySQL四、安装Redis三、安装RabbitMQ四、安装Minio五、安装Nginx特殊情况处理Centos7挂载磁盘服务器时间同步MySQL数据库时间同步安装解压软件修改数据库SQL模式 一、环境准备 下载镜像源 中科大镜像源下载至/opt目录下修改yum源为中…

flask 页面新增文件,存在重复文件时,返回错误消息

(40条消息) flask 读取文件夹文件&#xff0c;展示在页面&#xff0c;可以通过勾选删除_U盘失踪了的博客-CSDN博客 项目结构 这是一个基本的Flask应用程序&#xff0c;主要有两个路由&#xff0c;一个是index&#xff0c;用于显示所有存在的文件以及用于删除已选的文件&#…

Java使用 java.util.regex.Pattern 正则表达式校验参数值是否规范

场景&#xff1a; java中我们可以利用 Pattern 注解对某个入参进行规则校验&#xff0c;但有些特殊参数在接口入口处不方便校验&#xff0c;需要在代码中校验 一、使用 Pattern 注解校验 Pattern(regexp "^[a-zA-Z0-9]$", message "xxx号限输入字母、…

4.1 Bootstrap UI 编辑器

文章目录 1. Bootstrap Magic2. BootSwatchr3. Bootstrap Live Editor4. Fancy Boot5. Style Bootstrap6. Lavish7. Bootstrap ThemeRoller8. LayoutIt!9. Pingendo10. Kickstrap11. Bootply12. X-editable13. Jetstrap14. DivShot15. PaintStrap 以下是 15 款最好的 Bootstrap…

百度文心一言文心千帆大模型 ERNIE-Bot-turbo调用示例(golang版本)

百度的文心一言推出来也有一段时间了&#xff0c;但是接口部分一直没有公开&#xff0c;需要进行申请 最近&#xff0c;有朋友提供了文心千帆大模型的api权限&#xff0c;拿到了必须的参数&#xff0c;现在就来测试一下 下面是使用golang封装的文心千帆 ERNIE-Bot-turbo模型的调…

C++面向对象程序设计-基础入门(超详细)

目录 一、c概述 二、初识c 1、第一个c程序 2、c面向对象的三大特性&#xff08;重要&#xff09; 三、作用域运算符&#xff1a;&#xff1a; 1、使用关键字namespace创建一个命名空间 2、命名空间只能定义在全局 3、 命名空间嵌套 4、随时将新的成员加入命名空间 5、命…

DXFReader.NET 2023 Crack

DXFReader.NET 是一个 .NET 组件&#xff0c;允许直接从 AutoCAD 图形文件格式 DXF&#xff08;也称为图形交换格式&#xff09;查看、操作和打印。 DXFReader.NET 之 DXF 是 Drawing eXchange Format 的首字母缩写。DXF 是图形文件内容的复制&#xff0c;支持将文件从一个 CA…

picgo Request failed with status code 404

今天写picgo的时候&#xff0c;出现了一个错误&#xff0c;如何解决&#xff1a; 这里是repo的配置出现了问题&#xff0c;不过我的是因为粗心&#xff0c;把master写成了mater&#xff0c;emmmm 这里的repo要跟仓库的地址相同就是这一块&#xff1a;把这一块填到repo就行 然…

算法之图论

定义 图通常以一个二元组 G<V, E>表示&#xff0c;V表示节点集&#xff0c;E表示边集。节点集中元素的个数&#xff0c;称为图的阶。 若图G中的每条边都是没有方向的&#xff0c;称为无向图&#xff1b;每条边是由两个节点组成的无序对&#xff0c;例如节点V1和节点V2之…

论文阅读:矩阵乘法GEMM的cache优化,子矩阵的切分方法Anatomy of High-Performance MatrixMultiplication

矩阵乘法优化的知名论文goto paper&#xff1a; 矩阵乘法的优化需要将矩阵切分成子矩阵&#xff0c;用子矩阵相乘的结果组合为原矩阵相乘的结果&#xff1a; 上图是拆分矩阵的方法&#xff0c;M表示矩阵&#xff0c;X方向和Y方向的两个维度都是未知的。P表示横条或竖条&#x…

前端监控一vue指令实现埋点

前端监控一vue指令实现埋点 https://v2.vuejs.org/v2/guide/custom-directive.html 自定义指令 需要在main.js中执行 import Vue from vue // 自定义埋点指令 Vue.directive(track, {//钩子函数&#xff0c;只调用一次&#xff0c;指令第一次绑定到元素时调用。在这里可以…

Linux 下 nc 发送接收 udp、tcp数据

nc&#xff0c;全名叫 netcat&#xff0c;它可以用来完成很多的网络功能&#xff0c;譬如端口扫描、建立TCP/UDP连接&#xff0c;数据传输、网络调试等等&#xff0c;因此&#xff0c;它也常被称为网络工具的 瑞士军刀 。 一、只服务端使用nc 备注&#xff1a;这种方式只能发…

新能源汽车交流充电桩CP信号详解

随着新能源汽车的推广&#xff0c;交流充电桩迎来了巨大的市场需求&#xff0c;人们对车辆充电的便利性、安全性有着越来越高的要求。CP信号主要用于交流充电桩&#xff0c;充电桩和汽车之间只能通过CP信号进行通讯&#xff0c;判断、控制充电电流和状态。 汽车充电桩CP信号…

124.【SpringBoot 源码刨析C】

SpringBoot源码刨析C (三)、SpringBoot核心功能2.Web4.数据响应与内容协商(1).响应JSON&#xff08;1.1&#xff09;jackson.jarResponseBody&#xff08;1.1.1&#xff09;、返回值解析器&#xff08;1.1.2&#xff09;、返回值解析器原理 (1.2).SpringMVC到底支持哪些返回值(…

【STL】模拟实现简易 list

目录 1. 读源码 2. 框架搭建 3. list 的迭代器 4. list 的拷贝构造与赋值重载 拷贝构造 赋值重载 5. list 的常见重要接口实现 operator--() insert 接口 erase 接口 push_back 接口 push_front 接口 pop_back 接口 pop_front 接口 size 接口 clear 接口 别…