可更新视图及其规则

1 前言 
多表视图的定义:当视图的数据源只有一张数据表,则该视图为单表视图;当视图的数据源是多张数据表,则该视图为多表视图。 
可更新视图的定义:在绝大多数人的概念中,视图是只读的,不允许修改。ORACLE 8i以上版本,单表视图如果没有设定With Read Only,则该视图是可以更新的,对视图的操作将直接写入的数据表中。 
那么,如果视图的数据源是多张数据表,而多表视图如果实现可更新视图,则可以大大提高编码的效率。

2 多表可更新视图的应用范围 
在程序实现过程中,我们往往会将诸如产品编号、计量单位、客户信息等等存储于独立的数据表,在销售单据、出入库单据等处,引用其主键ID,就可以指向相关详细信息。 
在查询视图上,我们仅需要确定关联关系即可,但在数据录入界面,我们要实现多表信息同步编辑功能时,往往会遇到困扰。需要应用各种各样的编程方法,实现用户需求。 
多表可更新视图大大简化前台编程的工作量,对于前台FORM,可以认为该多表可更新视图就是一张完整的业务数据表,而数据的存储逻辑则建立于后台视图的Instead of 触发器中。

3 多表可更新视图的后台实现 
建立多表视图的Instead Of Trigger,在Trigger中定义数据存储逻辑,就实现了多表可更新视图<复杂的技术难点,解决的方法往往是无比简单的>。实例如下: 
3.1 创建测试数据表 
--=================================================== 
--创建测试表 
--=================================================== 
Drop Table t1; 
Drop Table t2; 
create table t1 
( t11 numeric(28),t12 varchar2(20)); 
create table t2 
( t11 numeric(28),t22 varchar2(20)); 
3.2 多表视图范例 
--=================================================== 
--创建测试视图 
--=================================================== 
create Or Replace view t as 
   select T1.t11 f1 ,T1.t12 f2 ,T2.t22 f3 
      from T1,T2  
      Where T1.t11=T2.t11; 
3.3 多表视图触发器范例       
--=================================================== 
--创建视图的替代触发器 
--=================================================== 
Create Or Replace Trigger Trg_InsUpdDel_t 
  Instead Of Insert or update or delete 
  on t 
  for each row 
Declare 
begin 
   If Inserting Then 
      Insert Into t1 (t11,t12) Values (:New.f1,:New.f2); 
      Insert Into t2 (t11,t22) Values (:New.f1,:New.f3); 
   elsif Updating Then 
      Update t1 set t11=:New.f1,t12=:New.f2 where t11=:New.f1; 
      Update t2 set t11=:New.f1,t22=:New.f3 where t11=:New.f1; 
   elsif Deleting then 
      Delete from t1 where t11=:Old.f1; 
      Delete from t2 where t11=:Old.f1; 
   End if; 
end; 
如此即实现多表可更新视图的定义工作,大家可以试着使用Insert或Delete或Update的SQL语句测试一下。 
3.4 数据库后台注意事项 
当视图使用Create Or Replace View...重新编译后,该触发器就会被覆盖,找不到了。所以大家记得在重新编译多表可更新视图之后,要重新创建其触发器。

4 多表可更新视图的前台实现及注意事项 
4.1 基本实现 
在数据源中,定义数据块的数据源为多表可更新视图,即可实现前台设定。 
当然还有许多注意事项,否则大家在实际应用过程中就会觉得困难重重。 
4.2 FORM前台注意事项 
4.2.1 主键,如果多表可更新视图中,包括外联<如:Where t1.t11=t2.t11(+)>,则必须在FORM中定义主键,包括数据块的主键和数据项的主键属性。否则,FORM将会提示“视图不允许更新”。 
4.2.2 SQL,多表视图如果使用Union或Distinct,则前台FORM可能无法实现更新功能。

可更新视图有以下三条规则:

(1) 若视图是基于多个表使用联接操作而导出的,那么对这个视图执行更新操作时,每次只能影响其中的一个表。

(2) 若视图导出时包含有分组和聚合操作,则不允许对这个视图执行更新操作。

(3) 若视图是从一个表经选择、投影而导出的,并在视图中包含了表的主键字或某个候选键,这类视图称为‘行列子集视图’。对这类视图可执行更新操作。

***
关于可更新视图的一些更具体的描述如下。

如果视图没有INSTEAD OF触发器,或者视图不是分区视图,则视图只有满足下列条件才可更新:

select语句在选择列表中没有聚合函数,也不包含TOP,GROUP BY,UNION(除非视图是分区视图)或DISTINCT子句。聚合函数可以用在FROM子句的子查询中,只要不修改函数返回的值。

select语句的选择列表中没有派生列。派生列是由任何非简单列表达式(使用函数、加法或减法运算符等)所构成的结果集列。

select语句中的FROM子句至少引用一个表。select语句不能只包含非表格格式的表达式(即不是从表派生出的表达式)。

