sql server中对视图更新的规则

SQL Server中更新视图, 可能出现的错误及处理.
定义视图后,对视图的查询没有什么限制,可以像对待表一样进行操作。但是,
如果对视图中的元组进行更新操作(INSERT,UPDATE,DELETE)将受到限制。概括起

来,关于可更新视图有以下三条规则:

(1) 若视图是基于多个表使用联接操作而导出的,那么对这个视图执行更新操作

时,每次只能影响其中的一个表。

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

(3) 若视图是从一个表经选择、投影而导出的,并在视图中包含了表的主键字或

某个候选键,这类视图称为‘行列子集视图’。对这类视图可执行更新操作。

定义可更新视图时加上WITH CHECK OPTION短语,表示强制在视图上的所有数据

更新语句都必须符合由select查询语句所设置的准则。

由于视图不一定包括表中的所有字段,所以在插入记录时可能会遇到问题。视图

中那些没有出现的字段无法显式插入数据,假如这些字段不接受系统指派的null

值,那么插入操作将失败。但这类视图仍然可以用于修改和删除操作。

·设有下面的视图定义:


 use mydb
 go
     CREATE VIEW s_e_c_view
 as
    SELECT student.sno,sname,cname,grade
      FROM student,elective,course
      WHERE student.sno=elective.sno and elective.cno=course.cno


   这个视图由三个表联接而成。如果对该视图执行下列插入操作:

use mydb
INSERT INTO s_e_c_view
VALUES ( 200200130, ’张小冬’, ’english’, 82 )

   系统将发出错误信息:“视图或函数‘s_e_c_view’不可更新,因为修改会影响

多个基表”。我们不妨假设在表course中,一个非键字段值(课程名cname)可能

对应多个主键值(课程号cno)。现在只有课程名‘english’而主键课程号cno不

确定,显然不能把数据插入course表中。同样,由于cno不确定,也不能把成绩8

2插到elective表中。因此,不允许对这个视图执行插入操作。这里的s_e_c_vie

w视图属于规则(1)所述的情形。

如果把插入操作换成修改操作,而且只影响其中一个表,同时新数据值中含有主

键字,系统将接受这个修改操作。实例如下:

use mydb

UPDATE s_e_c_view
SET sno=200200130, sname=‘张小冬’
WHERE sno=200200102

·设有下面的视图定义:

use mydb
go
CREATE VIEW e_view ( sno, c_amounnt, avg_grade )
as
SELECT sno,count(cno),avg(grade)
FROM elective
WHERE grade is not null
GROUP BY sno

这个视图虽然仅从一个表中导出,但导出时使用了分组和聚合操作。如果对该视

图执行下列插入操作:

use mydb

INSERT INTO e_view
VALUES ( 200200120, 2, 78 )

系统将发出错误信息:“视图或函数‘e_view’ 不可更新,因为它包含聚合”。

事实上,在原来的elective表中根本就不存在‘修课总数’和‘平均成绩’两列

。上述的更新操作显然不切实际。因此,不允许对这个视图执行更新操作是合理

的。这里的e_view视图属于规则(2)所述的情形。

·设有下面的视图定义:

use mydb
go

CREATE VIEW s_view
as
SELECT sno,sname,height
FROM student
WHERE sex=’男’

这个视图基于一个表且只使用选择和投影操作,同时还包含了主键字sno,所以这

个视图是可更新的。如果对该视图执行下列插入操作:

use mydb

INSERT INTO s_view
VALUES ( 200200120, ‘黄大春’, 178 )

在student表中将插入一个新的记录,对记录中没有指定值的字段系统将指派一

个NULL值。这里的s_view视图属于规则(3)所述的情形。

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

如果视图没有INSTEAD OF触发器,或者视图不是分区视图,则视图只有满足下列

条件才可更新:

select语句在选择列表中没有聚合函数,也不包含TOP,GROUP BY,UNION(除非视

图是分区视图)或DISTINCT子句。聚合函数可以用在FROM子句的子查询中,只要

不修改函数返回的值。

select语句的选择列表中没有派生列。派生列是由任何非简单列表达式(使用函

数、加法或减法运算符等)所构成的结果集列。

select语句中的FROM子句至少引用一个表。select语句不能只包含非表格格式的

表达式(即不是从表派生出的表达式)。

INSERT,UPDATE和DELETE语句在引用可更新视图之前,也必须如上述条件指定的

那样满足某些限制条件。只有当视图可更新,并且所编写的UPDATE或INSERT语句

只修改视图的FROM子句引用的一个基表中的数据时,UPDATE和INSERT语句才能引

用视图。只有当视图在其FROM子句中只引用一个表时,DELETE语句才能引用可更

新的视图。

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值