游标和触发器
1. 游标的定义
在PL/SQL块中执行SELECT、INSERT、DELETE和UPDATE语句时,ORACLE会在内存中为其分配上下文区(Context Area),即缓冲区。游标是指向该区的一个指针,或是命名一个工作区(Work Area),或是一种结构化数据类型。它为应用等量齐观提供了一种对具有多行数据查询结果集中的每一行数据分别进行单独处理的方法,是设计嵌入式SQL语句的应用程序的常用编程方式。
游标分类
1. 显式 游标用于处理SELECT语句返回的多行数据;人为创建,干预
2. 隐式 游标用于处理SELECT INTO和非查询的DML语句;系统自动创建,管理
2. 显式游标示例练习
--游标传参,显示游标
DECLARE
-- 定义游标,指定循环列表
cursor c_cur is select * from ruanjian182;
-- 定义收参
v_info ruanjian182%rowtype;
BEGIN
-- 打开游标
open c_cur;
-- loop 循环获取.
loop
fetch c_cur into v_info;
-- 退出条件判断
exit when c_cur%notfound;
dbms_output.put_line(v_info.id || ' '||v_info.name);
end loop;
-- 关闭游标
close c_cur;
END;
3. 隐式游标示例练习
--隐式 for 循环游标:
DECLARE
-- 定义游标,指定循环列表
cursor c_cur is select * from ruanjian182;
BEGIN
for v_info in c_cur loop
dbms_output.put_line(v_info.id || ' '||v_info.name);
end loop;
END;
1. 触发器的定义
触发器是指被隐含执行的存储过程,它可以使用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 TABLE rj182_log AS SELECT * FROM ruanjian182 WHERE 1=2;
select * from ruanjian182;
select * from rj182_log;
2. DML触发器
--删除示例:
create or replace trigger tr_del_rj182
--指定触发时机为删除操作前触发
before delete
on ruanjian182
--说明创建的是行级触发器
for each row
begin
--将修改前数据插入到日志记录表,要确保SQL可以正常工作
insert into rj182_log values(:old.id,:old.name,:old.age,
:old.price,:old.createdate,:old.sex,'delete');
end;
--修改示例:
create or replace trigger tr_update_rj182
--指定触发时机为修改操作后触发
after update
on ruanjian182
for each row
begin
-- 记录修改后的值
insert into rj182_log values(:new.id,:new.name,:new.age,
:new.price,:new.createdate,:new.sex,'update');
end;
--删除触发器
drop trigger rj182_log;
3. 登录,登出触发器练习
--创建日志记录表
create table log_event(
log_type varchar2(20),
username varchar2(20),
logonTime date,
logoffTime date
);
select * from log_event;
--登录触发器 需要使用管理员账号
create or replace trigger logon_trigger
after logon on database
begin
insert into log_event(log_type,username,logonTime)
values('logon',ora_login_user,sysdate);
end;
--登出触发器 需要使用管理员账号
create or replace trigger logoff_trigger
before logoff on database
begin
insert into log_event(log_type,username,logoffTime)
values('logoff',ora_login_user,sysdate);
end;