亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

請問oracle該怎么實現分頁?

請問oracle該怎么實現分頁?

開滿天機 2019-08-17 11:11:41
oracle怎么實現分頁
查看完整描述

5 回答

?
繁星點點滴滴

TA貢獻1803條經驗 獲得超3個贊

select t2.*
from (select rownum r,t1.* from youtable t1 where rownum<?) t2
where t2.r>?

小于最大的,大于最小的,就是你需要的條數
如果你取40-50條之間的
只需要小于50 大于40就OK了.


查看完整回答
反對 回復 2019-08-18
?
UYOU

TA貢獻1878條經驗 獲得超4個贊

分頁查詢格式:
SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40
)
WHERE RN >= 21

其中最內層的查詢SELECT * FROM TABLE_NAME表示不進行翻頁的原始查詢語句。ROWNUM <= 40和RN >= 21控制分頁查詢的每頁的范圍。

上面給出的這個分頁查詢語句,在大多數情況擁有較高的效率。分頁的目的就是控制輸出結果集大小,將結果盡快的返回。在上面的分頁查詢語句中,這種考慮主要體現在WHERE ROWNUM <= 40這句上。

選擇第21到40條記錄存在兩種方法,一種是上面例子中展示的在查詢的第二層通過ROWNUM <= 40來控制最大值,在查詢的最外層控制最小值。而另一種方式是去掉查詢第二層的WHERE ROWNUM <= 40語句,在查詢的最外層控制分頁的最小值和最大值。這是,查詢語句如下:

SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
)
WHERE RN BETWEEN 21 AND 40

對比這兩種寫法,絕大多數的情況下,第一個查詢的效率比第二個高得多。

這是由于CBO優化模式下,Oracle可以將外層的查詢條件推到內層查詢中,以提高內層查詢的執行效率。對于第一個查詢語句,第二層的查詢條件WHERE ROWNUM <= 40就可以被Oracle推入到內層查詢中,這樣Oracle查詢的結果一旦超過了ROWNUM限制條件,就終止查詢將結果返回了。

而第二個查詢語句,由于查詢條件BETWEEN 21 AND 40是存在于查詢的第三層,而Oracle無法將第三層的查詢條件推到最內層(即使推到最內層也沒有意義,因為最內層查詢不知道RN代表什么)。因此,對于第二個查詢語句,Oracle最內層返回給中間層的是所有滿足條件的數據,而中間層返回給最外層的也是所有數據。數據的過濾在最外層完成,顯然這個效率要比第一個查詢低得多。

上面分析的查詢不僅僅是針對單表的簡單查詢,對于最內層查詢是復雜的多表聯合查詢或最內層查詢包含排序的情況一樣有效。

這里就不對包含排序的查詢進行說明了,下一篇文章會通過例子來詳細說明。下面簡單討論一下多表聯合的情況。對于最常見的等值表連接查詢,CBO一般可能會采用兩種連接方式NESTED LOOP和HASH JOINMERGE JOIN效率比HASH JOIN效率低,一般CBO不會考慮)。在這里,由于使用了分頁,因此指定了一個返回的最大記錄數,NESTED LOOP在返回記錄數超過最大值時可以馬上停止并將結果返回給中間層,而HASH JOIN必須處理完所有結果集(MERGE JOIN也是)。那么在大部分的情況下,對于分頁查詢選擇NESTED LOOP作為查詢的連接方法具有較高的效率(分頁查詢的時候絕大部分的情況是查詢前幾頁的數據,越靠后面的頁數訪問幾率越?。?。

因此,如果不介意在系統中使用HINT的話,可以將分頁的查詢語句改寫為:

SELECT /*+ FIRST_ROWS */ * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40
)
WHERE RN >= 21






查看完整回答
反對 回復 2019-08-18
?
米琪卡哇伊

TA貢獻1998條經驗 獲得超6個贊

** 綜合練習:設計一個存儲過程,實現oracle中任意表數據的分頁

綜合案例預備
create or replace package type_pack
is
type cur_type is ref cursor;
end;

create or replace procedure all_data_pro(v_tableName varchar2,v_all_data out type_pack.cur_type,v_all_records out number)
is
v_sql varchar2(200);
v_sql1 varchar2(200);
begin
v_sql:='select * from '||v_tableName;
open v_all_data for v_sql;
v_sql1:='select count(*) from '||v_tableName;
execute immediate v_sql1 into v_all_records;--立即執行一條SQL語句
end;
語句塊調用以上存儲過程
declare
v_all_data type_pack.cur_type;
v_all_records number;
v_row_data emp%rowtype;
begin
all_data_pro('emp',v_all_data,v_all_records);
fetch v_all_data into v_row_data;
dbms_output.put_line(v_row_data.ename);
dbms_output.put_line(v_all_records);
end;

綜合案例實現:
create or replace procedure page_access_pro
(v_tableName varchar2,v_page number,v_pagesize number,v_page_data out type_pack.cur_type,v_maxpage out number)
is
v_page_sql varchar2(200);
v_all_records_sql varchar2(100);
v_count_records number;
v_begin number;
v_end number;
begin
v_begin:=(v_page-1)*v_pagesize;
v_end:=v_page*v_pagesize;
v_page_sql:='select empno,ename,job,mgr,HIREDATE,SAL,COMM,DEPTNO from (select e.*, rownum rn from(select * from '||v_tableName||')e where rownum<='||v_end||') where rn>'||v_begin;
dbms_output.put_line(v_page_sql);
open v_page_data for v_page_sql;
v_all_records_sql:='select count(*) from '||v_tableName;
execute immediate v_all_records_sql into v_count_records; --立即執行
v_maxpage:=ceil(v_count_records/v_pagesize);
end;
測試調用(注意,抓取游標中數據,類型的問題)
declare
v_page_data type_pack.cur_type;
v_maxpage number;
v_data_row emp%rowtype;
begin
page_access_pro('emp',1,2,v_page_data,v_maxpage);
dbms_output.put_line('最大頁數是:'||v_maxpage);
fetch v_page_data into v_data_row;
while v_page_data%found loop
dbms_output.put_line(v_data_row.ename);
fetch v_page_data into v_data_row;
end loop;
close v_page_data;
end;





查看完整回答
反對 回復 2019-08-18
?
臨摹微笑

TA貢獻1982條經驗 獲得超2個贊

select * from 表 where rownum >= 1 and rownum <= 100
其中,1和100是自己指定的查詢范圍。

查看完整回答
反對 回復 2019-08-18
  • 5 回答
  • 0 關注
  • 557 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號