例外:
例外是程序设计语言提供的一种功能,用来增强程序的健壮性和容错性.

例外分为:
系统例外
自定义例外

系统例外分为:
No_data_found(没有找到数据)、
Too_many_rows(select ... into 语句匹配多个行)、
Zero_Divide(被零除)、
Value_error(算数或转换错误,负数不能在实数范围开平方,abc不能转换成123)、
Timeout_on_resource(在等待资源时发生超时(分布式数据库))

No_data_found
组函数使用这个Exception无效,默认组函数在没有记录时会有默认的返回值 如count会返回0,max、min、avg等会返回空,这样的话是不会触发异常的

事例一:
--没有找到数据
set serveroutput on
declare
pename emp.ename%type;

begin
--查询员工号是1234的员工姓名
select ename into pename from emp where empno=1234;
exception
when no_data_found then
DBMS_OUTPUT.PUT_LINE('没有找到该员工');
when others then
DBMS_OUTPUT.PUT_LINE('其他例外');
end;
/

事例二:
--匹配多个行
set serveroutput on
declare
pename emp.ename%type;

begin
--查询所有10号部门的员工姓名
select ename into pename from emp where deptno=10;
exception
when too_many_rows then
DBMS_OUTPUT.PUT_LINE('select...into匹配了多个行');
when others then
DBMS_OUTPUT.PUT_LINE('其他例外');
end;
/
事例三:
--被零除
set serveroutput on
declare
--定义一个基本变量
pnum number;

begin
pnum :=1/0;
exception
when zero_divide then
DBMS_OUTPUT.PUT_LINE('1:0不能做除数');
DBMS_OUTPUT.PUT_LINE('2:0不能做除数');
when others then
DBMS_OUTPUT.PUT_LINE('其他例外');
end;
/
例外四:
-----value_error算数或转换错误
set serveroutput on
declare
--定义一个基本变量
pnum number;

begin
pnum :='abc';
exception
when value_error then
DBMS_OUTPUT.PUT_LINE('算数或者转换错误');
when others then
DBMS_OUTPUT.PUT_LINE('其他例外');
end;
/

自定义例外
(1)定义变量,类型是Exception
(2)使用raise抛出自定义例外

事例:
set serveroutput on
declare

cursor cemp is select ename from emp where deptno=50;
--定义一个基本变量
pename emp.ename%type;

--自定义例外
no_emp_found exception;

begin
open cemp;
--取出一条记录
fetch cemp into pename;
if cemp%notfound then
--抛出例外
raise no_emp_found;
end if;

--关闭游标
--oralce自动启动进程监视器pmon(process monition)
close cemp;
exception
when no_emp_found then
DBMS_OUTPUT.PUT_LINE('没有找到员工');
when others then
DBMS_OUTPUT.PUT_LINE('其他例外');
end;
/

PL/SQL程序设计综合案例
程序设计方法
瀑布模型
需求分析
设计
概要设计
详细设计
编码
测试
部署
运营

思考:所需要的SQl语句和变量
变量:1、初始值是多少
2、最终值如何得到

综合案例1
统计每年入职的员工人数
Total 1980 1981 1982 1987
======== ======= ========== ======== =========
14 1 10 1 2

注意:员工的入职年份已知

方法一(函数方式):
select count(*) Total,
sum(decode(to_char(hiredate,'YYYY'),'1980',1,0)) "1980",
sum(decode(to_char(hiredate,'YYYY'),'1981',1,0)) "1981",
sum(decode(to_char(hiredate,'YYYY'),'1982',1,0)) "1982",
sum(decode(to_char(hiredate,'YYYY'),'1987',1,0)) "1987"
from emp;

/*
SQL语句
select to_char(hiredate,'yyyy') from emp;
--->光标--->循环--->退出条件:notfound

变量:1.初始值2.如何得到
每年入职的员工人数:
count80 number:=0;
count81 number:=0;
count82 number:=0;
count87 number:=0;
*/

PL/SQL开发:

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

PL/SQL开发:
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
--1、工资总额>5W
exit when salTotal > 50000;
--取一个员工涨工资
fetch cemp into pempno,psal;
--2、%notfound
exit when cemp%notfound;
if (salTotal + psal*0.1) > 50000
then dbms_output.put_line('超额不能涨工资了');

--涨工资
else update emp set sal=sal*1.1 where empno=pempno;
--人数+1
countEmp:=countEmp+1;

--2、涨后的工资总额=涨前的工资总额+sal*0.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元以下)统计各工资段的职工人数、以及各部门的工资总额(工资总额中不包括奖金)
建立一张表
create table msg(
deptno number,
count1 number,
count2 number,
count3 number,
saltotal number
);

分析:
SQl语句
1、有哪些部门
select deptno from dept;
-->光标-->循环-->退出条件:1、工资总额>5W 2、%notfound
2、部门中员工的薪水
select sal from emp where deptno=? -->带一个参数的光标-->循环-->退出条件:notfound(=true)

