位于内存中的 "临时表"
。 具体以下:游标是从数据表中提取出来的数据,以 临时表 的形式存放到 内存中
,在游标中有一个 数据指针, 在初始状态下指向的是首记录,利用 fetch
语句能够移动该指针,从而对游标中的数据进行各类操做,而后将操做结果写回到数据库中。游标的本质是一个结果集resultset,主要用来临时存储从数据库中提取出来的数据块。sql
1. 显式游标:由用户定义,须要的操做:定义游标、打开游标、提取数据、关闭游标,主要用于对查询语句的处理。数据库
2.显式游标的属性oop
(1) %NOTFOUND。表示游标获取数据的时候是否有数据提取出来,没有数据返回TRUE,有数据返回false。常常用来判断游标是否所有循环完毕,如案例1%NOTFOUND为true的时候,说明循环完毕,跳出LOOP循环。测试
(2) %FOUND。正好和%NOTFOUND相反,当游标提取数据值时有值,返回TRUE,不然返回FALSE。fetch
(3) %ISOPEN。用来判断游标是否打开。spa
(4) %ROWCOUNT。表示当前游标FETCH INTO获取了多少行的记录值,用来作计数用的。指针
举例:打印表hu_test中的指定字段code
--显示游标 declare cursor hu_test_cursor is select owner,object_type,created from hu_test;--定义游标 v_owner hu_test.owner%type; v_object_type hu_test.object_type%type; v_created hu_test.created%type; begin open hu_test_cursor;--打开游标 loop fetch hu_test_cursor into v_owner,v_object_type,v_created;--提取数据 dbms_output.put_line('全部者:'||v_owner||' 类型是:'||v_object_type||' 建立时间:'||v_created); exit when hu_test_cursor%notfound; end loop; close hu_test_cursor;--关闭游标 EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE || ' : ' || SQLERRM);--返回错误消息 dbms_output.put_line(dbms_utility.format_error_backtrace);--返回错误行 end;
举例:检验游标是否打开,打开的话显示提取行数orm
--检验游标是否打开,打开的话显示提取行数 declare cursor hu_test_cursor is select owner,object_type,created from hu_test;--定义游标 v_owner hu_test.owner%type; v_object_type hu_test.object_type%type; v_created hu_test.created%type; begin open hu_test_cursor;--打开游标 loop fetch hu_test_cursor into v_owner,v_object_type,v_created;--提取数据 dbms_output.put_line('全部者:'||v_owner||' 类型是:'||v_object_type||' 建立时间:'||v_created); exit when hu_test_cursor%notfound; end loop; if(hu_test_cursor%isopen) then DBMS_OUTPUT.PUT_LINE('游标已打开'); DBMS_OUTPUT.PUT_LINE('读取了'||hu_test_cursor%ROWCOUNT||'行'); else DBMS_OUTPUT.PUT_LINE('游标没有打开'); end if; close hu_test_cursor;--关闭游标 EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE || ' : ' || SQLERRM);--返回错误消息 dbms_output.put_line(dbms_utility.format_error_backtrace);--返回错误行 end;
3. 隐式游标:由系统定义并为它建立工做区域,而且隐式的定义打开提取关闭,隐式游标的游标名就是'SQL',属性和显示游标相同,主要用于对单行select语句或dml操做进行处理。blog
(1)SQL%ISOPEN:游标是否开启
, true:开启,false:关闭
(2)SQL%FOUND:前一个 fetch 语句是否有值
,true:有,false:没有
(3)SQL%NOTFOUND:与上述相反,常被用于 退出循环
,true:没有,false:有, null : 空。注意哦,只有 为 true 时,才退出(当 第一次 fetch 为 null 时,不会退出!)
(4)SQL%ROWCOUNT:当前成功执行的数据行数(非总记录数
)
举例:用隐式游标测试插入,更新,删除,查询等
--隐式游标 declare v_count number; begin insert into hu_test(owner,object_type,created) values('SYS','test',sysdate); IF SQL%FOUND THEN dbms_output.put_line('插入成功!'); commit; END IF; update hu_test e set e.object_type='CLUSTER1' where e.object_type='CLUSTER'; IF SQL%FOUND THEN dbms_output.put_line('更新成功!'); commit; END IF; delete from hu_test e where e.object_id=3; IF SQL%FOUND THEN dbms_output.put_line('删除成功!'); commit; END IF; select count(*) into v_count from hu_test; IF SQL%FOUND THEN dbms_output.put_line('总记录为: '||v_count); END IF; IF SQL%ISOPEN THEN dbms_output.put_line('可手动查看'); ELSE dbms_output.put_line('没法手动查看'); END IF; EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE || ' : ' || SQLERRM); dbms_output.put_line(dbms_utility.format_error_backtrace); end;
4.游标FOR循环:隐含的执行了打开提取关闭数据,代码精简不少,syntax:
FOR table_record IN table_cursor LOOP STATEMENT; END LOOP;
举例:游标FOR循环
DECLARE cursor hu_test_cursor is select owner,object_type,created from hu_test; BEGIN FOR test_cursor IN hu_test_cursor LOOP dbms_output.put_line('全部者:'||test_cursor.owner||' 类型是:'||test_cursor.object_type||' 建立时间:'||test_cursor.created); END LOOP; END;
这里游标FOR循环省去了对于取到的数据的变量的命名和赋值,同时若是所有打印则不用写循环条件,代码精简了不少。
若是想让代码更加精简,则能够去掉对游标的声明引入子查询便可,操做以下。
--更简便的for循环 BEGIN FOR test_cursor IN (select owner,object_type,created from hu_test) LOOP dbms_output.put_line('全部者:'||test_cursor.owner||' 类型是:'||test_cursor.object_type||' 建立时间:'||test_cursor.created); END LOOP; END;
5.参数游标,动态游标1
举例:输入object_id查询相关数据
--参数游标 declare cursor hu_test_cursor(numid number) is select owner,object_type,created from hu_test e where e.object_id=numid; BEGIN FOR test_cursor IN hu_test_cursor(&numid) LOOP--这里也能够用一个变量来赋值 dbms_output.put_line('全部者:'||test_cursor.owner||' 类型是:'||test_cursor.object_type||' 建立时间:'||test_cursor.created); END LOOP; END;
6.参数游标,动态游标2
--动态游标 declare v_id hu_test.object_id%type; v_sql varchar2(2000); type test_cursor_type is ref cursor; test_cursor test_cursor_type; v_owner hu_test.owner%type; v_object_type hu_test.object_type%type; v_created hu_test.created%type; BEGIN v_id:=20; v_sql:='select owner,object_type,created from hu_test e where e.object_id = :v_id'; open test_cursor for v_sql using v_id; loop fetch test_cursor into v_owner,v_object_type,v_created; exit when test_cursor%notfound; dbms_output.put_line('全部者:'||v_owner||' 类型是:'||v_object_type||' 建立时间:'||v_created); END LOOP; close test_cursor; EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE || ' : ' || SQLERRM); dbms_output.put_line(dbms_utility.format_error_backtrace); END;