/**
*自治事务
* 能够保存出错信息-容许用户创建一个”事务中的事务”,可以独立与父事务提交或回滚
*可用于1.顶层匿名块 2.本地(过程当中的过程)、独立或打包的函数或者过程
3.对象数据类型的方法 4.数据库触发器
结束一个自治事务必须提交一个commit/rollback/执行DDL.
【使用缘由】
由于在数据库中某些状况若是发生异常了,那数据就会自动回滚,定义一个自治事务能够把异常信息保存下来,不会被回滚
*/程序员
insert into course values('11','aaaa',null,3);
commit;
select * from course;
delete from course where cno='11';
declare
pragma autonomous_transaction;
begin insert into course values('1112','滚尼玛',null,2);
commit;
end;
rollback;
结果
web
/**
若是必须访问变异表,则能够经过使用临时表,
或者一个PL/SQL容器,或者一个包变量绕过这些限制。
*/sql
/**
(3)、在学生-课程数据库中,学生表中有“平均成绩”列SAvgGrade,要求当对选课表SC 作insert(注
意特殊状况:插入的元组中成绩字段可能为null)、delete、update 修改时,系统自动修改学生表中平均
成绩。请编写触发器实现该业务,并设计案例加以测试。
*/数据库
create global temporary table student_transaction ( sno char(9) )on commit delete rows;
create or replace trigger t1_row after delete or insert or update on sc for each row declare begin if inserting then insert into student_transaction values(:new.sno);
elsif deleting then
insert into student_transaction values(:old.sno);
else
insert into student_transaction values(:old.sno);
insert into student_transaction values(:new.sno);
end if;
dbms_output.put_line('插入成功');
end t1_row;
–建立表级触发器oracle
create or replace trigger t2_statement after delete or insert or update on sc declare cursor c is select distinct sno from student_transaction;
avg1 number(3,0);
begin for i in c loop select avg(grade) into avg1 from sc where sno=i.sno;
dbms_output.put_line('avg1 = '||avg1 ||'i.sno ='|| i.sno);
update student set student.savggrade=avg1 where sno=i.sno;
end loop;
end t2_statement;
SELECT * FROM course;
--INSERT INTO STUDENT(SNO,SNAME) VALUES('9512105','lh');
delete from sc where sno='9512105';
INSERT INTO SC VALUES('9512102','11',150); --***问题这个位置把平均成绩打印不出来
COMMIT;
SELECT * FROM student_transaction;
SELECT * FROM STUDENT;
/**
(4)、在数据库中建立视图info_view,包含学生学号、姓名、课程号、课程名、成绩。该视图依赖于表
student、course 和sc,是不可更新视图。请编写替代触发器,当向视图中插入数据时分别向表student、
course 和sc 中插入数据,从而实现向视图插入数据的功能。
**【注意】**ORACLE 为行级触发器提供两个关联名NEW 和OLD
,前者表明修改 以后的行,后者表明修改以前的行
*/svg
create or replace view info_view as select sno,sname,cno,cname,grade from student s natural join sc natural join course;
create or replace trigger TT instead of insert or update or delete on info_view REFERENCING NEW AS n --给:new关键字去一个别名 for each row --给以省略 declare begin -- IF INSERTING then insert into student(sno,sname) values(:n.sno,:n.sname);
insert into course(cno,cname) values(:n.cno,:n.cname);
insert into sc values(:n.sno, :n.cno, :n.grade);
end TT;
insert into info_view(sno,sname,cno,cname,grade) values('2015007','张飞','110','软件工程',500);
select sno,sname from student;
select cno,cname from course;
【说明】
这里在第(3)题还有一个问题遗留,就是经过查询sc表把平均成绩放大avg1变量中而后打印出来发现居然没有值,很纳闷,下次上课时候问问老师。
能够看出这里没有打印出avg1的值
问题解释:
发如今建立临时表时,咱们指定的sno字段长度是9,而在实际插入数据时,sql语句
是
能够发如今插入数据是咱们sno写的是7位数字,因此会自动补上两个空格,致使查找数据查找不到。函数
触发器为了保证数据完整性
触发器定义:
触发器(trigger)是 提供给程序员和数据分析员来保证数据完整性的一种方法
,它是与表事件相关的特殊的存储过程
,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,
触发器与存储过程的区别:
触发器与存储过程的惟一区别是触发器不能执行EXECUTE语句调用,
而是在用户执行Transact-SQL语句时自动触发执行。oop
5.1与表关联的DML触发器,主要为业务实施使用。 触发事件有DELETE,INSERT,UPDATE,MERGE 分语句级触发器 和 行级触发器 5.2与视图关联的instead of触发器 只有行级触发器,以把对视图的操做转移给基表。 5.3与SCHEMA关联的DDL触发器。 5.4与SCHEMA、数据库关联的系统触发器。
触发器与触发其的语句构成一个事务,除非使用自治事务,不然不能在触发器中出现DDL语句和事务处理语句 测试
参考文献ORACLE TRIGGER文档spa