/*
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;