CURSOR命令定义一个游标,用于在一个大的查询里面检索少数几行数据。
为了处理SQL语句,存储过程进程分配一段内存区域来保存上下文联系。游标是指向上下文区域的句柄或指针。借助游标,存储过程可以控制上下文区域的变化。
语法:
CURSOR cursor_name
[ BINARY ] [ NO SCROLL ] [ { WITH | WITHOUT } HOLD ]
FOR query ;游标练习
创建游标,且使用select子句指定游标返回的行,分别使用FETCH抓取数据,MOVE重定位游标
创建表用于练习
omm=# create schema lxs_data;
CREATE SCHEMA
omm=# CREATE TABLE lxs_data.reason
omm-# (
omm(# r_reason_sk integer,
omm(# omm(# r_reason_id character(16),
r_reason_desc character(100)
omm(# );
CREATE TABLE
omm=#
omm=# INSERT INTO lxs_data.reason values(3,'AAAAAAAABAAAAAAA','reason 1'),
omm-# (10,'AAAAAAAABAAAAAAA','reason 2'),(4,'AAAAAAAABAAAAAAA','reason 3'),
omm-# (10,'AAAAAAAABAAAAAAA','reason 4'),(10,'AAAAAAAABAAAAAAA','reason 5'),
omm-# (20,'AAAAAAAACAAAAAAA','reason 6'),(30,'AAAAAAAACAAAAAAA','reason 7');
INSERT 0 7
omm=# create table lxs_data.company(name varchar(100), loc varchar(100), no integer);
CREATE TABLE
omm=# insert into lxs_data.company values ('macrosoft', 'usa', 001);
INSERT 0 1
omm=# insert into lxs_data.company values ('oracle', 'usa', 002);
INSERT 0 1
omm=# insert into lxs_data.company values ('backberry', 'canada', 003);
INSERT 0 1
创建游标,且使用select子句指定游标返回的行,分别使用FETCH抓取数据,MOVE重定位游标
omm=# start transaction;
START TRANSACTION
omm=# CURSOR cursorlxs FOR SELECT * FROM lxs_data.reason ;
DECLARE CURSOR
omm=# select * from pg_cursors;
cursorlxs | CURSOR cursorlxs FOR SELECT * FROM lxs_data.reason ; | f | f
| t | 2021-12-18 21:47:09.337097+08
(1 row)
name | statement | is_holdable | is_binary
| is_scrollable | creation_time
-----------+------------------------------------------------------+-------------+-----------
+---------------+-------------------------------
使用FETCH抓取头2行到游标
omm=# FETCH FORWARD 2 FROM cursorlxs;
r_reason_sk | r_reason_id | r_reason_desc
-------------+------------------+-----------------------------------------------------------
-------------------------------------------
3 | AAAAAAAABAAAAAAA | reason 1
10 | AAAAAAAABAAAAAAA | reason 2
(2 rows)
使用FETCH从当前关联位置开始,抓取前面的1行
omm=# FETCH BACKWARD 1 FROM cursorlxs;
r_reason_sk | r_reason_id | r_reason_desc
-------------+------------------+-----------------------------------------------------------
-------------------------------------------
3 | AAAAAAAABAAAAAAA | reason 1
(1 row)
MOVE重定位游标
omm=# MOVE FORWARD 1 FROM cursorlxs;
MOVE 1
然后关闭游标,结束事务
CLOSE cursorlxs;
end;
在系统视图pg_cursors中查看游标
cursorlxs | CURSOR cursorlxs FOR SELECT * FROM lxs_data.reason ; | f | f
| t | 2021-12-18 21:47:09.337097+08
(1 row)
name | statement | is_holdable | is_binary
| is_scrollable | creation_time
-----------+------------------------------------------------------+-------------+-----------
+---------------+-------------------------------
创建一个使用游标的存储过程
omm=# create or replace procedure cursorlxs_pro
omm-# as
omm$# company_name varchar(100);
omm$# company_loc varchar(100);
omm$# company_no integer;
omm$# cursor c1_all is --cursor without args
omm$# select name, loc, no from lxs_data.company;
omm$# begin
omm$# if not c1_all%isopen then
omm$# open c1_all;
omm$# end if;
omm$# loop
omm$# fetch c1_all into company_name, company_loc, company_no;
omm$#
ABORT DROP RESET
ALTER END REVOKE
ANALYZE EXECUTE ROLLBACK
BEGIN EXPLAIN SAVEPOINT
CALL FETCH SECURITY LABEL
CHECKPOINT GRANT SELECT
CLOSE INSERT SET
CLUSTER LISTEN SHOW
COMMENT LOAD START
COMMIT LOCK TABLE
COPY MOVE TRUNCATE
CREATE NOTIFY UNLISTEN
DEALLOCATE PREPARE UPDATE
DECLARE REASSIGN VACUUM
DELETE FROM REFRESH MATERIALIZED VIEW VALUES
DISCARD REINDEX WITH
DO RELEASE
omm$# RAISE INFO 'company_name: %' ,company_name;
omm$# exit when c1_all%notfound;
omm$# end loop;
omm$# if c1_all%isopen then
omm$# close c1_all;
omm$# end if;
omm$# end;
omm$# /
CREATE PROCEDURE
omm=# call cursorlxs_pro();
INFO: company_name: macrosoft
INFO: company_name: oracle
INFO: company_name: backberry
INFO: company_name: backberry
cursorlxs_pro
---------------
(1 row)
清理数据
omm=# drop procedure cursorlxs_pro;
DROP PROCEDURE
omm=# drop table lxs_data.reason;
DROP TABLE
omm=# drop table lxs_data.company;
DROP TABLE
omm=# drop schema lxs_data cascade;
NOTICE: drop cascades to table lxs_data.ompany
DROP SCHEMA
其他
FETCH
FETCH通过已创建的游标来检索数据。
每个游标都有一个供FETCH使用的关联位置。游标的关联位置可以在查询结果的第一行之前,或者在结果中的任意行,或者在结果的最后一行之后:
游标刚创建完之后,关联位置在第一行之前的。
在抓取了一些移动行之后,关联位置在检索到的最后一行上。
如果FETCH抓取完了所有可用行,它就停在最后一行后面,或者在反向抓取的情况下是停在第一行前面。
FETCH ALL或FETCH BACKWARD ALL将总是把游标的关联位置放在最后一行或者在第一行前面。
官方网址 https://opengauss.org/zh/docs/2.1.0/docs/Developerguide/FETCH.html
MOVE
MOVE在不检索数据的情况下重新定位一个游标。MOVE的作用类似于FETCH命令,但只是重定位游标而不返回行。语法:
MOVE [ direction [ FROM | IN ] ] cursor_name;
其中direction子句为可选参数。
NEXT | PRIOR | FIRST | LAST | ABSOLUTE count | RELATIVE count | count | ALL | FORWARD | FORWARD count | FORWARD ALL | BACKWARD | BACKWARD count | BACKWARD ALL
官网网址: https://opengauss.org/zh/docs/2.1.0/docs/Developerguide/MOVE.html




