/*
SQL语句
1.有哪些部门
select deptno from dept; -->光标 -->循环 -->退出条件:notfound
2.部门中员工的薪水
select sal from emp where deptno = ? -->带一个参数的光标-->循环-->退出条件:notfound
变量: 1.初始值 2.如何得到每个段的员工人数
count1 number;
count2 number;
count3 number;
每个部门的工资总额:
saltotal number;
1.SELECT sum(sal) into saltotal from emp where deptno = ???
2.累计
*/
set serveroutput ON
DECLARE
--部门的光标
CURSOR cdept is SELECT deptno from dept;
pdeptno dept.deptno%type;
--部门中员工的薪水
CURSOR cemp(dno NUMBER) is SELECT sal from emp where deptno = dno;
psal emp.sal%type;
--员工人数
count1 number;
count2 number;
count3 number;
--每个部门的工资总额:
saltotal number;
BEGIN
--打开部门光标
open cdept;
LOOP
fetch cdept into pdeptno;
EXIT when cdept%notfound;
--初始化工作
count1 :=0; count2:= 0; count3 := 0;
--得到部门的工资总额
--1.SELECT sum(sal) into saltotal from emp where deptno = ???
--2.saltotal:=0;
SELECT sum(sal) into saltotal from emp where deptno = pdeptno;
--取部门中员工的薪水
open cemp(pdeptno);
LOOP
--取一个员工的薪水
fetch cemp into psal;
EXIT WHEN cemp%notfound;
--saltotal:=saltotal+psal;
--判断薪水范围
if psal < 3000 then count1:=count1+1;
ELSIF psal >= 3000 and psal < 6000 THEN count2:=count2+1;
ELSE count3:=count3+1;
end if;
end loop;
--关闭员工光标
close cemp;
--保存当前部门的结果
insert into msg VALUES( pdeptno,count1,count2,count3,NVL(saltotal,0) );
end LOOP;
--关闭部门光标
close cdept;
dbms_output.put_line('统计完成');
end;
/
右击scott,刷新,可以看到新建的表
表数据 全选 点叉 点执行,可以删除数据
create table msg(
deptno number,
count1 number,
count2 number,
count3 number,
saltotal number);
set serveroutput on
declare
--获取所有部门
cursor c_dept is select deptno from dept;
--各部门编号
p_dno dept.deptno%type;
--各部门总金额
p_totalsal number;
--各工资分段人数:
num1 number;
num2 number;
num3 number;
--定义一个游标存放该部门下所有员工(带参数)
cursor c_emp(dno number) is select sal from emp where deptno = dno;
--员工的薪水
p_sal number;
begin
--打开部门游标
open c_dept;
loop --部门循环
fetch c_dept into p_dno;
exit when c_dept%notfound;
--初始化变量:
p_totalsal:=0;
num1:=0;
num2:=0;
num3:=0;
--获取本部门下所有员工,打开员工游标
open c_emp(p_dno);
loop --员工循环
fetch c_emp into p_sal;
exit when c_emp%notfound;
if p_sal <3000 then num1:=num1+1;
elsif p_sal >=3000 and p_sal<=6000 then num2:=num2+1;
elsif p_sal>6000 then num3:=num3+1;
end if;
--获取总金额
p_totalsal:=p_totalsal+p_sal;
end loop;
close c_emp;
--保存统计结果到msg
insert into msg values(p_dno,num1,num2,num3,p_totalsal);
end loop;
close c_dept;
commit;
dbms_output.put_line('统计完成');
end;
/
nvl(String1,replace_with )函数:当String1中的数为NULL时,用repalce_with中的数值代替String1中的数。
还没看视频先做一遍。。。唉,还是有很多问题。
set serveroutput on; DECLARE number1 NUMBER:=0; --小于3000元以下 number2 NUMBER:=0; --3000至6000之间 number3 NUMBER:=0; -- 6000以上 countAll NUMBER:=0; --小于3000元以下总额 tempDeptno NUMBER; --当选部门 CURSOR cemp IS SELECT d.deptno, d.dname, e.sal FROM emp e RIGHT JOIN dept d ON e.deptno=d.deptno; pdeptno dept.deptno%type; pdname dept.dname%type; psal emp.sal%type; BEGIN SELECT deptno INTO tempDeptno FROM dept WHERE rownum <=1 ORDER BY deptno ASC ; --第一个部门 OPEN cemp; --开启光标 LOOP --开启循环 FETCH cemp INTO pdeptno,pdname,psal; --赋值 EXIT WHEN cemp%notfound; IF pdeptno!=tempDeptno THEN --换部门啦 dbms_output.put_line('部门号:'||tempDeptno||',小于3000元的人数为:'||number1||',3000到6000区间的人数为:'||number2||',6000以上的人数为:'||number3||',总额为:'||countAll); number1 :=0; --重置数据 number2 :=0; number3 :=0; countAll :=0; tempDeptno := pdeptno; IF psal <3000 THEN number1 :=number1+1; elsif psal>=3000 AND psal<=6000 THEN number2 :=number2+1; ELSE number3:=number3+1; END IF; countAll := countAll+psal; ELSE IF psal <3000 THEN number1 :=number1+1; elsif psal>=3000 AND psal<=6000 THEN number2 :=number2+1; ELSE number3:=number3+1; END IF; countAll := countAll+psal; END IF; END LOOP; CLOSE cemp; --一旦结束循环就是最后一个部门的参数了。 dbms_output.put_line('部门号:'||tempDeptno||',小于3000元的人数为:'||number1||',3000到6000区间的人数为:'||number2||',6000以上的人数为:'||number3||',总额为:'||nvl(countAll,0)); END;