利用for遍历游标:
declare
cursor emplist(minsal number) is select * from emp where sal > minsal;
emprow emp%rowtype;
begin
--open emplist;
for emprow in emplist(2000) loop
dbms_output.put_line(emprow.ename || '==' || emprow.sal);
end loop;
end;
此处注意:如果我们使用fetch 需要爱前面进行open操作
如果使用for,就不需要open,for可以帮我们自动open游标。
plsql异常:
plsql提供了异常机制,当哦我们程序发生异常的时候我们可以进行捕获,并且控制其相应的逻辑
declare
v_name emp.ename%type;
begin
select ename into v_name from emp ;
dbms_output.put_line(v_name);
exception
when others then
dbms_output.put_line('others....');
end;
触发器:
触发器在数据库里以独立的对象存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来启动运行。即触发器是当某个事件发生时自动地隐式运行
对于我们数据来说,在我们对数据进行增、删、改的时候的可能需要进行一些具体的验证或者阻挡操作。 check(‘男’ or ‘女’)
1、触发器分为前置触发器和后置触发器
2、按类型分为 update 、insert、 delete
create or replace trigger stu_trigger
before insert on student1
for each row
when (new.sid > 0)
declare
begin
dbms_output.put_line('student插入数据了。。。');
end;
此处注意:增加和删除不能使用 of 列名这种写法,只有修改的时候才能
触发器关键自 new old
:new:就代表DML执行成功之后的表名
old :就代表执行DML成功之前的表名
触发器通常用于级联操作,或者限制表的操作(约束) 非空,检查。唯一
所谓的级联操作就是关联操作的一种体现,当两张表有外键关系, 我们删除数据的时候需要考虑该条数据是否被另外一张表引用
所谓的级联操作就是操作两张又外键关系的表。
---级联操作
create or replace trigger banji_tri_delete
before delete on banji
for each row
when (old.bianhao>0)
declare
bianhao number := :old.bianhao;
begin
delete from student1 where banji = bianhao;
end;
delete from banji where bianhao = 2
--限制操作
create or replace trigger stu_trigger_update
before update of ssex on student1
for each row
when (new.sid>0)
declare
begin
if (:new.ssex <> '男' and :new.ssex != '女') then
raise_application_error(-20000, '性别必须是男或者女');
end if;
end;
行级触发器、表级触发器
行级:就没操作一行触发器就执行依次 + for each row
表级: 无论操作多少行,触发器只执行依次。 去掉for each row (不常用)
利用游标:存储过程实现sql分页
-- 利用过程+游标实现分页
-- 定义包(游标数据类型)
create package pkg_query
as
type cur_query is ref cursor;
end pkg_query;
create or replace procedure pager(v_start in number, v_end in number,
v_data out pkg_query.cur_query)
is
v_sql varchar(300);
v_row emp%rowtype;
begin
v_sql := 'select ename from (select t.*, rownum as r from (select * from emp order by hiredate desc) t) t1 where t1.r>'||v_start||' and t1.r<='||v_end;
open v_data for v_sql;
execute immediate v_sql;
end;
declare
v_data pkg_query.cur_query;
v_ename varchar2(20);
begin
pager(5,10,v_data);
loop
fetch v_data into v_ename ;
dbms_output.put_line(v_ename);
exit when v_data%notfound;
end loop;
end;
--分页语句
select ename from
(select t.*, rownum as r from (select * from emp order by hiredate desc) t) t1
where
t1.r>5 and t1.r<=10