1、实验07 游标存储过程触发器实验七 游标,存储过程,触发器Sqlplus /nologconn scott/tigerdeclare cursor mycur isselect * from emp;myrecord emp%ROWTYPE;beginopen mycur;fetch mycur into myrecord;while mycur%FOUND loopdbms_output.put_line(myrecord.empno|,|myrecord.ename);fetch mycur into myrecord;end loop;close mycur;end;/save c:pl
2、sql_cursor01.txt带参数的游标,%NOTFOUND属性declarecursor cur_para(id varchar2) isselect ename from emp where empno=id;t_name emp.ename%TYPE;beginopen cur_para(7369);loopfetch cur_para into t_name;exit when cur_para%NOTFOUND;dbms_output.put_line(t_name);end loop;close cur_para;end;/用FOR循环实现declarecursor cur_p
3、ara(id varchar2) isselect ename from emp where empno=id;begindbms_output.put_line(*结果*);for cur in cur_para(7369) loopdbms_output.put_line(cur.ename);end loop;end;/%ISOPEN属性declaret_name emp.ename%TYPE;cursor cur(id varchar2) isselect ename from emp where empno=id;beginif cur%ISOPEN thendbms_output.
4、put_line(游标已打开);elseopen cur(7369);end if;fetch cur into t_name;close cur;dbms_output.put_line(t_name);end;/%ROWCOUNT属性declaret_name varchar2(10);cursor mycur isselect dname from dept;beginopen mycur;loopfetch mycur into t_name; -一开始可以不要这句试下,然后要这一句试下。exit when mycur%NOTFOUND or mycur%NOTFOUND is nul
5、l;dbms_output.put_line(游标mycur的rowcount是:|mycur%ROWCOUNT);end loop;close mycur;end;/利用游标修改数据declarecursor cur isselect dname from dept for update;text varchar2(10);beginopen cur;fetch cur into text;while cur%FOUND loopupdate dept set dname=dname|_t where current of cur;-判断当前行fetch cur into text;end
6、loop;close cur;end;/验证数据是否发生了变化select * from dept;rollback;数据回滚隐式游标的使用beginfor cur in(select dname from dept) loopdbms_output.put_line(cur.dname);end loop;end;/看不到游标的申明,打开和关闭。数据量很大时不建议使用游标。过程create or replace procedure myproc(id varchar2(10) 如果编译错会提示,可以查询错误信息show error show error procedure myproc;sa
7、ve c:plsql_proc01.txt将第一句改为create or replace procedure myproc(id varchar2) 默认为IN isname varchar2(10);beginselect ename into name from emp where empno=id;dbms_output.put_line(name);end myproc; -名称为可选/执行declaretid varchar2(10);begintid:=7369;myproc(tid);end;/也可以beginmyproc(7369);end;/甚至可以单独执行存储过程execu
8、te myproc(7369);但要求存储过程不带参数,或参数只能是IN,且为常量beginexecute myproc(7369);-这是错误的end;/输出参数的使用create or replace procedure myproc2(id varchar2,name out varchar2)isbeginselect ename into name from emp where empno=id;end;/declare tid varchar2(10);tname varchar2(10);begintid:=7369;myproc2(tid,tname);dbms_outpu.p
9、ut_line(tname);end;触发器可以看成一个过程,但自动完成。当数据进行增,删,改时,可以触发。存储在数据库中。当事件发生时,会显式调用触发器触发器不能带参数比如维护表的强制性约束数据操作元触发器 行级触发器 语句级触发器 替换触发器数据定义元触发器系统触发器触发器:事件+对象(表)+条件+执行语句体事务介绍:SQLselect * from emp;作一个删除SQLdelete from emp where empno=7876;SQLcommit; -语句真正的写到了数据库中SQLselect * from emp;SQLdelete from emp where empno=
10、7900;SQLselect * from emp;查到是删除了。但SQLrollback;SQLselect * from emp;删除的又回来了。确保事务完整性事务的四个特性:原子性,一致性,隔离性,永久性事务的原子性表的增删改都可能改变表的结果,对于一个单表而言,比如DELETE,要不删除成功,要不删除失败,比如:SQLdelete from emp where empno=7902;由于本身只有一个表,所以,本身就是原子的,因为一个表无法分割,要不成功,要不失败。事务的原子性是指对两个或两个以上的表,很可能对一个表成功,一个失败等四种可能,而这两个表中有很强的业务联系时,则进行两个表操
11、作时,可能出现不一致的问题,比如A转账给B,A转成功了,但B没有转成功,则会出问题。所以,必须保证都成功,如果有一个出问题,则都回滚。比如销售中销售的商品和库存中的商品要保持一致性,不能销售表成功了,但库存表中没有成功就不行。将两个表看成一个逻辑上不可分割的单元,通过事务的方式来保证,这就是原子性。可以通过触发器来完成。事务的一致性:保证操作前后,保证表的一致,A转3W到B,则转完后,前后要一致。销售也是一样的。原子性是手段,一致性是目的。事务的隔离性隔离性越强,并发性越差。隔离性越差,并发性越高隔离性有许多等级比如:只能读已提交的数据SQLdelete from emp;SQLselect
12、* from emp;看没有记录了我们打开另一个会话框用系统用户登录,再查该表,SQLselect * from emp;发现还有记录,即读不到未提交的信息。commit和rollback两个事务命令SQLdelete from emp where empno=7839;在另一个窗口还是可以看到这个数据,因为并没有提交SQLcommit; -写到数据文件中在另一个窗口中就看不到了。rollback是取消前面的功能。比如火车票售票,两个站都读到5张,卖3张,这是不可能的。因为没有6张。这就通过隔离性,在没有修改完成,对方不能读进来。SQLselect * from emp;SQLupdate e
13、mp set ename=sdfd where empno=7839;SQLselect * from emp;但对方看不到但如果我查到有5张,我还没有修改,对方已修改了,卖了3张。SQLselect * from emp for update则另一方不允许update emp set ename=adfadsf where empno=7839;通过锁的机制来实现的,先处理的用户会加锁,处理完了才能解锁,加锁后隔离性强,但并发性差了。比如:SQLupdate emp set ename=qq where empno=7839;SQLcommit;改完提交后,另一方才能改。永久性指提交了不能回
14、滚,回滚后不能提交了。因为已物理的改变了。再修改时,另一个事务又开始了。1 行级触发器delete ,insert ,update(select 由于是查询,不影响数据,所以,不会影响一致性)SQLselect * from emp;SQLselect * from dept;实现参考完整性,将部门表中的编号改掉时,员工的部门编号也要改,可以用行级触发器来实现SQLcreate or replace trigger del_deptidafter delete on deptfor each rowbegindelete from emp where deptno=:old.deptno;end del_deptid;/SQLdelete from dept where deptno=10;SQLselect * from dept;SQLselect * from emp;10的信息全没有了。SQLrollback;-回滚SQLcreate or replace trigger insert_deptafter insert on deptfor each rowbegininse
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1