INSERT, UPDATE和DELETE语句在引用可更新视图之前,也必须如上述条件指定的那样满足某些限制条件。只有当视图可更新,并且所编写的UPDATE或 INSERT语句只修改视图的FROM子句引用的一个基表中的数据时,UPDATE和INSERT语句才能引用视图。只有当视图在其FROM子句中只引用 一个表时,DELETE语句才能引用可更新的视图。

时间: 2024-08-09 10:36:47

可更新视图及其规则的相关文章

MVC路由自定义及视图找寻规则

这篇关于MVC路由及视图规则本来是昨天要发的,但是本人真的有点懒,终于今天忍无可忍了.初学MVC的时候比现在还菜一点(现在也很菜),想着会用就行,但是有时还是会好奇,为什么它能找到控制器?为什么控制器return View();就能找到视图,而为什么视图一定要建在Views文件下?好像说的有点多了,接下来一边上例子,一边分析! MVC路由自定义 相信对于MVC路由的配置大家也都了解过一些,其实,这也不是本章的重点. 创建MVC项目的时候,根目录下>>App_Start>>Route

onAttachedToWindow () 和 onDetachedFromWindow () ; 以及更新视图的函数ondraw() 和dispatchdraw()的区别

protected void onAttachedToWindow() This is called when the view is attached to a window. At this point it has a Surface and will    start drawing. Note that this function is guaranteed to be called  before onDraw(android.graphics.Canvas), however it

sas中的sql(7)创建视图,更新视图,删除视图

什么是视图? 视图是一系列的查询语句,在使用时被执行,用来从其他的数据集或视图中获取想要的子集(subset)或者超集(superset). The view contains only the logic for accessing the data, not the data itself 视图能用在哪些地方? 几乎在sas程序中任何真实表用的地方(不能用的地方暂未列出). 使用视图的好处? 1:节约空间,视图往往比真实表要小很多. 2:防止用户经常进行表查询而忽略默写列,视图写好后每次调用

MVC 多级目录(控制器) 路由重写 及 多级Views目录 的寻找视图的规则

转自:[原]Asp.net Mvc   多级控制器 路由重写 及 多级Views目录 的寻找视图的规则 asp.net mvc 为了更好的控制views的页面存放,和控制器的可读性,需要分开多级目录来存放. 1.那么我们再来看我们需要的访问方式,如下图 如果我们要访问Admin下的TestController里面的Index页面,那么我们输入Test/Index,这个肯定不行的.因为TestController根本就不在Controllers的根目录下,而是在Controllers/Admin下

Mvc多级Views目录 asp.net mvc4 路由重写及 修改view 的寻找视图的规则

一般我们在mvc开发过程中,都会碰到这样的问题.页面总是写在Views文件夹下,而且还只能一个Controller的页面只能写在相应的以Controller名命名的文件夹下.如果我们写到别处呢?那么肯定会报错.这是mvc中一个约定俗成的一个规定,必须这样写. 1.正常的项目目录,如下图: 我们要访问Index页面,只需要输入Home/Index就可以访问了.我们之所以能够这样访问,是因为我们在项目创建之初系统就默认配置了一个默认的路由.我们可以按照这个默认的路由规则进行访问. 2.那么我们再来看

sql server 更新视图的sp

create procedure RefreshAllViewas begin declare @ViewName varchar(250) declare #views cursor for select name from sysobjects where objectproperty(id,N'IsView')=1 and uid=1 order by name open #views fetch next from #views into @viewname while @@fetch_

PostgreSQL更新视图脚本的注意事项

项目最早是基于Oracle的,移植到PostgreSQL后,本着尽量少修改的原则,创建/更新视图的脚本也沿用了Oracle风格的CREATE OR REPLACE VIEW形式.但是每当要更新视图定义时,常常报"cannot change name of view column xxx to yyy"的错误,通常是在视图修改某字段名.中间增加字段.删除字段时发生. 究其原因,是PostgreSQL虽然支持CREATE OR REPLACE VIEW语义,却有着容易让人忽略的重要限制(O

vue数组操作不更新视图问题

vue 观察数组的变异方法 更新视图 push() pop() shift() unshift() splice(i,n,arr) sort(xx) reverse() ex: app.book.push({ name:'css', author:'lee' }) 有些方法不会改变数组 filter() concat() slice() 返回新数组  需要用 新返回的数组 更新原数组 app.books= app.books.filter(functiion(item){ return item

使用Ajax选取ListBox的值异步更新视图,并作为表单值提交

一.控制器返回一个ViewBag MultiSelecList值. public ActionResult Create() { ViewBag.ReviewIndexItems = new MultiSelectList(db.ReviewIndexItems.OrderBy(item => item.ReviewIndexItemNumber).ToList(), "ReviewIndexItemID","ReviewIndexItemName"); re