日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

oracle number类型_一文看懂Oracle分页实现方案的三种方式

發布時間:2023/12/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 oracle number类型_一文看懂Oracle分页实现方案的三种方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Oracle分頁實現

閑來無事,整理下Oracle、mysql、mssql以及PG數據庫的分頁實現方式,大家可以簡單做個對比,看下不同數據庫在分頁這塊是怎么實現的。今天先介紹一下Oracle分頁的實現方式。

oracle的分頁一共有三種方式,但在Oracle中實現分頁的方法主要是用ROWNUM關鍵字和用ROWID關鍵字兩種。Rownum 和 Rowid是Oracle數據庫所特有的,通過他們可以查詢到指定行數范圍內的數據記錄。


1、根據rowid來分

Oracle使用rowid數據類型存儲行地址,rowid是物理存在的,實際存在的一個列,是一種數據類型。 基于64為編碼的18個字符來唯一標識的一條記錄的物理位置的一個ID。而唯一標識出對應的存儲的物理位置, 類似hashcode值。

rowid可以分成兩種,分別適于不同的對象:

1)Physical rowids:存儲ordinary table,clustered table,table partition and subpartition,indexe,index partition and subpartition2)Logical rowids : 存儲IOT的行地址

另一種rowid類型叫universal rowed(UROWID),支持上述physical rowid和logical rowed,并且支持非oracle table, 即支持所有類型的rowid, 但COMPATIBLE必須在8.1或以上.

每個表在oracle內部都有一個ROWID偽列,它在所有sql中無法顯示,不占存儲空間; 它用于從表中查詢行的地址或者在where中進行參照,rowid偽列不存儲在數據庫中,它不是數據庫數據,這是從database及table的邏輯結構來說的,事實上,在物理結構上,每行由一個或多個row pieces組成,每個row piece的頭部包含了這個piece的address,即rowid.從這個意義上來說,rowid還是占了磁盤空間的。

我們在創建表時,可以為列指定為rowid數據類型,但oracle并不保證列中的數據是合法的rowid值,必須由應用程序來保證, 另外,類型為rowid的列需要6 bytes存儲數據

一般實現分頁的過程如下:

  • 1)獲取數據物理地址:SELECT ROWID RID, tablenumber FROM table_name ORDER BY tablenumber DESC
    2)取得最大頁數:SELECT ROWNUM RN, RID FROM (SELECT ROWID RID, tablenumber FROM table_name ORDER BY tablenumber DESC) WHERE ROWNUM <= xx
  • 3)取得最小頁數:SELECT RID FROM(SELECT ROWNUM RN, RID FROM (SELECT ROWID RID, tablenumber FROM table_name ORDER BY tablenumber DESC) WHERE ROWNUM <= xx)
  • 4)因為取得的頁數都是物理地址,再根據物理地址,查詢出具體數據
--currentPage:當前頁數--pageSize:每頁顯示幾條SELECT * FROM table_name WHERE ROWID IN (SELECT RID FROM (SELECT ROWNUM RN, RID FROM (SELECT ROWID RID, tablenumber FROM table_name ORDER BY tablenumber DESC) WHERE ROWNUM <= ((currentPage - 1) * pageSize + pageSize)) WHERE RN > ((currentPage - 1) * pageSize)) ORDER BY tablenumber DESC;

2、按分析函數 ROW_NUMBER() OVER()來分

語法格式:row_number() over(partition by 分組列 order by 排序列 desc)

oracle中的ROW_NUMBER() OVER(partition by col1 order by col2) 表示根據col1分組,在分組內部根據col2排序,而此函數計算的值就表示每組內部排序后的順序編號(組內是連續且唯一的)

一般實現分頁的過程如下:

--currentPage:當前頁數--pageSize:每頁顯示幾條SELECT * FROM (SELECT T.*, ROW_NUMBER() OVER(ORDER BY tablenumber DESC) RK FROM t T) WHERE RK <= ((currentPage - 1) * pageSize + pageSize) AND RK > ((currentPage - 1) * pageSize);

3、根據rownum 來分

rownum是偽列,是在獲取查詢結果集后再加上去的 (獲取一條記錄加一個rownum)。對符合條件的結果添加一個從1開始的序列號

對于rownum來說它是oracle系統順序分配為從查詢返回的行的編號,返回的第一行分配的是1,第二行是2,依此類推,這個偽字段可以用于限制查詢返回的總行數,且rownum不能以任何表的名稱作為前綴。

一般實現分頁的過程如下:

--currentPage:當前頁數--pageSize:每頁顯示幾條SELECT * FROM (SELECT T.*, ROWNUM RN FROM (SELECT * FROM t ORDER BY tablenumber DESC) T WHERE ROWNUM <= ((currentPage - 1) * pageSize + pageSize)) WHERE RN > ((currentPage - 1) * pageSize);

4、存儲過程實現

這個存儲過程主要是讓大家看看分頁的實現過程,可忽略

