Oracle SQL - Как перебирать записи, используя нумерацию страниц? - PullRequest
0 голосов
/ 10 января 2019

Я использую базу данных Oracle, где у меня есть таблица, содержащая 20 записей

CREATE TABLE MyTable (
    MY_RECORD_ID NUMBER PRIMARY KEY, 
    SOME_DATA_1 VARCHAR2(200), 
    SOME_DATA_2 VARCHAR2(200)
);

INSERT INTO MyTable VALUES (1, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (2, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (3, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (4, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (5, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (6, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (7, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (8, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (9, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (10, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (11, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (12, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (13, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (14, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (15, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (16, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (17, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (18, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (19, 'BLAH1', 'BLAH2');
INSERT INTO MyTable VALUES (20, 'BLAH1', 'BLAH2');

Что я хотел бы сделать, так это перебрать эту таблицу, выбирая 5 записей за раз, основываясь на столбце MY_RECORD_ID. Появятся команды OFFSET и FETCH, которые позволят мне сделать это:

SELECT * 
FROM MyTable 
ORDER BY MY_RECORD_ID 
OFFSET 0 ROWS -- start at the first row
FETCH NEXT 5 ROWS ONLY;

Я бы хотел вставить вышеприведенный оператор в цикл, чтобы я мог выполнять операции с данными для каждой из пяти строк (так что это будет выполнено в общей сложности 4 раза). Есть ли способ сделать это с помощью хранимой процедуры?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Вы можете использовать аналитические функции для запросов такого типа

SELECT my_record_id, some_data_1, some_data_2
  FROM (
        SELECT CEIL(ROW_NUMBER() OVER(ORDER BY mt.my_record_id) / 5/*set the page size*/) page_id
             ,mt.* 
          FROM MyTable mt
       ) t
 WHERE page_id = 1 /* set the desired page*/
ORDER BY my_record_id

Вы можете проверить эту документацию

Функции аналитики

https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions004.htm#SQLRF06174

Спроси Тома

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1137577300346084930

Другой пример

https://blogs.oracle.com/oraclemagazine/on-top-n-and-pagination-queries

0 голосов
/ 10 января 2019

Вы можете сделать это с помощью массового сбора.

DECLARE
  TYPE t_MyTable_tab IS TABLE OF MyTable%ROWTYPE;
  l_tab    t_MyTable_tab ; 
  CURSOR c_data IS
    SELECT *
    FROM   MyTable;
BEGIN
  OPEN c_data;
  LOOP
    FETCH c_data
    BULK COLLECT INTO l_tab LIMIT 5; --- Here 5 is your limiting number

    -- Process contents of collection here.
    DBMS_OUTPUT.put_line(l_tab.count || ‘ rows’);
    EXIT WHEN c_data%NOTFOUND;
  END LOOP
  CLOSE c_data;
END;
/
...