分页查询,就是将将过多的结果在有限的界面上分好多页来显示,这个是很多网站常用的功能,也是最基本的功能.
本教程是循序渐进的过程,分页查询前,先复习一下存储过程
--创建表
create table book (bookid number,bookname varchar2(50),publishname varchar2(50)) --创建无返回值过程 --in表示这个是输入参数,默认是in create or replace procedure sp_prol(spBookId in number,spName in varchar2,spPublish in varchar2) is begin insert into book values(spBookId,spName,spPublish);
end;
java代码调用
//创建CallableStatemet
call = ct.prepareCall("{call sp_prol(?,?,?)}");
//给问号赋值
call.setInt(1, 1);
call.setString(2, "笑傲江湖");
call.setString(3, "人民出版社");
//执行程序
call.execute();
--有输入和输出的存储过程
--out表示输出参数
create or replace procedure sp_pro2 (spno in number,spName out varchar2,spSal out number,spJob out varchar2) is begin select ename,sal,job into spName,spSal,spJob from emp where emp.empno=spno;
end;
java代码调用
//创建CallableStatemet
call = ct.prepareCall("{call sp_pro2(?,?,?,?)}");
//给第一个数赋值
call.setInt(1, 7499);
//取出数,相当于注册输出参数
call.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);
call.registerOutParameter(3,oracle.jdbc.OracleTypes.VARCHAR);
call.registerOutParameter(4,oracle.jdbc.OracleTypes.VARCHAR);
//执行
call.execute();
System.out.println("执行完毕");
//取出返回值,在执行之后,且注意顺序
System.out.println(call.getString(2)+call.getInt(3)+call.getString(4));
返回值是结果集的话,需要使用游标,这个时候需要先定义一个包,在包里面定义一个游标,存储过程再引用包的游标即可
--可以返回一个结果集
--必须要使用pagkage
--第一步创建包
create or replace package sp_pac1 as--这里是as --定义一个游标 type test_cursor is ref cursor;
end sp_pac1;
--第二步创建存储过程
create or replace procedure sp_pro3 --定义输入和输出游标 (spNo in number,sp_cursor out sp_pac1.test_cursor) is begin --打开游标 open sp_cursor for SELECT * FROM emp WHERE deptno=spNo;
end;
java代码调用
//创建CallableStatemet
call = ct.prepareCall("{call sp_pro3(?,?)}");
//设置参数
call.setInt(1, 10);
//注册输出参数为游标
call.registerOutParameter(2, OracleTypes.CURSOR);
//执行
call.execute();
//得到结果集
ResultSet rs = (ResultSet) call.getObject(2);
//循环打印输出
while(rs.next()){
System.out.println(rs.getInt(1)+" "+rs.getString(2));
}
首先是分页查询方法,oracle里面推荐使用rownum指令,这个指令对查询出来的结果进行排序,把排序出来的当成子表,即可实现范围查询
1.对表格按顺序排序
select t1.*,rownum rn from (select * from emp) t1 where rownum<10
2.把排序后的当成子视图
select * from (select t1.*,rownum rn from (select * from emp) t1 where rownum<10) where rn>6 ;
这样就可以实现分页查询了.下面写成存储过程
--开始编写分页过程
create or replace procedure sp_pro4
( tabName in varchar,
sp_size in number,--要查询的大小
sp_page in number,--要显示的页
myrows out number,--总记录数
mypagecount out number,--总页数
my_cursor out sp_pac1.test_cursor
) is
--定义一个sql语句
v_sql varchar2(1000);
--定义两个整数,保存起始和结束位置
v_begin number:=(sp_page-1)*sp_size+1;
v_end number:=sp_page*sp_size;
begin
--执行部分,给v_sql赋值
v_sql:=' select *
from (select t1.*,rownum rn from (select * from '||tabName||' order by sal) t1
where rownum<='||v_end||')
where rn>='||v_begin ;
--把游标和sql语句结合
open my_cursor for v_sql;
--计算myrows和mypagecount
--先创建sql语句
v_sql:='select count(*) from '||tabName;
--执行sql语句,并把返回值赋给myrows
execute immediate v_sql into myrows;
--计算mypagecount
if mod(myrows,sp_size)=0
then mypagecount:=myrows/sp_size;
else
mypagecount:=myrows/sp_size+1;
end if;--结束if
--这里如果关闭游标,则java中无法取出结果集
end;
java代码调用
//创建CallableStatemet
call = ct.prepareCall("{call sp_pro4(?,?,?,?,?,?)}");
//设置输入参数
call.setString(1, "emp");
call.setInt(2, 4);
call.setInt(3, 1);
//设置输出参数
call.registerOutParameter(4, OracleTypes.NUMBER);
call.registerOutParameter(5, OracleTypes.NUMBER);
call.registerOutParameter(6, OracleTypes.CURSOR);
//执行
call.execute();
//输出总数和总页数
System.out.println("总记录数"+call.getInt(4)+"--总页数"+call.getInt(5));
//循环取出表
ResultSet rs = (ResultSet) call.getObject(6);
while(rs.next()){
for (int i = 0; i < 7; i++) {
System.out.print(rs.getString(i+1)+" ");
}
System.out.println();
}