--1、開發一個包,在該包中,定義類型test_cursor,是個游標create or replace package testpackage as type test_cursor is ref cursor;end testpackage;--2、開始編寫分頁的過程create or replace procedure fenye(tableName in varchar2, --表名 pageSize in number, --一頁顯示記錄數 pageNow in number, --當前頁 myrows out number, --總記錄數 myPageCount out number, --總頁數 p_cursor out testpackage.test_cursor --返回的記錄集 ) is --定義部分 --定義sql語句 字符串 v_sql varchar2(1000); --定義兩個整數 v_begin number := (pageNow - 1) * pageSize + 1; v_end number := pageNow * pageSize;begin --執行部份 v_sql := 'select * from (select t1.*,rownum rn from (select * from ' || tableName || ') t1 where rownum<=' || v_end || ') where rn>=' || v_begin; --把游標和sql關聯 open p_cursor for v_sql; --計算myrows和myPageCount --組織一個sql v_sql := 'select count(*) from ' || tableName; --執行sql,并把返回的值賦給myrows; execute immediate v_sql into myrows; --計算myPageCount if mod(myrows, PageSize) = 0 then myPageCount := myrows / PageSize; else myPageCount := myrows / PageSize + 1; end if; --關閉游標 close p_cursor;end;

5、實例演示

5.1、環境準備

create table t(EMPNO NUMBER(4) not null, ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER(4), HIREDATE DATE, SAL NUMBER(7,2), COMM NUMBER(7,2), DEPTNO NUMBER(2));alter table t add constraint PK_EMP primary key (EMPNO) using index;INSERT INTO t VALUES ('7369', 'SMITH', 'CLERK', '7902', TO_DATE('1980-12-17 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '800', NULL, '20');INSERT INTO t VALUES ('7499', 'ALLEN', 'SALESMAN', '7698', TO_DATE('1981-02-20 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1600', '300', '30');INSERT INTO t VALUES ('7521', 'WARD', 'SALESMAN', '7698', TO_DATE('1981-02-22 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1250', '500', '30');INSERT INTO t VALUES ('7566', 'JONES', 'MANAGER', '7839', TO_DATE('1981-04-02 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '2975', NULL, '20');INSERT INTO t VALUES ('7654', 'MARTIN', 'SALESMAN', '7698', TO_DATE('1981-09-28 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1250', '1400', '30');INSERT INTO t VALUES ('7698', 'BLAKE', 'MANAGER', '7839', TO_DATE('1981-05-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '2850', NULL, '30');INSERT INTO t VALUES ('7782', 'CLARK', 'MANAGER', '7839', TO_DATE('1981-06-09 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '2450', NULL, '10');INSERT INTO t VALUES ('7788', 'SCOTT', 'ANALYST', '7566', TO_DATE('1987-04-19 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '3000', NULL, '20');INSERT INTO t VALUES ('7839', 'KING', 'PRESIDENT', NULL, TO_DATE('1981-11-17 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '5000', NULL, '10');INSERT INTO t VALUES ('7844', 'TURNER', 'SALESMAN', '7698', TO_DATE('1981-09-08 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1500', '0', '30');INSERT INTO t VALUES ('7876', 'ADAMS', 'CLERK', '7788', TO_DATE('1987-05-23 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1100', NULL, '20');INSERT INTO t VALUES ('7900', 'JAMES', 'CLERK', '7698', TO_DATE('1981-12-03 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '950', NULL, '30');INSERT INTO t VALUES ('7902', 'FORD', 'ANALYST', '7566', TO_DATE('1981-12-03 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '3000', NULL, '20');INSERT INTO t VALUES ('7934', 'MILLER', 'CLERK', '7782', TO_DATE('1982-01-23 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), '1300', NULL, '10');commit;

5.2、根據rowid查詢

--查詢當前第一頁,并顯示5行數據(currentPage=1,pagesize=5)SELECT * FROM t WHERE ROWID IN (SELECT RID FROM (SELECT ROWNUM RN, RID FROM (SELECT ROWID RID, EMPNO FROM t ORDER BY EMPNO DESC) WHERE ROWNUM <= ( (1-1) * 5 + 5 )) --每頁顯示幾條 WHERE RN > ((1-1) * 5) ) --當前頁數 ORDER BY EMPNO DESC; --查詢當前第二頁,并顯示6行數據(currentPage=2,pagesize=6)SELECT * FROM t WHERE ROWID IN (SELECT RID FROM (SELECT ROWNUM RN, RID FROM (SELECT ROWID RID, EMPNO FROM t ORDER BY EMPNO DESC) WHERE ROWNUM <= ( (2-1) * 6 + 6)) --每頁顯示幾條 WHERE RN > ((2-1) * 6) ) --當前頁數 ORDER BY EMPNO DESC;

5.3、根據分頁函數查詢

--查詢當前第一頁,并顯示6行數據(currentPage=1,pagesize=6)SELECT * FROM (SELECT T.*, ROW_NUMBER() OVER(ORDER BY tablenumber DESC) RK FROM t T) WHERE RK <= ((1 - 1) * 5 + 5) --每頁顯示幾條 AND RK > ((1 - 1) * 5); --當前頁數

5.4、根據分頁函數查詢

--查詢當前第二頁,并顯示4行數據(currentPage=2,pagesize=4)SELECT * FROM (SELECT T.*, ROWNUM RN FROM (SELECT * FROM t ORDER BY empno DESC) T WHERE ROWNUM <= ((2 - 1) * 4 + 4)) WHERE RN > ((2 - 1) * 4);

覺得有用的朋友多幫忙轉發哦!后面會分享更多devops和DBA方面的內容,感興趣的朋友可以關注下~

總結

以上是生活随笔為你收集整理的oracle number类型_一文看懂Oracle分页实现方案的三种方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。