码迷,mamicode.com
首页 > 其他好文 > 详细

视图之二--视图中数据的更新

时间:2014-09-07 21:07:15      阅读:466      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   使用   java   ar   for   数据   

  视图不是表,视图里面的数据是通过sql语句去表中查询得到的。当表中的数据发送更改之后,视图里的数据也会发生相应的更改。所以我么一般有两种方式更新视图里面的数据:一是更新表中的数据,从而间接地更新视图中的数据;二是直接写sql已经更新视图。第一种是方式是一定可以的,第二中方法,能否可行取决于视图的具体结构。以下对第二种方法进行分析。

表结构如下:

 1 -- ----------------------------
 2 -- 学生表
 3 -- ----------------------------
 4 DROP TABLE IF EXISTS `student`;
 5 CREATE TABLE `student` (
 6   `id` varchar(255) NOT NULL,
 7   `name` varchar(255) NOT NULL,
 8   `age` int(11) DEFAULT NULL,
 9   `password` varchar(255) DEFAULT NULL,
10   PRIMARY KEY (`id`)
11 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
12 
13 -- ----------------------------
14 -- 学生记录
15 -- ----------------------------
16 INSERT INTO `student` VALUES (10001, 张三, 20, zhang123);
17 INSERT INTO `student` VALUES (10002, 李四, 21, lisi123);
18 INSERT INTO `student` VALUES (10003, 王五, 22, wang123);
19 -- ----------------------------
20 -- 学生成绩表
21 -- ----------------------------
22 DROP TABLE IF EXISTS `course`;
23 CREATE TABLE `course` (
24   `id` int(11) NOT NULL AUTO_INCREMENT,
25   `stu_no` varchar(255) NOT NULL,
26   `name` varchar(255) NOT NULL,
27   `score` int(11) NOT NULL,
28   PRIMARY KEY (`id`),
29   KEY `id_fk` (`stu_no`),
30   CONSTRAINT `id_fk` FOREIGN KEY (`stu_no`) REFERENCES `student` (`id`)
31 ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
32 
33 -- ----------------------------
34 -- 学生成绩记录
35 -- ----------------------------
36 INSERT INTO `course` VALUES (1, 10001, c++, 70);
37 INSERT INTO `course` VALUES (2, 10001, java, 80);
38 INSERT INTO `course` VALUES (3, 10001, lisp, 90);
39 INSERT INTO `course` VALUES (4, 10002, c++, 75);
40 INSERT INTO `course` VALUES (5, 10002, java, 80);
41 INSERT INTO `course` VALUES (6, 10003, lisp, 91);
42 INSERT INTO `course` VALUES (7, 10003, c++, 73);

 

一、视图只包含一张表的字段

  1、包含全部字段

    视图定义如下: 

DROP VIEW IF EXISTS t_student;
CREATE VIEW t_student AS 
SELECT * FROM student
WITH CHECK OPTION; 

  该视图是查询student表中的所有记录,进行更新的语句如下。

1 INSERT INTO `t_student` VALUES (10004, 赵六, 22, wang123); -- 插入时如果其他未设置的字段有默认值,可以插入,如果没有就报错
2 UPDATE t_student SET name=赵六2 where id=10004; -- 更新可以 
3 DELETE FROM t_student WHERE id = 10004; -- 删除也可以

  UPDATE,INSERT,DELETE,都是可以的。INSERT的时候,如果之增加部分字段的值,如果未增加的字段没有默认值,且不能为空,则报错。

  2、带有id的部分字段

    视图定义如下:

CREATE OR REPLACE VIEW t_student2 AS 
SELECT  id, name, age FROM student;

  该视图查询student表中的id,name,age字段的记录,进行更新的语句如下:

INSERT INTO t_student2 VALUES ( 4,wangwu, 30); -- 插入时如果其他字段有默认值,可以插入,如果没有就报错
UPDATE t_student2 SET name=王五2 where id=4; -- 更新可以
DELETE FROM t_student2 WHERE id = 4; -- 删除也可以

  由于student表中password字段默认值为null,所以INSERT的时候password没有赋值,也是可以增加的,UPDATE和DELETE也是成功的。

  3、不带有id的部分字段

    视图定义如下:

CREATE OR REPLACE VIEW t_student3 AS 
SELECT  name, age  FROM student;

  该视图查询student表中的name,age字段的记录,进行更新的语句如下:

1 INSERT INTO t_student3 VALUES (wangwu, 30); -- id 没有默认值,不能插入
2 UPDATE t_student3 SET age=40 where name=wangwu; -- 更新可以
3 DELETE FROM t_student3 WHERE name = wangwu; -- 删除可以

  INSERT的时候id没有默认值,所以失败。UPDATE和DELETE都成功。

二、视图包含两张表

  1、使用了group by分组查询

    查询所有人各科成绩

CREATE OR REPLACE VIEW t_student_score AS  -- 创建或者替换视图
SELECT 
    s.name,
    sum(if(a.name = c++, score, 0)) as c,
    sum(if(a.name = java, score, 0)) as java,
    sum(if(a.name = lisp, score, 0)) as lisp
FROM 
    course  AS a,
    student s 
WHERE
    a.stu_no = s.id
GROUP BY 
    a.stu_no;

    要执行的更新语句如下:

1 INSERT INTO t_student_score VALUES (wangwu, 30, 40, 50); -- [Err] 1471 - The target table t_student_score of the INSERT is not INSERTable-into
2 UPDATE t_student_score SET c=40 where name=张三; -- [Err] 1288 - The target table t_student_score of the UPDATE is not updatable
3 DELETE FROM t_student_score WHERE name = 张三; -- [Err] 1288 - The target table t_student_score of the DELETE is not updatable
4  

   第一行INSERT,增加name,以及各科成绩。因为视图中的记录使用到了分组语句进行查询,索引无法进行增加,UPDATE和DELETE也一样会报错。

  2、没有使用group by等分组查询

    视图的定义如下:

CREATE OR REPLACE VIEW t_student_score2 AS
SELECT 
    c.id AS id,
    c.stu_no AS stu_no,
    s.name AS stu_name,
    c.name  AS course_name,
    c.score AS score
FROM 
    course AS c,
    student AS s 
WHERE
    c.stu_no = s.id;

  查询student表的id,stu_no,name,course表的name,score。

   要进行的更新语句如下:

INSERT INTO t_student_score2 (id, stu_no, course_name, score) VALUES (8,10001,c, 80);  -- 只能将结果插入单个表中,且插入的自动包含表中的所有不为空的字段(与其他表的关联字段设置的值,也必须是其他表中存在的)
UPDATE t_student_score2 SET score = 88 WHERE course_name = c; -- 可以更新
DELETE FROM t_student_score2 WHERE course_name = c; -- 不能删除

  对于多表可更新视图,如果是将其插入单个表中,INSERT能够工作。UPDATE也是可以的但不支持DELETE。

三、总结

  对于直接用sql语句去更新视图的的时候,有些时候是可以成功,有些时候不会。这 取决于视图的结构。

  视图内容是单表的时候,UPDATE,DELETE可以执行成功,对于INSERT如果未设值的字段都有默认值,或者是可以为空的字段的时候可以执行成功,否则会执行失败。对

  视图内容是两种或两张表以上的时候,如果使用了分组查询语句的时候,INSERT,updat,DELETE都会执行失败。如果没有使用分组查询语句的时候UPDATE是可以执行成功,DELETE会失败。INSERT只能将结构插入当个表中,所以插入的字段只能都在一张表中,而且未设置的字段都有默认值,或者是可以为空的字段的时候才可以执行成功,否则会执行失败。 

视图之二--视图中数据的更新

标签:style   blog   color   io   使用   java   ar   for   数据   

原文地址:http://www.cnblogs.com/always-online/p/3955921.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!