-
rowcount不是指一共多少行
查看全部 -
接受键盘输入
accept num prompt ' ****提示****‘;
num是地址值
查看全部 -
DECLARE CURSOR CUR IS SELECT A.EMPNO,A.ENAME FROM SCOTT.EMP A;
V_EMPNO SCOTT.EMP.EMPNO%TYPE;
V_ENAME SCOTT.EMP.ENAME%TYPE;
BEGIN
--打开游标
OPEN CUR;
--判断是否打开
IF CUR%ISOPEN THEN
LOOP
--当无数据时,退出循环
EXIT WHEN CUR%NOTFOUND;
FETCH CUR INTO V_EMPNO,V_ENAME;
DBMS_OUTPUT.put_line(V_EMPNO||':'||V_ENAME);
END LOOP;
--关闭游标
CLOSE CUR;
END IF;
END;
查看全部 -
-------------------PL/SQL程序设计方法-------------------
--瀑布模型
/*
1.需求分析
2.设计
1)概要设计
2)详细设计
3.编码 (Coding)
4.测试(Testing)
5.上线
SQL语句
变量:
1.初始值是多少
2.最终值如何得到
*/
------案例1、统计每年入职的员工人数-----
--SQL语句
select to_char(hiredate,'yyyy') from emp;
--> 游标 --> 循环 --> 退出条件:notfound
/*
变量:1.初始值 2.如何得到
每年入职的员工人数:
count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
*/
set serveroutput on;
declare
cursor cemp is select to_char(hiredate,'yyyy') from emp; --定义游标,从表中取出员工入职年份
phiredate varchar2(4);
--每年入职的员工人数:
count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
begin
open cemp;
loop
fetch cemp into phiredate; --取出一个员工的入职年份
exit when cemp%notfound; --取不到退出
--判断入职年份
if phiredate = '1980' then count80 := count80 + 1;
elsif phiredate = '1981' then count81 := count81 +1;
elsif phiredate = '1982' then count82 := count82 +1;
else count87 := count87 + 1;
end if;
end loop;
close cemp;
--输出结果
dbms_output.put_line('Total:'||(count80 + count81 + count82 + count87));
dbms_output.put_line('1980:'||count80);
dbms_output.put_line('1981:'||count81);
dbms_output.put_line('1982:'||count82);
dbms_output.put_line('1987:'||count87);
end;
/
/*
---案例2、为员工涨工资。从最低工资涨起,每人涨10%,单工资总额不能超过5万元,请计算涨工资的人数和涨工资后的工资总额,并输出涨工资人数及工资总额。
SQL语句
select empno,sal from emp order by sal;
-- > 游标 --> 循环 --> 退出条件: 1.工资总额>5w 2.%notfound
变量:1.初始值 2.如何得到
涨工资的人数: countEmp number := 0;
涨后的工资总额:salTotal number;
1.select sum(sal) into salTotal from emp;
2.涨后的工资总额=涨前的工资总额 + sal * 0.1
*/
set serveroutput on;
declare
cursor cemp is select empno,sal from emp order by sal; --定义游标
pempno emp.empno%type; --定义员工编号变量
psal emp.sal%type; --定义员工工资变量
countEmp number := 0; --涨工资人数计数器
salTotal number; --涨后的工资
begin
select sum(sal) into salTotal from emp; --给合计工资赋值
open cemp;
loop
exit when salTotal >50000; --合计工资大于5w退出循环
fetch cemp into pempno,psal; --从游标取值赋值到变量
exit when cemp%notfound; --取不到值退出循环
if salTotal + psal * 0.1 <= 50000 then --涨后的工资小于5w才执行涨工资
update emp set sal = sal * 1.1 where emp.empno = pempno; --执行涨工资
countEmp := countEmp + 1; --统计张工资的人数
salTotal := salTotal + psal * 0.1; --涨后的工资总额
end if;
end loop;
close cemp;
--commit; 提交最终涨工资事务
dbms_output.put_line('涨工资的人数为:'||countEmp);
dbms_output.put_line('涨工资后的工资总额为:'||salTotal);
end;
/
/*
案例3、用PL/SQL语言编写程序,实现按部门分段(6000以上、(6000、3000)3000以下)统计各工资段的职工人数、以及各部门的工资总额(工资总额中不包括奖金)
SQL语句
1.有哪些部门
select deptno from dept; --游标 --> 循环 --> 退出条件:notfound
2.部门中员工的薪水
select sal from emp where deptno = ? 带一个参数的游标 --> 循环 --> 退出条件:notfound
变量:1.初始值 2.如何得到
每个段的员工人数:
count1 number;
count2 number;
count3 number;
每个部门的工资总额: 有2中方式获取
saltotal number;
1.select sum(sal) into saltotal from emp where deptno = ???
2.累加
*/
--创建一张表保存各工资段数据
create table msg(
deptno number,
count1 number,
count2 number,
count3 number,
saltotal number);
SELECT * FROM msg;
--程序第一种实现方式,SQL统计
DECLARE
CURSOR cdept IS SELECT deptno FROM dept; --定义游标,取出部门
pdeptno dept.deptno%TYPE; --定义部门变量
CURSOR cemp(dno NUMBER) IS SELECT sal FROM emp WHERE deptno = pdeptno; --部门中员工的薪水
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;
--得到部门的工资总额
SELECT SUM(sal) INTO saltotal FROM emp WHERE deptno = pdeptno;
--取部门中员工的薪水
OPEN cemp(pdeptno); --打开员工游标
LOOP
FETCH cemp INTO psal;
EXIT WHEN cemp%NOTFOUND;
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; --关闭部门游标
--COMMIT;
dbms_output.put_line('统计完成');
END;
/
--程序第二种实现方式,算数累加
DECLARE
CURSOR cdept IS SELECT deptno FROM dept; --定义游标,取出部门
pdeptno dept.deptno%TYPE; --定义部门变量
CURSOR cemp(dno NUMBER) IS SELECT sal FROM emp WHERE deptno = pdeptno; --部门中员工的薪水
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;
saltotal := 0;
--取部门中员工的薪水
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; --关闭部门游标
COMMIT;
dbms_output.put_line('统计完成');
END;
/
SELECT * FROM msg;
/*
案例3、用plsql语言编写一个程序。按系(系名)分段统计(成绩小于60分,60-85分,85分以上)“大学物理”课程各分数段的学生人数,及各系学生的平均成绩。
1.SQL.语句
1).得到有哪些系
select dno,dname from dep; --> 游标 -- 循环 --> 退出条件:notfound
2).得到系中,选修了“大学物理”课程学生的成绩
select grade from sc where cno = (select cno from course where cname = ???)
and sno in (select sno from student where dno = ???);
--> 带参数的光标 --> 循环 --> 退出条件:notfound
2.变量:1).初始值 2).如何得到
count1 number; count2 number; count3 number; 每个分数段的人数
avggrade number; 每个系选修了“大学物理”学生平均成绩
1.算术运算
2.select avg(grade) into avggrade from sc where cno = (select cno from course where cname=???)
and sno in (select sno from student where dno = ???);
*/
--创建一个表存储结果
CREATE TABLE msg1(
coursename VARCHAR2(20),
dnma VARCHAR2(20),
count1 NUMBER,
count2 NUMBER,
count3 NUMBER,
avggrade NUMBER
);
--程序
SET serveroutput ON;
DECLARE
--定义系的游标
CURSOR cdept IS select dno,dname from dep;
pdno dep.dno%TYPE;
pdname dep.dname%TYPE;
--定义成绩游标
CURSOR cgrade(coursename VARCHAR2, depno NUMBER)
IS select grade from sc where cno = (select cno from course where cname=coursename)
and sno in (select sno from student where dno = depno);
pgrade sc.grade%TYPE;
count1 number; count2 number; count3 number; --每个分数段的人数
avggrade NUMBER; --每个系选修了“大学物理”学生平均成绩
pcourseName VARCHAR2(20) := '大学物理'; --课程名称
BEGIN
OPEN cdept; --打开系的游标
LOOP
--取出一个系的信息
FETCH cdept INTO pdno,pdname;
EXIT WHEN cdept%NOTFOUND;
count1 := 0; count2 := 0; count3 := 0; --初始值
--系的平均成绩
select avg(grade) into avggrade from sc where cno = (select cno from course where cname=pcourseName)
and sno in (select sno from student where dno = pdno);
--取出系中,选修了大学物理的学生成绩
OPEN cgrade (pcourseName,pdno);
LOOP
--取出一个学生的成绩
FETCH cgrade INTO pgrade;
EXIT WHEN cgrade%NOTFOUND;
--判断成绩范围
IF pgrade < 60 THEN count1 := count1 + 1;
ELSIF pgrade >= 60 AND pgrade < 85 THEN count2 := COUNT2 + 1;
ELSE count3 := count3 + 1;
END IF;
END LOOP;
CLOSE cgrade;
--保存当前的结果
INSERT INTO msg1 VALUES(pcourseName,pdname,count1,count2,count3,avggrade);
END LOOP;
CLOSE cdept;
--COMMIT;
dbms_output.put_line('统计完成');
END;
/
SELECT * FROM msg1;
查看全部 -
if---then
elsif then
esle;
while---loop
end--loop;
exit while---loop
end loop;
for 变量名 in 1..10 loop
end loop;
查看全部 -
set serveroutput on
declare
cursor cm1 is select to_char(e.hiredate,'yyyy') from emp e;
pdate VARCHAR2(4);
count80 number:=0;
count81 number:=0;
count82 number:=0;
begin
open cm1;
loop
fetch cm1 into pdate;
exit when cm1%notfound;
if pdate='1980' then count80:=count80+1;
elsif pdate='1981' then count81:=count81+1;
elsif pdate='1982' then count82:=count82+1;
else count82:=count82+1;
end if;
end loop;
close cm1;
dbms_output.put_line('总共入职:'||(count80+count81+count82));
dbms_output.put_line('1980年入职:'||count80);
end;
/查看全部 -
例外是程序设计语言提供一种功能,用来增强程序的健壮性和容错性
系统例外
no_data_found 没有找到数据
too_many_rows select..into语句匹配多个行
Zero_Divide 被零除
Value_error 算数或转换错误
timeout_on_resource 在等待资源时发生超时
查看全部 -
1、光标的属性
%found %notfound
%isopen 判断光标是否打开
%rowcount 影响的行数
2、光标的限制:默认情况下,oracle数据库只允许在同一个会话中,打开300个光标
查看全部 -
光标语法
cursor 光标名 【(参数名 数据类型【,参数名 数据类型】...)】
is select 语句;
打开光标
open c1; (打开光标执行查询)
关闭光标
close c1; (关闭游标释放资源)
--取一行光标的值
fetch c1 into pename;(取一行到变量中)
查看全部 -
while 循环
while total <=2500 loop
....
end loop;
loop循环
looP
exit [when 条件];
....
end loop;
for循环
for i in 1..3 loop
....
end loop;
查看全部 -
if语句
1.if 条件 then 语句1;
语句2;
end if;
2. if 条件 then 语句序列 1;
esle 语句序列2;
end if;
3. if 条件 then 语句;
eslif 语句 then 语句;
else 语句;
end if;
/*
判断用户从键盘输入的数字
如何使用if语句
接收一个键盘输入(从键盘输的都是字符串)
*/
set serveroutput onaccept num prompt'请输入一个数字';
declare
pnum number = #
begin
if pnum=0 then
dbms_output.put_line('输入的数字为0');
elsif pnum =1
dbms_output.put_line('输入数字为1');
else dbms_output.put_line('输入的是其他数字');
end if;
end;
/
查看全部 -
:= 赋值查看全部
-
记录型变量 代表表中的一行(多个列),类似数组
emp_rec.列名 := ‘xxx’ --引用某一列的数据
查看全部 -
说明部分,变量定义,对变量赋值注意是 冒号+等号 进行赋值
查看全部 -
pl/sql程序结构
declare 说明部分,变量说明、光标申明、例外说明
begin开始(语句序列-dml语句) end+分号结尾 最后‘/’,中间exception(例外处理语句)
查看全部
举报