昨天刚写了一个存储过程的分页,oracel里面和sqlserver可真的不太一样,利用rownum完成。
解决方案 »
- 奇怪的oracleu问题
- ?????帮助偶解决存储过程速度慢的问题的200分都给您老,没有第二!
- Oracle Job 调用的存储过程 Inser语句为啥不能执行!!
- Oracle 执行分区时报错
- 请各位高手帮忙:程序包没有权限
- 求sql语句:同时取主表数据及从表中最新的一条数据
- oracle访问问题,纳闷中……
- oracle for unix5.0.5监听程序无法启动,大家帮忙看看!
- 一个关于sql脚本的问题
- oracle中为什么调用存储过程在表中插入一条数据时,实际插入了两条
- 高技术问题:oracle数据库的OCCI技术,目前只有VC的,问有没有C++BUILDER
- oracle建立表的时候 按定义列和按索引组织的表有什么区别?
iPagesize number,--每页记录数
iCurrentpage number,--当前页码
strSql varchar2, --最终语句
iRecordCount out number, --总记录数
iPagenum out number, --输出总页码
oFlag out number, --操作正确标志
sFlag out varchar2,
v_cur out Pkg_cursor.cur
)
as
tmpSql varchar2(500);
tmpNum number(9,2);
tmpRow number;
tmpPageSize number;
begin tmpSql:='select * from ('|| strSql ||')';
execute immediate tmpSql;
execute immediate 'select count(1) from ('|| tmpSql ||')' into iRecordCount;
if iRecordCount=0 then --没有记录
oFlag:=16;
iPagenum:=0;
open v_cur for tmpSql; --返回空纪录
return;
end if; if iRecordCount<iPagesize then --所有记录只有一页
oFlag:=17;
iPagenum:=1;
open v_cur for tmpSql;
return;
end if; --计算总页数
tmpNum:=iRecordCount/iPagesize;
if tmpNum>trunc(tmpNum) then
iPagenum:=trunc(tmpNum)+1;
else
iPagenum:=trunc(tmpNum);
end if;
oFlag:=18;
if(iCurrentpage>iPagenum or iCurrentpage<1) then --页码不对
oFlag:=19;
oFlag:=3; --页码不对
open v_cur for 'select 1 from sys_users where rownum<1';
return;
end if; --计算第一个iRow
if iCurrentpage=1 then
tmpRow:=1;
else
tmpRow:=(iCurrentpage-1)*iPagesize+1;
end if;
tmpPageSize:=iPagesize+1;
tmpSql:=tmpSql || ' where rownum<'|| tmpPageSize ||' and iRow>='|| tmpRow;
sFlag:=tmpSql;
open v_cur for tmpSql;
oFlag:=iPagenum; exception
when others then
begin
--oFlag:=0; --操作失败
open v_cur for 'select 1 from sys_users where rownum<1';
end;end;
已经测试通过,要求传入的sql:例如:select rownum rowid,a.col....from fds a........
select * from (select rownum id,tbname.* from tbname where rownum<21) t
where t.id>10;
排序的话需要再嵌套一层
(
iPagesize number,--每页记录数
iCurrentpage number,--当前页码
strSql varchar2, --最终语句
iRecordCount out number, --总记录数
iPagenum out number, --输出总页码
oFlag out number, --返回操作标志
v_cur out Pkg_cursor.cur
)
as
tmpSql varchar2(500);
tmpNum number(9,2);
tmpRow number;
tmpPageSize number;
begin tmpSql:='select * from (select rownum iRow,a.* from ('|| strSql ||') a)';
execute immediate tmpSql;
execute immediate 'select count(1) from ('|| tmpSql ||')' into iRecordCount;
if iRecordCount=0 then --没有记录
oFlag:=16;
iPagenum:=0;
open v_cur for 'select 1 from sys_users where rownum<1'; --返回空纪录
return;
end if; if iRecordCount<iPagesize then --所有记录只有一页
oFlag:=17;
iPagenum:=1;
open v_cur for tmpSql;
return;
end if; --计算总页数
tmpNum:=iRecordCount/iPagesize;
if tmpNum>trunc(tmpNum) then
iPagenum:=trunc(tmpNum)+1;
else
iPagenum:=trunc(tmpNum);
end if;
oFlag:=18;
if(iCurrentpage>iPagenum or iCurrentpage<1) then --页码不对
oFlag:=19;
oFlag:=3; --页码不对
open v_cur for 'select 1 from sys_users where rownum<1';
return;
end if; --计算第一个iRow
if iCurrentpage=1 then
tmpRow:=1;
else
tmpRow:=(iCurrentpage-1)*iPagesize+1;
end if;
tmpPageSize:=iPagesize+1;
tmpSql:=tmpSql || ' where rownum<'|| tmpPageSize ||' and iRow>='|| tmpRow; open v_cur for tmpSql;
oFlag:=iPagenum; exception
when others then
begin
--oFlag:=0; --操作失败
open v_cur for 'select 1 from sys_users where rownum<1';
end;end;
例如:我要取出emp表中sal排在第5-10位的信息SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
--------- ---------- --------- --------- ---------- --------- --------- ---------
7369 SMITH CLERK 7902 17-12月-80 800 20
7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
7566 JONES MANAGER 7839 02-4月 -81 2975 20
7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30
7698 BLAKE MANAGER 7839 01-5月 -81 2850 30
7782 CLARK MANAGER 7839 09-6月 -81 2450 10
7839 KING PRESIDENT 17-11月-81 5000 10
7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30
7900 JAMES CLERK 7698 03-12月-81 950 30
7902 FORD ANALYST 7566 03-12月-81 3000 20
7934 MILLER CLERK 7782 23-1月 -82 1300 10已选择12行。SQL> select rownum id,emp.ename,emp.sal from emp order by sal desc; ID ENAME SAL
--------- ---------- ---------
8 KING 5000
11 FORD 3000
4 JONES 2975
6 BLAKE 2850
7 CLARK 2450
2 ALLEN 1600
9 TURNER 1500
12 MILLER 1300
3 WARD 1250
5 MARTIN 1250
10 JAMES 950
1 SMITH 800已选择12行。SQL> select * from (select rownum id,emp.ename,emp.sal from emp order by sal desc) t
2 where id between 5 and 10; ID ENAME SAL
--------- ---------- ---------
8 KING 5000
6 BLAKE 2850
7 CLARK 2450
9 TURNER 1500
5 MARTIN 1250
10 JAMES 950已选择6行。可见这样操作是错误的!
正确写法:
SQL> select * from (select rownum id,emp.ename,emp.sal from (select * from emp order by sal desc)
2 emp where rownum<=10) where id>=5; ID ENAME SAL
--------- ---------- ---------
5 CLARK 2450
6 ALLEN 1600
7 TURNER 1500
8 MILLER 1300
9 WARD 1250
10 MARTIN 1250已选择6行。SQL>
2 emp where rownum<=10) where id>=5;
我感觉是一样的。你觉得呢,如果一样哪个的效率高一点。
这个效率高?!