编写分页过程,就需要将包,游标,过程,SQL结合起来:
以下案例虽然能够实现,但总感觉还有点不足,后期修改
脚本:
--删除表
drop table book;
--创建表book
create table book (bid number,bname varchar2(50),bhouse varchar2(50));
--插入数据
insert into book(bid,bname,bhouse) values(1,'笑傲江湖','人民出版社');
insert into book(bid,bname,bhouse) values(2,'钢铁是怎样炼成的','人民出版社');
insert into book(bid,bname,bhouse) values(3,'平凡的世界','人民出版社');
commit;
下面看案例:
--创建包,定义一个游标
create or replace package sp_package as
type tesc_cursor is ref cursor;
end sp_package;
--创建过程
create or replace procedure feny(
spname in varchar2,--分页的表名
spsize in number,--每页显示的记录数
sppagenow in number,--当前页
spzongjls out number,--总记录数
spzongys out number,--总页数
spyoub out sp_package.tesc_cursor --游标
)is
--定义部分
--定义一个sql语句 字符串
v_sql varchar2(1000);
--定义两个整数,用于计算总记录数和总页数
v_begin number:= (sppagenow-1)*spsize;
v_end number:= sppagenow*spsize;
begin
--执行部分
--编写分页SQL语句,存储到v_sql变量中
v_sql:='select bid,bname,bhouse
from (select tab.*,rownum rn
from (select * from '||spname ||') tab
where rownum <='||v_end||') temp
where temp.rn >'||v_begin;
--打开游标
open spyoub for v_sql;
--计算总记录数
v_sql:='select count(*) from '||spname;
--执行sql语句并把返回的值赋给spzongjls
execute immediate v_sql into spzongjls;
--计算总页数
if mod(spzongjls,spsize ) = 0 then
spzongys :=spzongjls/spsize ;
else
spzongys :=spzongjls/spsize+1 ;
end if;
--关闭游标
--close spyoub
end;
在SQL中调用:
declare
spname varchar2(50):='book';--表名
spsize number:=3;--每页显示的记录数
sppagenow number:=1;--当前页
spzongjls number;--总记录数
spzongys number;--总页数
spyoub sp_package.tesc_cursor; --游标
--定义三个变量,用于接收分页的数据
v_bid book.bid%type;
v_bname book.bname%type;
v_bhouse book.bhouse%type;
begin
--调用过程
feny(spname,spsize,sppagenow,spzongjls,spzongys,spyoub);
loop
--将游标获取到的数据传到变量
fetch spyoub into v_bid,v_bname,v_bhouse;
--判断spyoub是否为空
exit when spyoub%notfound;
dbms_output.put_line('书号:'||v_bid||'书名:'||v_bname||'出版社:'||v_bhouse);
end loop;
dbms_output.put_line('总记录:'||spzongjls);
dbms_output.put_line('总页数:'||spzongys);
end;
或者将过程包装成一个包体:
--创建包规则,定义游标和分页过程
create or replace package sp_package is
type tesc_cursor is ref cursor;
procedure feny(
spname in varchar2,--分页的表名
spsize in number,--每页显示的记录数
sppagenow in number,--当前页
spzongjls out number,--总记录数
spzongys out number,--总页数
spyoub out tesc_cursor --游标
);
end sp_package;
--创建包体
create or replace package body sp_package is
procedure feny(
spname in varchar2,--分页的表名
spsize in number,--每页显示的记录数
sppagenow in number,--当前页
spzongjls out number,--总记录数
spzongys out number,--总页数
spyoub out tesc_cursor --游标
)is
--定义部分
--定义一个sql语句 字符串
v_sql varchar2(1000);
--定义两个整数
v_begin number:= (sppagenow-1)*spsize;
v_end number:= sppagenow*spsize;
begin
--执行部分
v_sql:='select bid,bname,bhouse
from (select tab.*,rownum rn
from (select * from '||spname ||') tab
where rownum <='||v_end||') temp
where temp.rn >'||v_begin;
--打开游标
open spyoub for v_sql;
--计算总记录数
v_sql:='select count(*) from '||spname;
--执行sql语句并把返回的值赋给spzongjls
execute immediate v_sql into spzongjls;
--计算总页数
if mod(spzongjls,spsize ) = 0 then
spzongys :=spzongjls/spsize ;
else
spzongys :=spzongjls/spsize+1 ;
end if;
--关闭游标
--close spyoub
end;
end;
编写一个过程测试分页实例
create or replace procedure ces (spname varchar2,spsize number,sppagenow number) is
spzongjls number(5);--总记录数
spzongys number(5);--总页数
spyoub sp_package.tesc_cursor; --游标
v_bid book.bid%type;
v_bname book.bname%type;
v_bhouse book.bhouse%type;
begin
sp_package.feny(spname,spsize,sppagenow,spzongjls,spzongys,spyoub);
loop
fetch spyoub into v_bid,v_bname,v_bhouse;
--判断spyoub是否为空
exit when spyoub%notfound;
dbms_output.put_line('书号:'||v_bid||'书名:'||v_bname||'出版社:'||v_bhouse);
end loop;
dbms_output.put_line('总记录:'||spzongjls);
dbms_output.put_line('总页数:'||spzongys);
end;
--调用测试过程
exec ces('book',3,1);