1. 介紹sql
當咱們在作查詢時,常常會遇到如查詢限定行數或分頁查詢的需求,MySQL中可使用LIMIT子句完成,在MSSQL中可使用TOP子句完成,那麼在Oracle中,咱們如何實現呢?數據庫
Oracle提供了一個rownum的僞列,它會根據返回記錄生成一個序列化的數字。oracle
rownum和rowid都是僞列,可是二者的根本是不一樣的。rownum是根據SQL查詢出的結果給每行分配一個邏輯編號,因此SQL不一樣也就會致使最終rownum不一樣;rowid是物理結構上的,在每條記錄INSERT到數據庫中時,都會有一個惟一的物理記錄。測試
2. 限定查詢行數spa
若是但願限定查詢結果集的前幾條數據,經過ROWNUM能夠輕鬆實現。code
示例:blog
-- 查找前三條員工的記錄 SELECT * FROM employee WHERE rownum <= 3;
3. 分頁查詢排序
在數據庫應用系統中,咱們會常常使用到分頁功能,如每頁顯示5條記錄,查詢第2頁內容該如何查詢呢?get
SELECT * FROM employee WHERE rownum > 5 AND rownum <= 10;
上面的SQL語句是否能查詢出咱們想要的結果呢?class
當執行該SQL就會發現,顯示出來的結果要讓你失望了:查不出一條記錄,即便表中有20條記錄。問題是出在哪呢?
由於rownum是對結果集加的一個僞列(即先查到結果集以後再加上去的一個列),簡單的說rownum是對符合條件結果集添加的序列號。它老是從1開始排起的,因此選出的結果中不可能沒有1,而有其餘大於1的值。
rownum > 5 AND rownum <= 10 查詢不到記錄,由於若是第一條的 rownum = 1,不知足條件被去掉,第二條的rownum又成了1,繼續判斷,因此永遠沒有知足條件的記錄。
任什麼時候候想把 rownum = 1 這條記錄拋棄是不對的,它在結果集中是不可或缺的,少了rownum=1 就像空中樓閣通常不能存在,因此你的 rownum 條件要包含到 1。
那麼,若是想要用 rownum > 5 這種條件的話就要用子查詢,把rownum先生成,而後再對生成結果進行查詢。
示例:
SELECT * FROM ( SELECT e.*, rownum r FROM employee WHERE rownum <= 10 ) t WHERE t.r > 5;
4. 使用rownum的注意事項
5 下面就是利用包來寫的一個分頁的查詢的過程
1 -- 包說明 2 CREATE OR REPLACE PACKAGE pkg_page IS 3 TYPE page_cur_type IS REF CURSOR; 4 PROCEDURE get_page_rec(current_page NUMBER, page_size NUMBER, page_rec OUT PAGE_CUR_TYPE); 5 END pkg_page; 6 7 -- 包體 8 CREATE OR REPLACE PACKAGE BODY pkg_page IS 9 -- 分頁查詢的過程 10 PROCEDURE get_page_rec(current_page NUMBER, page_size NUMBER, page_rec OUT PAGE_CUR_TYPE) IS 11 lower_bound NUMBER(4); -- 記錄下限編號 12 upper_bound NUMBER(4); -- 記錄上限編號 13 BEGIN 14 lower_bound := (current_page - 1) * page_size; 15 upper_bound := current_page * page_size; 16 17 OPEN page_rec FOR 18 SELECT id, name, birthday, address, did, salary FROM( 19 SELECT t1.*,rownum r FROM 20 (SELECT id, name, birthday, address, did, salary FROM employee ORDER BY name) t1 21 WHERE rownum <= upper_bound 22 ) t 23 WHERE t.r > lower_bound; 24 END get_page_rec; 25 END pkg_page; 26 27 -- 測試 28 DECLARE 29 page_index NUMBER(4) := 1; -- 頁碼 30 page_size NUMBER(4) := 4; -- 每頁顯示記錄數 31 cur_var PKG_PAGE.page_cur_type; 32 rec employee%ROWTYPE; 33 BEGIN 34 PKG_PAGE.get_page_rec(page_index, page_size, cur_var); 35 LOOP 36 FETCH cur_var INTO rec; 37 EXIT WHEN cur_var%NOTFOUND; 38 DBMS_OUTPUT.PUT_LINE('工號:' || rec.id || ',姓名:' || rec.name || ',工資:' || rec.salary); 39 END LOOP; 40 CLOSE cur_var; 41 END;