Oracle游标详细.docx

上传人:b****5 文档编号:5649351 上传时间:2022-12-30 格式:DOCX 页数:9 大小:20.22KB
下载 相关 举报
Oracle游标详细.docx_第1页
第1页 / 共9页
Oracle游标详细.docx_第2页
第2页 / 共9页
Oracle游标详细.docx_第3页
第3页 / 共9页
Oracle游标详细.docx_第4页
第4页 / 共9页
Oracle游标详细.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

Oracle游标详细.docx

《Oracle游标详细.docx》由会员分享,可在线阅读,更多相关《Oracle游标详细.docx(9页珍藏版)》请在冰豆网上搜索。

Oracle游标详细.docx

Oracle游标详细

这个文档几乎包含了oracle游标使用的方方面面,全部通过了测试

--声明游标;CURSORcursor_nameISselect_statement

--For循环游标

--

(1)定义游标

--

(2)定义游标变量

--(3)使用for循环来使用这个游标

declare

--类型定义

cursorc_job

is

selectempno,ename,job,sal

fromemp

wherejob='MANAGER';

--定义一个游标变量v_cinfoc_emp%ROWTYPE,该类型为游标c_emp中的一行数据类型

c_rowc_job%rowtype;

begin

forc_rowinc_jobloop

dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal);

endloop;

end;

--Fetch游标

--使用的时候必须要明确的打开和关闭

declare

--类型定义

cursorc_job

is

selectempno,ename,job,sal

fromemp

wherejob='MANAGER';

--定义一个游标变量

c_rowc_job%rowtype;

begin

openc_job;

loop

--提取一行数据到c_row

fetchc_jobintoc_row;

--判读是否提取到值,没取到值就退出

--取到值c_job%notfound是false

--取不到值c_job%notfound是true

exitwhenc_job%notfound;

dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal);

endloop;

--关闭游标

closec_job;

end;

--1:

任意执行一个update操作,用隐式游标sql的属性%found,%notfound,%rowcount,%isopen观察update语句的执行情况。

begin

updateempsetENAME='ALEARK'WHEREEMPNO=7469;

ifsql%isopenthen

dbms_output.put_line('Openging');

else

dbms_output.put_line('closing');

endif;

ifsql%foundthen

dbms_output.put_line('游标指向了有效行');--判断游标是否指向有效行

else

dbms_output.put_line('Sorry');

endif;

ifsql%notfoundthen

dbms_output.put_line('AlsoSorry');

else

dbms_output.put_line('Haha');

endif;

dbms_output.put_line(sql%rowcount);

exception

whenno_data_foundthen

dbms_output.put_line('SorryNodata');

whentoo_many_rowsthen

dbms_output.put_line('TooManyrows');

end;

declare

empNumberemp.EMPNO%TYPE;

empNameemp.ENAME%TYPE;

begin

ifsql%isopenthen

dbms_output.put_line('Cursorisopinging');

else

dbms_output.put_line('CursorisClose');

endif;

ifsql%notfoundthen

dbms_output.put_line('NoValue');

else

dbms_output.put_line(empNumber);

endif;

dbms_output.put_line(sql%rowcount);

dbms_output.put_line('-------------');

selectEMPNO,ENAMEintoempNumber,empNamefromempwhereEMPNO=7499;

dbms_output.put_line(sql%rowcount);

ifsql%isopenthen

dbms_output.put_line('Cursorisopinging');

else

dbms_output.put_line('CursorisClosing');

endif;

ifsql%notfoundthen

dbms_output.put_line('NoValue');

else

dbms_output.put_line(empNumber);

endif;

exception

whenno_data_foundthen

dbms_output.put_line('NoValue');

whentoo_many_rowsthen

dbms_output.put_line('toomanyrows');

end;

--2,使用游标和loop循环来显示所有部门的名称

--游标声明

declare

cursorcsr_dept

is

--select语句

selectDNAME

fromDepth;

--指定行指针,这句话应该是指定和csr_dept行类型相同的变量

row_deptcsr_dept%rowtype;

begin

--for循环

forrow_deptincsr_deptloop

