#postgresql #plpgsql #database-cursor
Вопрос:
У меня есть таблица с более чем 1000 строками. Мне нужно получать 5 строк каждый раз, когда я вызываю функцию psql. В функции у меня будут аргументы, если аргументы пусты, она должна возвращать первые 5 строк, иначе следующие 5 строк с аргументом, который я передал
code | title | did | date_prod | kind | len ------- ------------------------- ----- ------------ ---------- ------- BL101 | The Third Man | 101 | 1949-12-23 | Drama | 01:44 BL102 | The African Queen | 101 | 1951-08-11 | Romantic | 01:43 JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25 P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08 P_302 | Becket | 103 | 1964-02-03 | Drama | 02:28 create or replace function get_giusers_batch(code) returns void as $ declare user_batch record; giusers cursor for select * from giuser; begin -- open the cursor open giusers(code); -- fetch row into the film user_batch := fetch FORWARD 10 FROM giusers; -- exit when no more row to fetch exit when not found; -- close the cursor close giusers; return user_batch; end; $
Комментарии:
1. Создайте курсор, затем попросите функцию извлечь 5 строк из этого курсора.
2.
BEGIN WORK; DECLARE films_cur SCROLL CURSOR FOR SELECT * FROM film; -- Fetch the first 5 rows in the cursor films_cur: fetch FORWARD 10 FROM films_cur; -- Close the cursor and end the transaction: CLOSE films_cur; COMMIT WORK;
@LaurenzAlbe это правильно?
Ответ №1:
Если вы хотите разбить страницу на страницы, вы имеете в виду взаимодействие с пользователем. Вы не можете держать транзакцию открытой во время этого, поэтому вам нужен WITH HOLD
курсор. Для этого вам нужен динамический SQL в PL/pgSQL. Важно, чтобы курсор был явно закрыт!
Вот пример:
CREATE FUNCTION get_data(arg integer) RETURNS SETOF uni LANGUAGE plpgsql VOLATILE CALLED ON NULL INPUT AS $BEGIN IF arg IS NOT NULL THEN /* make sure cursor is closed */ BEGIN EXECUTE 'CLOSE get_data_cur'; EXCEPTION WHEN invalid_cursor_name THEN NULL; /* ignore */ END; /* declare and open cursor */ EXECUTE format( E'DECLARE get_data_cur CURSOR WITH HOLD FORn' 'SELECT id FROM unin' 'WHERE id gt; %s', arg ); END IF; /* return next five rows */ RETURN QUERY EXECUTE 'FETCH 5 FROM get_data_cur'; /* close cursor when we are done */ IF NOT FOUND THEN EXECUTE 'CLOSE get_data_cur'; END IF; END;$;