Oracle 游标使用全解(三)

2015-07-16 12:09:19 · 作者: · 浏览: 9
前后的数据输出出来)
declare
? ? cursor
? ? ? ? crs_UpadateSal
? ? is
? ? ? ? select * from emp1 for update of SAL;
? ? ? ? r_UpdateSal crs_UpadateSal%rowtype;
? ? ? ? salAdd emp1.sal%type;
? ? ? ? salInfo emp1.sal%type;
begin
? ? ? ? for r_UpdateSal in crs_UpadateSal loop
? ? ? ? ? salAdd:= r_UpdateSal.SAL*0.2;
? ? ? ? ? if salAdd>300 then
? ? ? ? ? ? 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);
? ? ? ? ? end if;
? ? ? ? ? update emp1 set SAL=salInfo where current of crs_UpadateSal;
? ? ? ? end loop;
end;
? ?
--11:将每位员工工作了多少年零多少月零多少天输出出来?
--近似
? --CEIL(n)函数:取大于等于数值n的最小整数
? --FLOOR(n)函数:取小于等于数值n的最大整数
? --truc的用法 http://publish.it168.com/2005/1028/20051028034101.shtml
declare
? cursor
? crs_WorkDay
? is
? select ENAME,HIREDATE, trunc(months_between(sysdate, hiredate) / 12) AS SPANDYEARS,
? ? ? trunc(mod(months_between(sysdate, hiredate), 12)) AS months,
? ? ? trunc(mod(mod(sysdate - hiredate, 365), 12)) as days
? from emp1;
? r_WorkDay crs_WorkDay%rowtype;
begin
? ? for? r_WorkDay in crs_WorkDay loop
? ? dbms_output.put_line(r_WorkDay.ENAME||'已经工作了'||r_WorkDay.SPANDYEARS||'年,零'||r_WorkDay.months||'月,零'||r_WorkDay.days||'天');
? ? end loop;
end;
?
--12:输入部门编号,按照下列加薪比例执行(用CASE实现,创建一个emp1表,修改emp1表的数据),并将更新前后的数据输出出来
--? deptno? raise(%)
--? 10? ? ? 5%
--? 20? ? ? 10%
--? 30? ? ? 15%
--? 40? ? ? 20%
--? 加薪比例以现有的sal为标准
--CASE expr WHEN comparison_expr THEN return_expr
--[, WHEN comparison_expr THEN return_expr]... [ELSE else_expr] END
declare
? ? cursor
? ? ? ? crs_caseTest
? ? ? ? ? is
? ? ? ? ? select * from emp1 for update of SAL;
? ? ? ? ? r_caseTest crs_caseTest%rowtype;
? ? ? ? ? salInfo emp1.sal%type;
? ? begin
? ? ? ? for r_caseTest in crs_caseTest loop
? ? ? ? case
? ? ? ? ? when r_caseTest.DEPNO=10
? ? ? ? ? THEN salInfo:=r_caseTest.SAL*1.05;
? ? ? ? ? when r_caseTest.DEPNO=20
? ? ? ? ? THEN salInfo:=r_caseTest.SAL*1.1;
? ? ? ? ? when r_caseTest.DEPNO=30
? ? ? ? ? THEN salInfo:=r_caseTest.SAL*1.15;
? ? ? ? ? ? when r_caseTest.DEPNO=40
? ? ? ? ? THEN salInfo:=r_caseTest.SAL*1.2;
? ? ? ? end case;
? ? ? ? ? update emp1 set SAL=salInfo where current of crs_caseTest;
? ? ? ? end loop;
end;


--13:对每位员工的薪水进行判断,如果该员工薪水高于其所在部门的平均薪水,则将其薪水减50元,输出更新前后的薪水,员工姓名,所在部门编号。
--AVG([distinct|all] expr) over (analytic_clause)
---作用:
--按照analytic_clause中的规则求分组平均值。
? --分析函数语法:
? --FUNCTION_NAME(,...)
? --OVER
? --()
? ? --PARTITION子句
? ? --按照表达式分区(就是分组),如果省略了分区子句,则全部的结果集被看作是一个单一的组
? ? select * from emp1
DECLARE
? ? CURSOR
? ? crs_testAvg
? ? IS
? ? select EMPNO,ENAME,JOB,SAL,DEPNO,AVG(SAL) OVER (PARTITION BY DEPNO ) AS DEP_AVG
? ? FROM EMP1 for update of SAL;
? ? r_testAvg crs_testAvg%rowtype;
? ? salInfo emp1.sal%type;
? ? begin
? ? for r_testAvg in crs_testAvg loop
? ? if r_testAvg.SAL>r_testAvg.DEP_AVG then
? ? salInfo:=r_testAvg.SAL-50;
? ? end if;
? ? update emp1 set SAL=salInfo where current of crs_testAvg;
? ? end loop;
end;