允许进行DML操作的视图条件

视图可以屏蔽某些基表的信息,或是join多个基表组成一个复杂查询,视图本身也是可以进行DML操作,但受一些条件的限制。

首先我们看下官方文档对视图进行DML操作的要求说明:

The following notes apply to updatable views:

An updatable view is one you can use to insert, update, or delete base table rows. You can create a view to be inherently updatable, or you can create an INSTEAD OF trigger on any
view to make it updatable.

这里说明了两种可updateable(包括增删改基表)视图的方法:一是继承基表的视图,二是使用INSTEAD OF的触发器来实现任意视图的updatable。

To learn whether and in what ways the columns of an inherently updatable view can be modified, query the USER_UPDATABLE_COLUMNS data dictionary view. The information displayed by
this view is meaningful only for inherently updatable views.

USER_UPDATABLE_COLUMNS数据字典视图可以找到视图的哪些字段可以进行增加、更新和删除。

For a view to be inherently updatable, the following conditions must be met:

对于这种updatable继承的视图,需要满足以下条件:

1. Each column in the view must map to a column of a single table. For example, if a view column maps to the output of a TABLE clause (an unnested collection), then the view is
not inherently updatable.

2. The view must not contain any of the following constructs:

A set operator

DISTINCT operator

An aggregate or analytic function

GROUP BYORDER BYMODELCONNECT BY, or START WITH clause

A collection expression in a SELECT list

A subquery in a SELECT list

A subquery designated WITH READ ONLY

Joins, with some exceptions, as documented in Oracle
Database Administrator‘s Guide

3.
In addition, if an inherently updatable view contains pseudocolumns or expressions, then you cannot update base table rows with an UPDATE statement
that refers to any of these pseudocolumns or expressions.

4. If you want a join view to be updatable, then all of the following conditions must be true:

对于一个join视图,如果需要可updatable,那么就需要满足如下条件:

(1) The DML statement must affect only one table underlying the join.

DML必须仅影响一个join连接的表。

(2) For an INSERT statement, the view must not be created WITH CHECK OPTION,
and all columns into which values are inserted must come from a key-preserved table. A key-preserved table is one for which every primary key or
unique key value in the base table is also unique in the join view.

INSERT语句,不能使用WITH CHECK OPTION,并且所有待插入的列都来自于key-preserved表。

key-preserved表是指基表中每个主键或唯一键也必须是在join视图中唯一。

(3) For an UPDATE statement, the view must not be created WITH CHECK OPTION,
and all columns updated must be extracted from a key-preserved table.

UPDATE语句,视图不能使用WITH CHECK OPTION创建,同样更新字段也必须来自于key-preserved表。

5. For a DELETE statement, if the join results in more than one key-preserved table, then Oracle
Database deletes from the first table named in the FROM clause, whether or not the view was created WITH CHECK OPTION.

DELETE语句,如果join结果有多个key-preserved表,Oracle只会删除FROM子句中第一个表的记录,不管视图是否使用WITH CHECK OPTION。

下面通过一系列实验来说明。

创建测试表:

create table dept(deptid int primary key, deptname varchar2(20));

create table employee(empid int primary key, empname varchar2(20), deptid int);

创建测试数据:

insert into dept values(1,‘dept1‘);

insert into dept values(2,‘dept2‘);

insert into dept values(3,‘dept3‘);

insert into employee values(1,‘emp1‘,1);

insert into employee values(2,‘emp2‘,1);

insert into employee values(3,‘emp3‘,2);

创建视图:

create view testv

as select d.deptid deptid, deptname, empid, empname, e.deptid edeptid

from dept d join employee e

on d.deptid = e.deptid;

SQL> select * from testv;

DEPTID   DEPTNAME               EMPID  EMPNAME            EDEPTID

---------- -------------------- ---------- -------------------- ----------

1   dept1                         1           emp1                    1

1   dept1                         2           emp2                    1

2   dept2                         3           emp3                    2

仅employee表是key-preserved表。

测试1:对key-preserved表字段进行增加、更新的操作

update testv set empname=‘empx‘ where edeptid=1;

update testv set empname=‘empx‘ where empid=1;

update testv set empname=‘empx‘ where deptid=1;

insert into testv(empid,empname,edeptid) values(4,‘emp4‘,2);

以上SQL可以执行,因为修改或添加的字段都是employee的,即key-preserved表。

测试2:验证上述“DELETE语句,如果join结果有多个key-preserved表,Oracle只会删除FROM子句中第一个表的记录,不管视图是否使用WITH CHECK OPTION”

create view testv

as select d.deptid deptid, deptname, empid, empname, e.deptid edeptid

from employee e join dept d

on d.deptid = e.deptid;

create view testv

as select d.deptid deptid, deptname, empid, empname, e.deptid edeptid

from employee e join dept d

on d.deptid = e.deptid

WITH CHECK OPTION;

select * from testv;

DEPTID  DEPTNAME           EMPID      EMPNAME           EDEPTID

---------- -------------------- ---------- -------------------- ----------

1    dept1                         1          emp1                          1

1    dept1                         2          emp2                          1

2    dept2                         3          emp3                          2

delete from testv where deptid = 1;

2 rows deleted.

select * from dept;

DEPTID  DEPTNAME

---------- --------------------

1      dept1

2      dept2

3      dept3

select * from employee;

EMPID   EMPNAME            DEPTID

---------- -------------------- ----------

3     emp3                          2

delete from testv where empid = 1;

1 row deleted.

select * from testv;

DEPTID   DEPTNAME           EMPID    EMPNAME            EDEPTID

---------- -------------------- ---------- -------------------- ----------

1      dept1                         2       emp2                          1

2      dept2                         3       emp3                          2

select * from dept;

DEPTID   DEPTNAME