dbms_output.put_line('部门名称:

'||row_dept.DNAME);

endloop;

end;

--3,使用游标和while循环来显示所有部门的的地理位置(用%found属性)

declare

--游标声明

cursorcsr_TestWhile

is

--select语句

selectLOC

fromDepth;

--指定行指针

row_loccsr_TestWhile%rowtype;

begin

--打开游标

opencsr_TestWhile;

--给第一行喂数据

fetchcsr_TestWhileintorow_loc;

--测试是否有数据,并执行循环

whilecsr_TestWhile%foundloop

dbms_output.put_line('部门地点:

'||row_loc.LOC);

--给下一行喂数据

fetchcsr_TestWhileintorow_loc;

endloop;

closecsr_TestWhile;

end;

select*fromemp

--4,接收用户输入的部门编号,用for循环和游标,打印出此部门的所有雇员的所有信息(使用循环游标)

--CURSORcursor_name[(parameter[,parameter],...)]ISselect_statement;

--定义参数的语法如下:

Parameter_name[IN]data_type[{:

=|DEFAULT}value]

declare

CURSOR

c_dept(p_deptNonumber)

is

select*fromempwhereemp.depno=p_deptNo;

r_empemp%rowtype;

begin

forr_empinc_dept(20)loop

dbms_output.put_line('员工号:

'||r_emp.EMPNO||'员工名:

'||r_emp.ENAME||'工资:

'||r_emp.SAL);

endloop;

end;

select*fromemp

--5:

向游标传递一个工种,显示此工种的所有雇员的所有信息(使用参数游标)

declare

cursor

c_job(p_jobnvarchar2)

is

select*fromempwhereJOB=p_job;

r_jobemp%rowtype;

begin

forr_jobinc_job('CLERK')loop

dbms_output.put_line('员工号'||r_job.EMPNO||''||'员工姓名'||r_job.ENAME);

endloop;

end;

SELECT*FROMEMP

--6:

用更新游标来为雇员加佣金:

(用if实现,创建一个与emp表一摸一样的emp1表,对emp1表进行修改操作),并将更新前后的数据输出出来

--

createtableemp1asselect*fromemp;

declare

cursor

csr_Update

is

select*fromemp1forupdateOFSAL;

empInfocsr_Update%rowtype;

saleInfoemp1.SAL%TYPE;

begin

FORempInfoINcsr_UpdateLOOP

IFempInfo.SAL<1500THEN

saleInfo:

=empInfo.SAL*1.2;

elsifempInfo.SAL<2000THEN

saleInfo:

=empInfo.SAL*1.5;

elsifempInfo.SAL<3000THEN

saleInfo:

=empInfo.SAL*2;

ENDIF;

UPDATEemp1SETSAL=saleInfoWHERECURRENTOFcsr_Update;

ENDLOOP;

END;

--7:

编写一个PL/SQL程序块,对名字以‘A’或‘S’开始的所有雇员按他们的基本薪水(sal)的10%给他们加薪(对emp1表进行修改操作)

declare

cursor

csr_AddSal

is

select*fromemp1whereENAMELIKE'A%'ORENAMELIKE'S%'forupdateOFSAL;

r_AddSalcsr_AddSal%rowtype;

saleInfoemp1.SAL%TYPE;

begin

forr_AddSalincsr_AddSalloop

dbms_output.put_line(r_AddSal.ENAME||'原来的工资:

'||r_AddSal.SAL);

saleInfo:

=r_AddSal.SAL*1.1;

UPDATEemp1SETSAL=saleInfoWHERECURRENTOFcsr_AddSal;

endloop;

end;

--8:

编写一个PL/SQL程序块,对所有的salesman增加佣金(comm)500

declare

cursor

csr_AddComm(p_jobnvarchar2)

is

select*fromemp1whereJOB=p_jobFORUPDATEOFCOMM;

r_AddCommemp1%rowtype;

commInfom%type;

begin

forr_AddCommincsr_AddComm('SALESMAN')LOOP

commInfo:

=r_AddComm.COMM+500;

UPDATEEMP1SETCOMM=commInfowhereCURRENTOFcsr_AddComm;

ENDLOOP;

END;

--9:

编写一个PL/SQL程序块,以提升2个资格最老的职员为MANAGER(工作时间越长,资格越老)

--(提示:

可以定义一个变量作为计数器控制游标只提取两条数据;也可以在声明游标的时候把雇员中资格最老的两个人查出来放到游标中。

declare

cursorcrs_testComput

is

select*fromemp1orderbyHIREDATEasc;

--计数器

top_twonumber:

=2;

r_testComputcrs_testComput%rowtype;

begin

opencrs_testComput;

FETCHcrs_testComputINTOr_testComput;

whiletop_two>0loop

dbms_output.put_line('员工姓名:

'||r_testComput.ENAME||'工作时间:

'||r_testComput.HIREDATE);

--计速器减一

top_two:

=top_two-1;

FETCHcrs_testComputINTOr_testComput;

endloop;

closecrs_testComput;

end;

--10:

编写一个PL/SQL程序块,对所有雇员按他们的基本薪水(sal)的20%为他们加薪,

--如果增加的薪水大于300就取消加薪(对emp1表进行修改操作,并将更新前后的数据输出出来)

declare

cursor

crs_UpadateSal

is

select*fromemp1forupdateofSAL;

r_UpdateSalcrs_UpadateSal%rowtype;

salAddemp1.sal%type;

salInfoemp1.sal%type;

begin

forr_UpdateSalincrs_UpadateSalloop

salAdd:

=r_UpdateSal.SAL*0.2;

ifsalAdd>300then

salInfo:

=r_UpdateSal.SAL;

dbms_output.put_line(r_UpdateSal.ENAME||':

加薪失败。

'||'薪水维持在:

'||r_UpdateSal.SAL);

else

salInfo:

=r_UpdateSal.SAL+salAdd;

dbms_output.put_line(r_UpdateSal.ENAME||':

加薪成功.'||'薪水变为:

'||salInfo);

endif;

updateemp1setSAL=salInfowherecurrentofcrs_UpadateSal;

endloop;

end;

--11:

将每位员工工作了多少年零多少月零多少天输出出来

--近似

--CEIL(n)函数:

取大于等于数值n的最小整数

--FLOOR(n)函数:

取小于等于数值n的最大整数

--truc的用法

declare

cursor

crs_WorkDay

is

selectENAME,HIREDATE,trunc(months_between(sysdate,hiredate)/12)ASSPANDYEARS,

trunc(mod(months_between(sysdate,hiredate),12))ASmonths,

trunc(mod(mod(sysdate-hiredate,365),12))asdays

fromemp1;

r_WorkDaycrs_WorkDay%rowtype;

begin

forr_WorkDayincrs_WorkDayloop

dbms_output.put_line(r_WorkDay.ENAME||'已经工作了'||r_WorkDay.SPANDYEARS||'年,零'||r_WorkDay.months||'月,零'||r_WorkDay.days||'天');

endloop;

end;

--12:

输入部门编号,按照下列加薪比例执行(用CASE实现,创建一个emp1表,修改emp1表的数据),并将更新前后的数据输出出来

--deptnoraise(%)

--105%

--2010%

--3015%

--4020%

--加薪比例以现有的sal为标准

--CASEexprWHENcomparison_exprTHENreturn_expr

--[,WHENcomparison_exprTHENreturn_expr]...[ELSEelse_expr]END

declare

cursor

crs_caseTest

is

select*fromemp1forupdateofSAL;

r_caseTestcrs_caseTest%rowtype;

salInfoemp1.sal%type;

begin

forr_caseTestincrs_caseTestloop

case

whenr_caseTest.DEPNO=10

THENsalInfo:

=r_caseTest.SAL*1.05;

whenr_caseTest.DEPNO=20

THENsalInfo:

=r_caseTest.SAL*1.1;

whenr_caseTest.DEPNO=30

THENsalInfo:

=r_caseTest.SAL*1.15;

whenr_caseTest.DEPNO=40

THENsalInfo:

=r_caseTest.SAL*1.2;

endcase;

updateemp1setSAL=salInfowherecurrentofcrs_caseTest;

endloop;

end;

--13:

对每位员工的薪水进行判断,如果该员工薪水高于其所在部门的平均薪水,则将其薪水减50元,输出更新前后的薪水,员工姓名,所在部门编号。

--AVG([distinct|all]expr)over(analytic_clause)

---作用:

--按照analytic_clause中的规则求分组平均值。

--分析函数语法:

--FUNCTION_NAME(,...)

--OVER

--(

--PARTITION子句

--按照表达式分区(就是分组),如果省略了分区子句,则全部的结果集被看作是一个单一的组

select*fromemp1

DECLARE

CURSOR

crs_testAvg

IS

selectEMPNO,ENAME,JOB,SAL,DEPNO,AVG(SAL)OVER(PARTITIONBYDEPNO)ASDEP_AVG

FROMEMP1forupdateofSAL;

r_testAvgcrs_testAvg%rowtype;

salInfoemp1.sal%type;

begin

forr_testAvgincrs_testAvgloop

ifr_testAvg.SAL>r_testAvg.DEP_AVGthen

salInfo:

=r_testAvg.SAL-50;

endif;

updateemp1setSAL=salInfowherecurrentofcrs_testAvg;

endloop;

end;

posted@2011-12-0323:

21 肖雄 Views(4672) Comments

(1) Edit 收藏

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1