变量:1、初始值 2、如何得到
每个段的员工人数:
count1 number := 0;
count2 number := 0;
count3 number := 0;

每个部门的工资总额:
salTotal number;
1、select sum(sal) into salTotal from emp where deptno=???;
2、累加(优越)

PL/SQL开发:
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=???
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;
commit;
dbms_output.put_line('统计完成!!');
end;
/

查看结果:
select * from msg;

综合案例4
用PL/SQL语言编写一个程序.按系(系名)分段统计(成绩小于60分,60-85分,85分以上)"大学物理"课程各分数段的学生人数,及各系学生的平均成绩.
(多表查询和子查询)

脚本student.sql
drop table sc;
drop table course;
drop table student;
drop table teacher;
drop table dep;

create table dep(
dno number(2),
dname varchar2(30),
director number(4),
tel varchar(8)
);

create table teacher(
tno number(4),
tname varchar2(10),
title varchar2(20),
hiredate date,
sal number(7,2),
bonus number(7,2),
mgr number(4),
deptno number(2)
);

create table student(
sno number(6),
sname varchar2(8),
sex varchar2(2),
birth date,
passwd varchar2(8),
dno number(2)
);

create table course(
cno varchar2(8),
cname varchar2(20),
credit number(1),
ctime number(2),
quota number(3)
);

create table sc(
sno number(6),
cno varchar2(8),
grade number(3)
);

alter table dep add(constraint pk_deptno primary key(dno));
alter table dep add(constraint dno_number_check check(dno>=10 and dno<=50));
alter table dep modify(tel default 62795032);
alter table student add(constraint pk_sno primary key(sno));
alter table student add(constraint sex_check check(sex='男' or sex='女'));
alter table student modify(birth default sysdate);
alter table course add(constraint pk_cno primary key(cno));
alter table sc add(constraint pk_key primary key(cno,sno));
alter table teacher add(constraint pk_tno primary key(tno));
alter table sc add(foreign key(cno) references course(cno));
alter table sc add(foreign key(sno) references student(sno));
alter table student add(foreign key(dno) references dep(dno));
alter table teacher add(foreign key(deptno) references dep(dno));

insert into dep values(10,'计算机学院',9469,'62785234');
insert into dep values(20,'自动化学院',9581,'62775234');
insert into dep values(30,'无线电学院',9791,'62778932');
insert into dep values(40,'信息管理学院',9611,'62785520');
insert into dep values(50,'微纳电子学院',2031,'62797686');

insert into teacher values(9468,'CHARLES','PROFESSOR','17-Dec-17',8000,1000,null,10);
insert into teacher values(9469,'SMITH','PROFESSOR','17-Dec-17',5000,1000,9468,10);
insert into teacher values(9470,'ALLEN','ASSOCIATE PROFESSOR','20-Feb-16',4200,500,9469,10);
insert into teacher values(9471,'WARD','LECTURER','22-Feb-17',3000,300,9469,10);
insert into teacher values(9581,'JONES','PROFESSOR','2-Apr-2016',6500,1000,9468,20);
insert into teacher values(9582,'MARTIN','ASSOCIATE PROFESSOR','28-Sep-2018',4000,800,9581,20);
insert into teacher values(9583,'BLAKE','LECTURER','1-May -2019',3000,300,9581,20);
insert into teacher values(9791,'CLAKE','PROFESSOR','9-Jun-2016',5500,null,9468,30);
insert into teacher values(9792,'SCOTT','ASSOCIATE PROFESSOR','09-Dec-17',4500,null,9791,30);
insert into teacher values(9793,'BAGGY','LECTURER','17-Nov-2017',3000,null,9791,30);
insert into teacher values(9611,'TURNER','PROFESSOR','8-Sep-2018',6000,1000,9468,40);
insert into teacher values(9612,'ADAMS','ASSOCIATE PROFESSOR','12-Jan-17',4800,800,9611,40);
insert into teacher values(9613,'JAMES','LECTURER','3-Dec-19',2800,200,9611,40);
insert into teacher values(2031,'FORD','PROFESSOR','3-Dec-18',5500,null,9468,50);
insert into teacher values(2032,'MILLER','ASSOCIATE PROFESSOR','23-Jan-2018',4300,null,2031,50);
insert into teacher values(2033,'MIGEAL','LECTURER','23-Jan-2019',2900,null,2031,50);
insert into teacher values(2034,'PEGGY','LECTURER','23-Jan-2020',2800,null,2031,50);

更改格式
alter session set nls_date_language='AMERICAN';
19-JUN-01

保存数据的表格
create table msg1(
coursename varchar2(20),
dname varchar2(20),
count1 number,
count2 number,
count3 number,
avggrade number
);

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

变量: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=??);