---------- --------------------

1      dept1

2      dept2

3      dept3

select * from employee;

EMPID   EMPNAME            DEPTID

---------- -------------------- ----------

2      emp2                          1

3      emp3                          2

测试3:对于INSERT和UPDATE语句,不能使用WITH CHECK OPTION创建视图

create view test1v

as select t1id ,t1v,t2id,t2v

from test1 join test2

on test1.t1id=test2.t2id

with check option;

insert into test1v(t1id,t1v) values(4,‘t4‘);

*

ERROR at line 1:

ORA-01733: virtual column not allowed here

update test1v set t1id=4 where t1id=1;

*

ERROR at line 1:

ORA-01733: virtual column not allowed here

测试4:非key-preserved表字段不能更新或插入

update testv set deptname=‘deptx‘ where deptid=1

update testv set deptname=‘deptx‘ where empid=1

insert into testv(deptid,deptname) values(4,‘dept4‘)

ORA-01779: cannot modify a column which maps to a non key-preserved table

测试5:查看视图中哪些字段可以增删改

select * from USER_UPDATABLE_COLUMNS where table_name=‘TESTV‘;

OWNER TABLE_NAME
COLUMN_NAME UPD INS DEL

-------------------------------------------------------------------------------------------

DCSOPEN TESTV
DEPTID NO  NO  NO

DCSOPEN TESTV
DEPTNAME NO  NO  NO

DCSOPEN TESTV
EMPID YES YES YES

DCSOPEN TESTV
EMPNAME YES YES YES

DCSOPEN TESTV
EDEPTID YES YES YES

If
you want a join view to be updatable, then all of the following conditions must be true:

允许进行DML操作的视图条件

时间: 2024-08-25 22:45:25

允许进行DML操作的视图条件的相关文章

Oracle-31-对视图DML操作

一.对视图进行DML操作 1.创建一个视图v_person create or replace noforceview v_person as select *from person where id between 1003 and 1007; 2.向视图v_person中进行insert操作 insertinto v_person (id,name) values(1010,'J') [注意]对视图进行DML操作时候.仅仅能对简单视图运行DML操作.复杂视图不支持DML操作.因为v_pers

第一讲SQL命令的DDL和DML操作讲解

知识点: 一.sql命令DDL(结构化操作) 二.sql命令DML操作(增删改查) 1.sql命令DDL(结构化操作) 1.1表添加字段: alter table 表名 add 列定义 如: alter table Student add email varchar(128); 1.2 修改字段: alter table 表名 change 旧字段名 新字段名: alter table Student change email StuEmail varchar(256); 1.3删除字段: al

Oracle的闪回技术--闪回错误的DML操作

提交DML操作后,该操作使用的还原段就可以被其它对象使用了,为了保证闪回操作时这些数据仍然被保存在还原段中,可能需要重新设置undo_retention参数,表示一个事务提交后,该事务的数据必须保存在还原段中的时间:但是这也并不能完全保证指定的时间的数据一定能够被恢复,还原表空间没有足够的时间时,仍会覆盖要求保留的磁盘空间. 查看undo_retention的当前值: SQL> show parameter undo_retention NAME TYPE VALUE -------------

MySQL/MariaDB DML操作之Select

前言 上文我们已经讲解了MySQL/MariaDB的基础知识和DDL相关操作,接下来我们来说一下MySQL/MariaDB的DML操作,因select查询较复杂也较重要,所以本文主要是对select查询的详解. DML操作 DML之select 投影查询 select col_name,[col_name1,...] from table_name; select * from table_name ;#显示全表 遍历整张数据表,但对系统资源消耗较大,再进行大数据量的查询时,禁止使用这类操作 条

如何使用Logminer来分析具体的DML操作日志

如何使用Logminer来分析具体的DML操作日志在Oracle数据库维护中,常常需要分析原来数据库都做了哪些删除.更新.增加数据的操作,所以一般需要用到Logminer这工具来分析归档日志.环境:AIX5.3+Oracle10.2.0.1   使用IBM的Tivoli Storage Manager把数据库数据.归档日志备份到带库中 1.确定具体时间的DML操作,把相应的归档日志从带库恢复到数据库中2.用Logminer来分析相应的归档日志 一.在sqlplus用sys超级用户登陆数据库中,然

MySQL学习笔记——DML操作

有关数据库的DML操作 -insert into -delete.truncate -update -select -条件查询 -查询排序 -聚合函数 -分组查询 多表连接和子查询

高级dml操作,insert操作

drop table e1 purge; drop table e2 purge; create table e1 as select ename,sal,hiredate from emp where 9=0; create table e2 as select ename,deptno,mgr from emp where 9=0; insert all into e1 values(ename,sal,hiredate) into e2 values(ename,depno,mgr) se

Python数据库操作 DML操作-数据的增删改#学习猿地

# MySQL 数据操作 DML > 数据的DML操作:添加数据,修改数据,删除数据 ## 添加数据 > 格式: insert into 表名[(字段列表)] values(值列表...); ```sql --标准添加(指定所有字段,给定所有的值) mysql> insert into stu(id,name,age,sex,classid) values(1,'zhangsan',20,'m','lamp138'); Query OK, 1 row affected (0.13 sec

使用Trigger审计一张表的DML操作

最近ogg的灾备端复制进程中的一张表老是报错ORA-04031,但是又查不到原因,于是想用审计的方法来看到底这张表是被谁做了DML操作,把数据搞没了.本来想用数据库自带的审计功能参考:http://hbxztc.blog.51cto.com/1587495/1870181 但是需要重启数据库,就放弃了,上网查资料看到有人用触发器来实现这个功能,于是自己也做了尝试. 平台11.2.0.4 [email protected]>select * from v$version; BANNER -----