视图和触发器部分

1.  视图定义:视图是从一个或几个基本表(或视图)导出的表,它与基本表不同,是一个虚表,数据库中只存放视图的定义。一旦基本表的数据发生变化,从视图中查询也会变换。

   1. 建立视图

create view <视图名>[(列名)[,<列名>...)]
as <子查询>
[with check option]

   其中子查询可以是任意的 select 语句是否能有order by 字句和distinct 短句取决于具体的系统。

   with check option 表示对于视图进行update,insert,delete的时候要保证更新,插入,删除的行为满足视图定义中的谓词条件(即子查询中的条件表达式)

   组成视图的属性列名或者全部省略或者全部指定。如果省略视图的各个属性列名,则隐含该视图由子查询中select 字句目标列中的诸字段组。但是出现以下情况是必须明确指定

   (1)某个目标列不是单纯的属性名,而是聚集函数或者列表达式

   (2)多表连接的时候选出了几个同名列作为视图的字段

   (3)需要在视图中为某个列启用新的更合适的名字

   给个例子看下:(就这是最基本的视图的创建)

create view V_view1_J122
as
select * from T_stud_J122
where 'U'||sno=user or 'U'||mno=user or 'U'||majorno=user;

   下面就是多表连接,需要指定的那种

create view is_si(sno,sname,grage)
as
select Student.sno,sname,grade
from Student,SC
where Sdep="is" and Student.sno=SC.sno 
and SC.cno="1";

   2. 查询视图

   建立了视图就可以像基本表一样进行查询

   但是在不同用户查询对应的视图的时候要加上你创建视图的用户

select * from U_J122.V_view1_J122;

   3. 更新视图

   更新视图是是指通过视图来插入,删除和修改数据,但是由于视图是虚表,所以视图的更新实质上还是对于基本表的更新,但是不建议用视图去更新数据。

   要修改的话最好加上with check option 这样的话在通过视图更新数据的时候,不会更新掉不属于该视图范围的数据。

   注意:并不是所有的视图都是可更新的。

   因为通过视图的更新语句最后还是要转换为对于基本表更新的语句,但是有时候视图的更新不能唯一的有意义的转换成对应基本表的更新。

   注意不允许更新和不可更新是有区别的。

   不允许更新的七种情况:

    1. 若视图是由两个以上基本表导出的,则此视图不允许更新。

    2. 若视图的字段来自字段表达式或常数,则不允许对此视图执行INSERT和UPDATE操作,但允许执行DELETE操作。

    3. 若视图的字段来自集函数,则此视图不允许更新。

    4. 若视图定义中含有GROUP BY子句,则此视图不允许更新。

    5. 若视图定义中含有DISTINCT短语,则此视图不允许更新。

    6. 若视图定义中有嵌套查询,并且内层查询的FROM子句中涉及的表也是导出该视图的基本表,则此视图不允许更新。例如将成绩在平均成绩之上的元组定义成一个视图GOOD_SC: CREATE VIEW     GOOD_SC AS SELECT Sno, Cno, Grade FROM SC WHERE Grade> (SELECT AVG(Grade) FROM SC);   导出视图GOOD_SC的基本表是SC,内层查询中涉及的表也是SC,

    所以视图GOOD_SC是不允许更新的。

    7. 一个不允许更新的视图上定义的视图也不允许更新。

   4. 视图的作用

    1.视图能够简化用户的操作

    2.视图使用户能以多种角度看待同一数据

    3.视图对重构数据库提供一定程度的逻辑独立性‘   

    4.视图能够对机密数据提供安全保护

    5.适当利用视图可以更清晰地表达查询

2.  触发器

    1. 触发器是用户定义在关系表上的一类由事件驱动的特殊过程(事情—条件—动作规则)。一旦定义,触发器会保存在数据库的服务器中,任何用户对于表的增删改操作都会自动触发相应的触发器。

    2. 定义触发器

create trigger <触发器名>
{before | after}<触发事件> on <表名> /*指明触发器激活的时间是执行触发事件前后*/
 
referencing new | old row as <变量> /*指出引用的变量*/
for each {row | statement} /*定义触发器的类型,指明动作体执行的频率*/
[when <触发条件>]<触发动作体>

     实例:

create trigger tg_T_attend_J122
    before insert or update or delete on T_attend_J122
    for each row
declare
    mnewscore binary_integer;
    moldscore binary_integer;
begin 
    if inserting then
        select score into mnewscore from T_attendscore_J122 where mstatus=:new.mstatus;
        update T_stud_J122 set sum_evaluation=nvl(sum_evaluation,0)+mnewscore where T_stud_J122.sno=:new.sno;
    elsif updating then
        select score into mnewscore from T_attendscore_J122 where mstatus=:new.mstatus;
        select score into moldscore from T_attendscore_J122 where mstatus=:old.mstatus;
        update T_stud_J122 set sum_evaluation=nvl(sum_evaluation,0)-moldscore where T_stud_J122.sno=:old.sno;
        update T_stud_J122 set sum_evaluation=nvl(sum_evaluation,0)+mnewscore where T_stud_J122.sno=:new.sno;
    else 
        select score into moldscore from T_attendscore_J122 where mstatus=:old.mstatus;
        update T_stud_J122 set sum_evaluation=nvl(sum_evaluation,0)-moldscore where T_stud_J122.sno=:old.sno;
    end if;
end;

     3. 触发器的执行

      触发器的执行由触发事件执行,如果一个表上定义了多个触发器。执行顺序是先执行表上的before触发器,激活触发器的sql语句,再执行表上的after触发器。  

      对于同一个表的多个before , after 触发器按创建的顺序来进行。

    4. 删除触发器

dalete trigger <触发器名> on <表名>

 

posted @ 2019-01-08 13:54  从让帝到the_rang  阅读(441)  评论(0编辑  收藏  举报