游标(Cursor):用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作。
oracle中显示使用游标一般要包含以下5个步骤:
- 声明一些变量以便存储从游标返回的值。
- 声明游标,并指定查询。
- 打开游标。
- 遍历游标并取得数据。
- 关闭游标
表结构及数据如下:
1 -- Create table
2 create table EXCHANGETIME
3 (
4 ID NUMBER(18) default 0 not null,
5 SYSTEM_TYPE CHAR(1) default ' ' not null,
6 TIME_KIND NUMBER(10) default 0 not null,
7 TIME_NAME VARCHAR2(16) default ' ' not null,
8 BEGIN_TIME NUMBER(10) default to_number(to_char(sysdate,'hh24miss')) not null,
9 END_TIME NUMBER(10) default to_number(to_char(sysdate,'hh24miss')) not null
10 )
11
12 insert into EXCHANGETIME (ID, SYSTEM_TYPE, TIME_KIND, TIME_NAME, BEGIN_TIME, END_TIME)
13 values (1, '0', 0, '上午交易时间', 91500, 113000);
14
15 insert into EXCHANGETIME (ID, SYSTEM_TYPE, TIME_KIND, TIME_NAME, BEGIN_TIME, END_TIME)
16 values (2, '0', 1, '下午交易时间', 130000, 150000);
17
18 insert into EXCHANGETIME (ID, SYSTEM_TYPE, TIME_KIND, TIME_NAME, BEGIN_TIME, END_TIME)
19 values (3, '1', 2, '盘后交易时间', 150000, 153000);
1 -- Create table
2 create table BACKUPINFO
3 (
4 ID NUMBER(18) default 0 not null,
5 INIT_DATE NUMBER(10) default to_number(to_char(sysdate,'yyyymmdd')) not null,
6 TREAT_FLAG VARCHAR2(120) default ' ' not null,
7 ERROR_INFO VARCHAR2(4000) default ' ' not null,
8 FLAG CHAR(1) default ' ' not null
9 )
10
11 insert into backupinfo (ID, INIT_DATE, TREAT_FLAG, ERROR_INFO, FLAG)
12 values (1, 20140923, '1', '343%3r3', '2');
13
14 insert into backupinfo (ID, INIT_DATE, TREAT_FLAG, ERROR_INFO, FLAG)
15 values (2, 19900909, '4', 'fr454', ' ');
16
17 insert into backupinfo (ID, INIT_DATE, TREAT_FLAG, ERROR_INFO, FLAG)
18 values (1, 20140923, '1', '343%3r3', '2');
19
20 insert into backupinfo (ID, INIT_DATE, TREAT_FLAG, ERROR_INFO, FLAG)
21 values (2, 19900909, '4', 'fr454', ' ');
22
23 insert into backupinfo (ID, INIT_DATE, TREAT_FLAG, ERROR_INFO, FLAG)
24 values (1, 20140923, '1', '343%3r3', '2');
25
26 insert into backupinfo (ID, INIT_DATE, TREAT_FLAG, ERROR_INFO, FLAG)
27 values (2, 19900909, '4', 'fr454', ' ');
28
29 insert into backupinfo (ID, INIT_DATE, TREAT_FLAG, ERROR_INFO, FLAG)
30 values (1, 20140923, '1', '343%3r3', '2');
31
32 insert into backupinfo (ID, INIT_DATE, TREAT_FLAG, ERROR_INFO, FLAG)
33 values (2, 19900909, '4', 'fr454', ' ');
下面来看几个例子:
1. 完整的示例:
1 declare
2 --声明变量(用于存放游标查询出来的值)
3 id exchangetime.id%type;
4 system_type exchangetime.system_type%type;
5 time_kind exchangetime.time_kind%type;
6 time_name exchangetime.time_name%type;
7 begin_time exchangetime.begin_time%type;
8 end_time exchangetime.end_time%type;
9
10 --声明游标
11 cursor v_eq is select * from exchangetime;
12 begin
13 --打开游标
14 open v_eq;
15
16 loop
17 --从游标中取出每行数据赋给上面定义的变量并打印出来
18 fetch v_eq into id, system_type, time_kind, time_name, begin_time, end_time;
19 dbms_output.put_line(id || ' ' || system_type|| 'time_kind:' || time_kind || ' time _name:' || time_name || ' ' || begin_time || '-->' || end_time);
20
21 exit when v_eq%NOTFOUND;
22 end loop;
23
24 --关闭游标
25 close v_eq;
26
27 end;
28 /
输出结果:
1 0time_kind:0 time _name:上午交易时间 91500-->113000
2 0time_kind:1 time _name:下午交易时间 130000-->150000
3 1time_kind:2 time _name:盘后交易时间 150000-->153000
3 1time_kind:2 time _name:盘后交易时间 150000-->153000
2. 与for循环联合使用(推荐用法)
1 declare
2 begin
3 --mcursor的名字可以随便定义,aa或者bb都行,这样写的好处是不用显示定义游标,打开游标循环取值再关闭游标,很方便。
4 for mcursor in (select * from exchangetime) loop
5 dbms_output.put_line(mcursor.id || mcursor.time_name);
6 end loop;
7
8 end;
9 /
结果如下:
1上午交易时间
2下午交易时间
3盘后交易时间
3.使用open ... for ...语句
1 declare
2 --定义游标指针并指定返回类型为exchangetime的所有列
3 type t_cursor is ref cursor return exchangetime%rowtype; 4 --定义接收返回值的变量 5 v_etresult exchangetime%rowtype; 6 --相当于定义了一个指针变量 7 v_cursor t_cursor; 8 begin 9 --将指针并指向一个游标并打开 10 open v_cursor for select * from exchangetime t where t.id<3; 11 12 loop 13 -- --指向的游标里面每一行的值赋给接收的变量,并打印出来 14 fetch v_cursor into v_etresult; 15 dbms_output.put_line(v_etresult.time_name); 16 exit when v_cursor%notfound; 17 end loop; 18 --关闭指向的游标 19 close v_cursor; 20 21 --将指针指向另外一个游标并打开 22 open v_cursor for select * from exchangetime t; 23 24 loop 25 fetch v_cursor into v_etresult; 26 dbms_output.put_line(v_etresult.time_name|| '--' || v_etresult.system_type); 27 exit when v_cursor%notfound; 28 end loop; 29 30 31 --关闭指针指向的游标 32 close v_cursor; 33 end; 34 /
结果如下:
上午交易时间
下午交易时间
下午交易时间
上午交易时间--0
下午交易时间--0
盘后交易时间--1
盘后交易时间--1
4.无约束游标:前面的游标都有返回类型称为约束游标,约束游标的返回类型必须与游标运行时查询中的列相匹配。无约束游标没有返回类型因此可以运行任何查询。
1 declare
2 --定义游标指针
3 type t_cursor is ref cursor;
4 --定义接收返回值的变量
5 v_etresult exchangetime%rowtype;
6 v_buresult backupinfo%rowtype;
7 --相当于定义了一个指针变量
8 v_cursor t_cursor;
9 begin
10 --将指针并指向一个游标并打开
11 open v_cursor for select * from exchangetime t where t.id<3;
12
13 loop
14 --指向的游标里面每一行的值赋给接收的变量,并打印出来
15 fetch v_cursor into v_etresult;
16 dbms_output.put_line(v_etresult.time_name);
17 exit when v_cursor%notfound;
18 end loop;
19 --关闭指向的游标
20 close v_cursor;
21
22 --将指针指向另外一个游标并打开
23 open v_cursor for select * from backupinfo t;
24
25 loop
26 --指向的游标里面每一行的值赋给接收的变量,并打印出来
27 fetch v_cursor into v_buresult;
28 dbms_output.put_line(v_buresult.flag|| '--' || v_buresult.init_date);
29 exit when v_cursor%notfound;
30 end loop;
31
32
33 --关闭指针指向的游标
34 close v_cursor;
35 end;
36 /
结果如下:
上午交易时间
下午交易时间
下午交易时间
2--20140923
--19900909
2--20140923
--19900909
2--20140923
--19900909
2--20140923
--19900909
--19900909