在 PL/pgSQL 中实现游标功能作为分页
Posted
技术标签:
【中文标题】在 PL/pgSQL 中实现游标功能作为分页【英文标题】:Implement cursor function as pagination in PL/pgSQL 【发布时间】:2021-11-16 06:23:37 【问题描述】:我有超过 1000 行的电影表。每次调用 psql 函数时,我都需要获取 5 行。在函数中,如果参数为空,我将有参数,它应该返回前 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; $$
【问题讨论】:
创建一个游标,然后让函数从该游标中获取 5 行。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
游标。为此,您需要 PL/pgSQL 中的动态 SQL。明确关闭游标很重要!
这是一个例子:
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 FOR\n'
'SELECT id FROM uni\n'
'WHERE id > %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;$$;
【讨论】:
以上是关于在 PL/pgSQL 中实现游标功能作为分页的主要内容,如果未能解决你的问题,请参考以下文章