oracle cursor 为空,Oracle Cursor用法总结

cursor分为三种,一是直接声明为cursor变量,二是首先声明类型再声明变量,三是声明为sys_refcursor。

(1)直接声明

declare

cursoremp_curisselect*fromemp;

emp_record emp%rowtype;

begin

openemp_cur;

loop

fetchemp_curintoemp_record;

exitwhenemp_cur%notfound;

dbms_output.put_line('name is:'||

emp_record.ename ||' and sal is:'|| emp_record.sal);

endloop;

closeemp_cur;

end;

/

(2)ref cursor:分为强类型(有return子句的)和弱类型,强类型在使用时,其返回类型必须和return中的类型一致,否则报错,而弱类型可以随意打开任何类型。

例如:

强类型

declare

typeemp_cur_typeisrefcursorreturnemp%rowtype;

emp_cur emp_cur_type;

emp_record emp%rowtype;

begin

openemp_curforselect*fromemp;

loop

fetchemp_curintoemp_record;

exitwhenemp_cur%notfound;

dbms_output.put_line('name is:'||emp_record.ename ||' and sal is:'||

emp_record.sal);

endloop;

closeemp_cur;

--open emp_cur for select * from

dept;错误的,类型不一致。

--close emp_cur;

end;

/

弱类型:

declare

typeemp_cur_typeisrefcursor;

emp_cur emp_cur_type;

emp_record emp%rowtype;

dept_record dept%rowtype;

begin

openemp_curforselect*fromemp;

loop

fetchemp_curintoemp_record;

exitwhenemp_cur%notfound;

dbms_output.put_line('name is:'||

emp_record.ename ||' and sal is:'|| emp_record.sal);

endloop;

closeemp_cur;

openemp_curforselect*fromdept;--可再次打开,不同类型的

loop

fetchemp_curintodept_record;

exitwhenemp_cur%notfound;

dbms_output.put_line('dname is:'||

dept_record.dname);

endloop;

closeemp_cur;

end;

/

(3)sys_refcursor:可多次打开,直接声明此类型的变量,不用先定义类型再声明变量。

declare

emp_cursys_refcursor;

emp_record emp%rowtype;

dept_record dept%rowtype;

begin

openemp_curforselect*fromemp;

loop

fetchemp_curintoemp_record;

exitwhenemp_cur%notfound;

dbms_output.put_line('name is:'||

emp_record.ename ||' and sal is:'|| emp_record.sal);

endloop;

closeemp_cur;

openemp_curforselect*fromdept;--可再次打开,不同类型的

loop

fetchemp_curintodept_record;

exitwhenemp_cur%notfound;

dbms_output.put_line('dname is:'||

dept_record.dname);

endloop;

closeemp_cur;

end;

/

其他总结:

1、游标可以用for循环,但只限于cursor cur_var is……这种类型,用在其他的里面都是错误的;for本身就包含了打开、关闭游标,此时再显示打开关闭都是错误的。

declare

cursoremp_curisselect*fromemp;

begin

--open emp_cur;是错误的,因为for本身就包含了打开、关闭

foremp_recordinemp_cur

loop

dbms_output.put_line('name is:'||emp_record.ename ||' and sal is:'||

emp_record.sal);

endloop;

--close emp_cur;是错误的,for本身包含了关闭。

end;

--是不是表示:ref cursor变量不支持for打开并循环?

declare

typeemp_cur_typeisrefcursorreturnemp%rowtype;

emp_cur emp_cur_type;

begin

openemp_curforselect*fromemp;--怎么都是错,for已经打开了。

foremp_recordinemp_cur--不管前面有没有打开语句,for都不承认这种类型

loop

dbms_output.put_line('name is:'||emp_record.ename ||' and sal is:'||

emp_record.sal);

endloop;

end;

2、游标可以带参数

DECLARE

CURSORc1 (jobVARCHAR2, max_wageNUMBER)IS

SELECT*FROMemployeesWHEREjob_id = jobANDsalary >

max_wage;

BEGIN

FORpersonINc1('CLERK',3000)

LOOP

DBMS_OUTPUT.PUT_LINE('Name = '||

person.last_name ||', salary = '||

person.salary ||', Job Id = '|| person.job_id );

ENDLOOP;

END;

3、bulk collect批量赋值

declare

typeemp_cur_typeisrefcursor;

emp_cur emp_cur_type;

typename_lististableofemp.ename%type;

typesal_lististableofemp.sal%type;

names name_list;

sals sal_list;

begin

openemp_curforselectename,salfromemp;

fetchemp_curbulkcollectintonames,sals;

closeemp_cur;

foriinnames.first .. names.last

loop

dbms_output.put_line('name is:'||names(i)||' and sal is:'||sals(i));

endloop;

end;

/

4、cursor变量的位置

CREATEPACKAGEemp_dataAS

TYPEEmpCurTypISREFCURSORRETURNemployees%ROWTYPE;

-- emp_cv EmpCurTyp; -- not allowed

PROCEDUREopen_emp_cv;

ENDemp_data;

/

CREATEPACKAGEBODYemp_dataAS

-- emp_cv EmpCurTyp; -- not allowed

PROCEDUREopen_emp_cvIS

emp_cv EmpCurTyp;-- this is legal

BEGIN

OPENemp_cvFORSELECT*FROMemployees;

ENDopen_emp_cv;

ENDemp_data;

/

5、嵌套cursor

打开父cursor时,子cursor隐含打开;当

语法格式:cursor(subquery)

Anestedcursorisimplicitly  openedwhenthecontainingrowisfetchedfromtheparentcursor.

Thenestedcursorisclosedonlywhen:

Thenestedcursorisexplicitly  closedbytheuser

Theparentcursorisreexecuted

Theparentcursorisclosed

Theparentcursoriscanceled

示例;declare

typeemp_cur_typeisrefcursor;

typedept_cur_typeisrefcursor;

v_ename emp.ename%type;

v_dname dept.dname%type;

emp_cur emp_cur_type;

dept_cur dept_cur_type;

begin

opendept_curfor

selectd.dname,

cursor(selecte.enamefromemp  ewheree.deptno=d.deptno )emps

fromdept d;

loop

fetchdept_curintov_dname,emp_cur;

exitwhendept_cur%notfound;

dbms_output.put_line('dname is : '||v_dname);

loop

fetchemp_curintov_ename;

exitwhenemp_cur%notfound;

dbms_output.put_line('--ename is : '||v_ename);

endloop;

endloop;

closedept_cur;

end;

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值