CURSOR
功能描述
游标(CURSOR)是数据库系统在内存中开设的一个数据缓冲区,存放SQL语句的执行结果。
除了原有的游标定义语法以外,Vastbase支持兼容PostgreSQL风格的游标定义语法。
注意事项
无。
语法格式
name [ [ NO ] SCROLL ] CURSOR [ ( arguments ) ] FOR query;
参数说明
name
游标变量的名称。
[NO] SCROLL
SCROLL
如果指定了SCROLL特性,则表示游标的光标可以向后滚动(回滚)。
NO SCROLL
使用 NO SCROLL表示游标不能回滚。
如果两个关键字都没有出现,则是否允许反向回迁取决于查询。
CURSOR
关键字,指明变量是游标类型。
[ ( arguments ) ]
如果指定了arguments,则是一个逗号分隔的对名称数据类型列表,起到类似绑定变量作用。
FOR
关键字,表示后面的语句为游标定义的内容,可以被IS取代。
query
查询语句,包含各种关联查询和子查询。
示例
示例1:使用PG风格的CURSOR定义语法。
CREATE OR REPLACE procedure a() as
c1_all scroll cursor FOR select * from tt;
BEGIN
select 2*3 from dual;
END;
/
示例2: 在存储过程中定义并使用CURSOR。
1、创建测试表并插入数据。
create table company(name varchar(100), loc varchar(100), no integer);
insert into company values ('oracle', 'usa', 002);
insert into company values ('sumsung', 'south korea', 004);
insert into company values ('tencent', 'china', 005);
insert into company values ('ibm', 'usa', 006);
insert into company values ('sony', 'japan', 009);
insert into company values ('baidu', 'china', 010);
insert into company values ('kingsoft', 'china', 011);
insert into company values ('macrosoft', 'usa', 001);
insert into company values ('backberry', 'canada', 003);
insert into company values ('nokia', 'finland', 007);
insert into company values ('apple', 'usa', 008);
2、定义并调用存储过程。
create or replace procedure test_cursor_scroll()
as
company_name varchar(100);
company_loc varchar(100);
company_no integer;
c1_all scroll cursor for select name, loc, no from company order by no;
begin
if not c1_all%isopen then
raise notice '%','c1_all%isopen=false: c1_all closed';
open c1_all;
raise notice '%','c1_all opened';
end if;
loop
raise notice '%','test current cursor value';
fetch c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test next cursor value';
fetch next from c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test prior cursor value';
fetch prior from c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test first cursor value';
fetch first from c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test last cursor value';
fetch last from c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test absolute 2 cursor value';
fetch absolute 2 from c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test relative -1 cursor value';
fetch relative -1 from c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test forward cursor value';
fetch forward from c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test forward cursor value';
fetch forward from c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test backward cursor value';
fetch backward from c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test backward cursor value';
fetch backward from c1_all into company_name, company_loc, company_no;
if c1_all%notfound then
raise notice '%','c1_all%notfound=true: no rows selected';
exit;
end if;
if c1_all%found then
raise notice 'rows_%: % % %',c1_all%rowcount,company_name,company_loc,company_no;
end if;
raise notice '%','test NEXT、 PRIOR、 FIRST、 LAST、 ABSOLUTE count、 RELATIVE count、 FORWARD、BACKWARD ok!';
exit;
end loop;
if c1_all%isopen then
raise notice '%','c1_all%isopen=true: c1_all opened';
close c1_all;
raise notice '%','c1_all closed';
end if;
end;
/
call test_cursor_scroll();
返回结果为:
NOTICE: c1_all%isopen=false: c1_all closed
NOTICE: c1_all opened
NOTICE: test current cursor value
NOTICE: rows_1: macrosoft usa 1
NOTICE: test next cursor value
NOTICE: rows_2: oracle usa 2
NOTICE: test prior cursor value
NOTICE: rows_3: macrosoft usa 1
NOTICE: test first cursor value
NOTICE: rows_4: macrosoft usa 1
NOTICE: test last cursor value
NOTICE: rows_5: kingsoft china 11
NOTICE: test absolute 2 cursor value
NOTICE: rows_6: oracle usa 2
NOTICE: test relative -1 cursor value
NOTICE: rows_7: macrosoft usa 1
NOTICE: test forward cursor value
NOTICE: rows_8: oracle usa 2
NOTICE: test forward cursor value
NOTICE: rows_9: backberry canada 3
NOTICE: test backward cursor value
NOTICE: rows_10: oracle usa 2
NOTICE: test backward cursor value
NOTICE: rows_11: macrosoft usa 1
NOTICE: test NEXT、 PRIOR、 FIRST、 LAST、 ABSOLUTE count、 RELATIVE count、 FORWARD、BACKWARD ok!
NOTICE: c1_all%isopen=true: c1_all opened
NOTICE: c1_all closed
test_cursor_scroll
--------------------
(1 row)