用游标来指代一个DML SQL操作返回的结果集。即当一个对数据库的查询操作返回一组结果集时,用游标来标注这组结果集,以后通过对游标的操作来获取结果集中的数据信息。在plsql中要获取多行的结果集必须要用游标来获取。
1.创建游标
CURSOR 游标名 IS select语句
显性游标
1.显性游标的固定步骤
打开游标:open 游标名
获取值 : fetch 游标名 into 变量 --每次取一行给变量
关闭游标:close 游标名
2.显性游标属性
游标名%found:当最近一次读记录时返回成功提取到数据,返回值为TRUE;
游标名%notfound:当最近一次读记录时为空时未取到数据,则返回值为TRUE;
游标名%rowcount:返回INSERT、UPDATE、或DELETE所影响的行数以及由SELECT INTO所选择的行数
游标名%isopen:检测游标是否打开,当游标已打开时返回TRUE;
3.简单案例(打印emp表中员工编号和员工姓名)
显性游标+loop循环(游标无参)
declare
v_no number(5);
v_name varchar2(20);
–创建游标
cursor emp is select empno,ename from emp;
begin
–打开游标
open emp;
loop
–获取值
fetch into v_no,v_name;
exit when emp%notfound;
dbms_output.put_line(vno || ’ ’ || v_name);
end loop;
–关闭游标
–close emp;
end;
显性游标(游标传参)
declare
–定义一个游标,并指定循环列表
cursor c_cursor(id number) is select * from student stu_id=id;
–定义收参
v_info student%rowtype;
begin
–打开游标,并传入参数
open c_cursor(1);
loop
fetch c_cursor into v_info;
exit when c_cursor%notfound;
dbms_output.put_line(v_info.stu_id);
end loop;
–关闭游标
close c_cursor;
end;
隐性游标
1、对于非查询语句,如修改、删除操作,则由ORACLE系统自动地为这些操作设置游标并创建其工作区,这些由系统隐含创建的游标称为隐性游标,这是ORACLE系统定义的。
2、对于隐性游标的操作,如定义、打开、取值及关闭操作,都由ORACLE系统自动完成,无需用户进行处理。用户只能通过隐性游标的相关属性,来完成相应操作。
3、隐性游标属性
SQL%FOUND
SQL%NOTFOUND
SQL%ROWCOUNT
SQL%ISOPEN (总是FALSE) 因为隐性的不需要打开这一步骤
INSERT、UPDATE、DELETE、以及由SELECT INTO所影响的行,都由隐性游标
4、案例
//查看更新几条数据
declare
begin
update emp set deptno=11 where deptno=10;
if sql%notfound then
dbms_output.put_line(‘没有找到该条数据’);
else
dbms_output.put_line(‘更新了’ || sql%rowcount || ‘数据’);
end if;
end;
触发器
触发器是指被隐含执行的存储过程,它可以使用PL/SQL进行开发,当发生特定案件(如修改表、创建对象、登录到数据库)时,ORACLE会自动执行触发器的相应代码。
触发器类型
1、DML触发器
在对数据库表进行DML,(INSERT、UPDATE、DELETE)操作时触发并且可以对每行或语句操作上进行触发。
2、替代触发器
是Oracle8专门进行视图操作的一种触发器
3、系统触发器
对数据库系统事件进行触发,如启动、关闭等
注意事项
1、触发器不接受参数
2、一个表上最多可有12个触发器,但同一时间、同一事件、同一类型的触发器只能有一个,并各类触发器之间不能有矛盾
3、在一个表上的触发器越多,对在该表上的DML操作的性能影响就越大
4、触发器最大为32kb,若确实需要,可以先建立过程,然后在触发器中使用CALL语句进行调用
5、触发器中不能包含事务控制语句( COMMIT、ROLLBACK、SAVEPOINT)。因为触发器是触发语句的一部分,触发语句被提交,回退时,触发器也被提交、回退了。在触发器主体中调用的任何过程、函数,都不能使用事务控制语句
触发器结构
CREATE [OR REPLACE] TRIGGER 触发器名称
BEFORE | AFTER
DELETE | INSERT | UPDATE [OF 列名字]
ON 表名
[FOR EACH ROW [ WHEN (条件)]]
PLSQL块
表头复制
create table dept_log as select * from dept where 1=2;
DML触发器
删除案例
create or repeclace trigger tr_del_student
–指定触发时机为删除操作前触发
before delete
on student
–说明创建的是行级触发器
for each row
begin
–将修改前的数据插入到日志记录表中,确保SQL语句可以正常工作
insert into student_log values(:old.stu_id,:old.stu_name,:old.stu_age,:old.stu_sex,:old.stu_class,:old.stu_create_date)
end;
删除触发器
drop trigger tr_del_student;
系统触发器
创建日志表
create table log_even(
log_type varchar2(20),
username varchar2(20),
logonTime date,
logoffTime date
);
登录触发器
create or replace trigger logon_trigger
after logon
on database
begin
–记录数据类型
insert into log_even(log_type,username,logoTime,)
values(‘logon’,ora_login_user,sysdate);
end;
退出触发器
create or replace trigger logoff_trigger
before logoff
on database
begin
insert into log_even(log_type,username,logoffTime)
values(‘logoff’,ora_login_user,sysdate);
end;
语句级触发器和行级触发器
语句级触发器:在指定的操作语句操作之前或者之后执行一次,不管这语句影响了多少行针对的是表
航级触发器:触发语句作用的每一条记录都被触发,在行级触发器中使用 :old和·:new伪记录变量,识别值的状态
针对行级触发器:
1、:old 和 :new代表同一条记录
2、:old表示操作执行之前,在这一行的值, :new表示操作之后,在这一行的值
raise_application_error 自定义错误代码区间是-2000到-20999
plsql游标和触发器
最新推荐文章于 2022-08-11 19:59:11 发布