1、定义
所谓存储过程(Stored Procedure),就是一组用于完成特定数据库功能的SQL语句集,该SQL语句集经过
编译后存储在数据库系统中。在使用时候,用户通过指定已经定义的存储过程名字并给出相应的存储过程参数
来调用并执行它,从而完成一个或一系列的数据库操作。
2、存储过程的创建
Oracle存储过程包含三部分:过程声明,执行过程部分,存储过程异常。
3.语法
create [or replace] procedure 存储过程名(param1 in type,param2 out type)
as
变量1 类型(值范围);
变量2 类型(值范围);
Begin
Select count(*) into 变量1 from 表A where列名=param1;
If (判断条件) then
Select 列名 into 变量2 from 表A where列名=param1;
Dbms_output。Put_line(‘打印信息’);
Elsif (判断条件) then
Dbms_output。Put_line(‘打印信息’);
Else
Raise 异常名(NO_DATA_FOUND);
End if;
Exception
When others then
Rollback;
End;
先建两个表(读者信息表,和图书信息表)
create table readerinfo(
readerid char(4) constraint pk_readerinfo_id primary key,
readername varchar2(20),
unit varchar2(20),
bookcount integer
);
create table bookinfo(
bookid char(4) constraint pk_bookid_bookinfo primary key,
readerid char(4) constraint fk_book_reade_readid references readerinfo(readerid),
bookname varchar2(20)
);
insert into readerinfo values('9701','朱三丰','计算机系',3);
insert into readerinfo values('9702','朱一丰','计算机系',4);
insert into readerinfo values('9703','朱二丰','计算机系',3);
insert into readerinfo values('9704','朱四丰','生物系',2);
insert into readerinfo values('9705','朱五丰','生物系',3);
insert into readerinfo values('9706','朱六丰','生物系',1);
insert into readerinfo values('9707','朱七丰','自动化系',3);
insert into readerinfo values('9709','朱九丰','自动化系',6);
insert into readerinfo values('9708','朱八丰','自动化系',4);
insert into bookinfo values('1000','9701','长征1');
insert into bookinfo values('1001','9701','长征2');
insert into bookinfo values('1002','9701','长征3');
insert into bookinfo values('1003','9707','长征1');
insert into bookinfo values('1004','9708','长征2');
insert into bookinfo values('1005','9709','长征1');
insert into bookinfo values('1006','9709','长征1');
insert into bookinfo values('1007','9704','长征1');
insert into bookinfo values('1008','9704','长征2');
insert into bookinfo values('1009','9704','长征3');
1:创建无参数的存储过程,给计算机系的学生的bookcount+1
create or replace procedure reader_pro
as
begin
update readerinfo set bookcount=bookcount+1 where unit='计算机系';
end;
exec reader_pro;
drop procedure reader_pro;
2:在存储过程中使用游标,搜素表中所有自动化和生物系的数据,并判断当可借书数目小于三时,加1
create or replace procedure reader_pro
as
cursor c_reader is select * from
readerinfo where unit in('生物系','自动化系') for update of bookcount nowait;
begin
for c_row in c_reader loop
if c_row.bookcount<3 then
update readerinfo set bookcount=bookcount+1 where current of c_reader;
end if;
end loop;
end;
exec reader_pro;
drop procedure reader_pro;
3:在存储过程中创建表:要求创建前先判断是否存在readerinfo_history 这个表,如果存在
删除该表记录,不存在,创建一个结构如同readerinfo 的表
create or replace procedure reader_pro
as
tag number;
mycode varchar2(1000);
begin
select count(*) into tag from all_tables where table_name='readerinfo_history' ;
mycode:='create table readerinfo_history as select * from readerinfo where 1=2';
if tag=0 then
execute immediate mycode;/*sql动态执行*/
else
execute immediate 'delete from readerinfo_history';/*必须这么写,不能直接写delete语句,否则无法通过编译*/
end if;
end;
exec reader_pro;
desc readerinfo_history;
drop table readerinfo_history;
drop procedure reader_pro;
4:创建带有参数的存储过程
要求创建一个存储过程,用于查询readerinfo表中所有读者的readerid,readername,unit,bookcount,以及其在bookinfo
表中所借图书书目
通过设置参数,使得存储过程能灵活显示读者单位unit,以及能借阅的最少读书数目min bookcount
create or replace procedure reader_pro(cunit readerinfo.unit%type,minbookcount readerinfo.bookcount%type)
as
type reader_book_rc is record(
r_readerid readerinfo.readerid%type,
r_readername readerinfo.readername%type,
r_unit readerinfo.unit%type,
r_bookcount readerinfo.bookcount%type,
r_borrownum readerinfo.bookcount%type
);
reader_book reader_book_rc;
cursor c_reader
is select r.readerid,r.readername,r.unit,r.bookcount,count(b.bookid)
from readerinfo r left outer join bookinfo b
on r.readerid=b.readerid
where r.bookcount>=minbookcount
and r.unit like cunit
group by r.readerid,r.readername,r.unit,r.bookcount
order by r.readerid;
begin
open c_reader;
loop
fetch c_reader into reader_book;
exit when c_reader%notfound;
dbms_output.put_line(reader_book.r_readerid||'-'||reader_book.r_readername||'-'
||reader_book.r_unit||'-'
||reader_book.r_bookcount||'-'
||reader_book.r_borrownum||'-'
);
end loop;
close c_reader;
end;
create or replace procedure reader_pro(cunit readerinfo.unit%type,minbookcount readerinfo.bookcount%type)
as
cursor c_reader
is select r.readerid,r.readername,r.unit,r.bookcount,count(b.bookid) borrownum
from readerinfo r left outer join bookinfo b
on r.readerid=b.readerid
where r.bookcount>=minbookcount
and r.unit like cunit
group by r.readerid,r.readername,r.unit,r.bookcount
order by r.readerid;
reader_book c_reader%rowtype;
begin
open c_reader;
loop
fetch c_reader into reader_book;
exit when c_reader%notfound;
dbms_output.put_line(reader_book.readerid||'-'||reader_book.readername||'-'
||reader_book.unit||'-'
||reader_book.bookcount||'-'
||reader_book.borrownum||'-'
);
end loop;
close c_reader;
end;
exec reader_pro('计算机系',3);
exec reader_pro('%',3);
drop procedure reader_pro;
5:创建带有输出参数的过程
eg:
create or replace procedure pro_out_elt(cunit out varchar2)
as
begin
cunit:='计算机系';
end;
6:利用5创建的过程给该过程的变量v_unit赋值
如果计算机系学生的bookcount<=4,该值加一
create or replace procedure reader_pro
as
v_unit readerinfo.unit%type;
cursor c_reader
is select r.bookcount from readerinfo r
where r.unit=v_unit
for update of bookcount;
c_row c_reader%rowtype;
begin
pro_out_elt(v_unit);
for c_row in c_reader loop
if c_row.bookcount<=4 then
update readerinfo set bookcount=bookcount+1 where current of c_reader;
end if;
end loop;
end;