PL/SQL开发:
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;

Oracle学习笔记(十一)的更多相关文章

  1. Oracle学习笔记十一 游标

    游标的简介 游标的概念 游标是从数据表中提取出来的数据,以临时表的形式存放在内存中,在游标中有一个数据指针,在初始状态下指向的是首记录,利用fetch语句可以移动该指针,从而对游标中的数据进行各种操作 ...

  2. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  3. oracle学习笔记第一天

    oracle学习笔记第一天 --oracle学习的第一天 --一.几个基础的关键字   1.select select (挑选) 挑选出显示的--列--(可以多列,用“,”隔开,*表示所有列),为一条 ...

  4. python3.4学习笔记(十一) 列表、数组实例

    python3.4学习笔记(十一) 列表.数组实例 #python列表,数组类型要相同,python不需要指定数据类型,可以把各种类型打包进去#python列表可以包含整数,浮点数,字符串,对象#创建 ...

  5. Go语言学习笔记十一: 切片(slice)

    Go语言学习笔记十一: 切片(slice) 切片这个概念我是从python语言中学到的,当时感觉这个东西真的比较好用.不像java语言写起来就比较繁琐.不过我觉得未来java语法也会支持的. 定义切片 ...

  6. Oracle学习笔记——点滴汇总

    Oracle学习笔记——点滴汇总 http://www.botangdb.com/ Oracle GI = Grid Infrastructure = ASM + Cluster

  7. Oracle学习笔记之四sp1,Oracle 11g的常用函数

    从Oracle学习笔记之四,SQL语言入门中摘出来的,独立成一章节 3.1 字符类函数 ASCII(c)和CHR(i)    分别用于返回一个字符的ASCII码和返回给定ASCII值所对应的字符. C ...

  8. Oracle学习笔记之四,SQL语言入门

    1. SQL语言概述 1.1 SQL语言特点 集合性,SQL可以的高层的数据结构上进行工作,工作时不是单条地处理记录,而对数据进行成组的处理. 统一性,操作任务主要包括:查询数据:插入.修改和删除数据 ...

  9. Oracle学习笔记—数据字典和常用命令(转载)

    转载自: oracle常用数据字典和SQL语句总结 Oracle常用命令大全(很有用,做笔记) 一.Oracle数据字典 数据字典是Oracle存放有关数据库信息的地方,其用途是用来描述数据的.比如一 ...

随机推荐

  1. FastAdmin 是如何利用 Git 管理插件代码的?

    FastAdmin 是如何利用 Git 管理插件代码的? 由于 FastAdmin 的插件很多,如果每一个插件用一个项目来管理,可以倒是可以,但是项目还多了. 但是如果使用文件夹在同一级的的方式又不方 ...

  2. Nginx 服务器伪静态配置不当造成 Access denied

    Nginx 服务器伪静态配置不当造成 Access denied 有群有反馈将 FastAdmin 布署到阿里云后无法打开后台. 出现如下提示,首页是可以打开,点登录链接后出现的.(下是群友的截图) ...

  3. haproxy 安装与配置

    一. Haproxy 介绍 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.根据官方数据,其最高极限支持10G的并发.HAP ...

  4. NOIP2013 Day2

    1.积木大赛 https://www.luogu.org/problemnew/show/1969 这道题在考试时暴力得比较麻烦,导致只得了80分,t了两个点. 思路为寻找一个区间内高度大于0的最低点 ...

  5. bzoj4466 超立方体

    Description 超立方体是立方体在高维空间内的拓展(其在 2 维情况下退化为正方形,1维情况下退化成线段).在理论计算机科学领域里,超立方体往往可以和 2 进制编码联系到一起.对理论计算机科学 ...

  6. 解决Maven出现Plugin execution not covered by lifecycle configuration 错误

    http://blog.163.com/xh_ding/blog/static/1939032892015222368827/ 解决Maven出现Plugin execution not covere ...

  7. jetty之嵌入式开发

    一.Jetty 是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境.Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布.开发人员可 ...

  8. Windows RDP远程连接CentOS 7

      1. 打开已经安装了CentOS7的主机,以root用户登录,在桌面上打开一个终端,输入命令:rpm -qa|grep epel,查询是否已经安装epel库(epel是社区强烈打造的免费开源发行软 ...

  9. sorl 6.6.0 定时更新索引

    solr 定时更新索引 – solr 6.6.0 – dataimport.scheduler 这里先重点说下,定时更新引用的org.apache.solr.handler.dataimport.sc ...

  10. 551. Student Attendance Record I + Student Attendance Record II

    ▶ 一个学生的考勤状况是一个字符串,其中各字符的含义是:A 缺勤,L 迟到,P 正常.如果一个学生考勤状况中 A 不超过一个,且没有连续两个 L(L 可以有多个,但是不能连续),则称该学生达标(原文表 ...