1.从客户表中提取绿园融泰,每个对私客户客户状态正常的数据
select *from S_CR_CISFMBBIF_H
where crtdpt in (SELECT ORG FROM S_CR_BISFMNOD_W WHERE SBNAME LIKE ‘%绿园融泰%’ )
and custyp=‘1’ and cussts=‘0’
select * from S_CR_ECIF_CISFMBBIF_H where BLNG_LGLPSN_ID='149002011’and custyp=‘1’ and cussts=‘0’
- 从子交易流水中提取2019年12月31日当天,所有机构交易金额最大的那笔交易信息(每个机构只取一条在同一个结果集)
select * form S_CR_PFSFTCJRN_A where JLTXDT=‘2019-12-31’
select * from S_CR_BISFMNOD_W
where ORG in
( SELECT COUNT (JLORGNO), MAX (JLAMT), JLTXDT=‘2019-12-31’ FROM S_CR_PFSFTCJRN_A
GROUP BY JLORGNO
HAVING COUNT(JLORGNO) >1 )
–select * form S_CR_PFSFTCJRN_A where JLTXDT=‘2019-12-31’
–and distinct JLORGNO and order by JLAMT
–查找重复记录
select count(num), max(name) from student
–列出重复的记录数,并列出他的name属性
group by num
having count(num) >1
–SELECT * FROM TABLE_NAME WHERE ROWID!=(SELECT MAX(ROWID) FROM TABLE_NAMe --WHERE TABLE_NAME.COL1=D.COL1 AND TABLE_NAME.COL2=D.COL2);
sql 里的 order by 和 group by 的区别:
order by 从英文里理解就是行的排序方式,默认的为升序。
order by 后面必须列出排序的字段名,可以是多个字段名。
group by 从英文里理解就是分组。必须有“聚合函数”来配合才能使用,使用时至少需要一个分组标志字段。
什么是“聚合函数”?像sum()、count()、avg()等都是“聚合函数” 使用group by 的目的就是要将数据分类汇总。
一般如:
select 单位名称,count(职工id),sum(职工工资) form [某表] group by 单位名称
–这样的运行结果就是以“单位名称”为分类标志统计各单位的职工人数和工资总额。
在sql命令格式使用的先后顺序上,group by 先于 order by。
order by 排序查询、asc升序、desc降序
示例:
select * from 学生表 order by 年龄
–查询学生表信息、按年龄的升序(默认、可缺省、从低到高)排列显示
也可以多条件排序、 比如 order by 年龄,成绩 desc 按年龄升序排列后、再按成绩降序排列
group by 分组查询、having 只能用于group by子句、作用于组内,having条件子句可以直接跟函数表达式。使用group by 子句的查询语句需要使用聚合函数。
示例:
select 学号,SUM(成绩) from 选课表 group by 学号
–按学号分组、查询每个学号的总成绩
select 学号,AVG(成绩) from 选课表 group by 学号 having AVG(成绩)>(select AVG(成绩) from 选课表 where 课程号=‘001’) order by AVG(成绩) desc
–查询平均成绩大于001课程平均成绩的学号、并按平均成绩的降序排列
数据库中复合索引的概念:
1、定义:
单一索引:单一索引是指索引列为一列的情况,即新建索引的语句只实施在一列上;
复合索引:复合索引也叫组合索引;
用户可以在多个列上建立索引,这种索引叫做复合索引(组合索引)。
复合索引在数据库操作期间所需的开销更小,可以代替多个单一索引;
同时有两个概念叫做窄索引和宽索引,窄索引是指索引列为1-2列的索引,宽索引也就是索引列超过2列的索引;
设计索引的一个重要原则就是能用窄索引不用宽索引,因为窄索引往往比组合索引更有效;
2、使用:
创建复合索引 :
CREATE INDEX columnId ON table1(col1,col2,col3) ;
查询语句:
select * from table1 where col1= A and col2= B and col3 = C
这时候查询优化器,不在扫描表了,而是直接的从索引中拿数据,因为索引中有这些数据,这叫覆盖式查询,这样的查询速度非常快;
3、注意事项:
(1)对于复合索引,在查询使用时,最好将条件顺序按找索引的顺序,这样效率最高;
select * from table1 where col1=A AND col2=B AND col3=D
如果使用
where col2=B AND col1=A
或者
where col2=B
将不会使用索引。
(2) 何时使用复合索引
根据where条件建索引是极其重要的一个原则; 注意不要过多用索引,否则对表更新的效率有很大的影响,因为在操作表的时候要化大量时间花在创建索引中
(3)复合索引会替代单一索引么
如果索引满足窄索引的情况下可以建立复合索引,这样可以节约空间和时间
4、备注:
对一张表来说,如果有一个复合索引 on (col1,col2),就没有必要同时建立一个单索引 on col1;
如果查询条件需要,可以在已有单索引 on col1的情况下,添加复合索引on (col1,col2),对于效率有一定的提高;
同时建立多字段(包含5、6个字段)的复合索引没有特别多的好处,相对而言,建立多个窄字段(仅包含一个,或顶多2个字段)的索引可以达到更好的效率和灵活性。
5、复合索引的使用注意事项:索引最左匹配原则
对于复合索引,在查询使用时,最好将条件顺序按找索引的顺序,这样效率最高,例如:
select * from table1 where col1=A AND col2=B AND col3=D。
如果使用 where col2=B AND col1=A 或者 where col2=B 将不会使用索引。
开窗函数的使用
首先针对开窗函数做一下简单介绍:
开窗函数
Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组只返回一行。
开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例:
over(order by
f_user_num) 按照f_user_num排序进行累计,order by是个默认的开窗函数
over(partition by
f_user_num)按照f_user_num分区
over(partition by
f_user_num order by
f_shop_card )按照f_user_num分区,并以f_shop_card进行排序
删除重复数据的原理:
1、将原始数据拷贝到一个备份表中。
2、使用开窗函数将数据以重复标识字段进行分区,以其他字段进行排序
3、取其中第1条,并将筛选后的数据放入新表中(该表即为处理之后的数据)
示例如下:
insert into t_1249_target_user
select f_stage_num,
f_user_num,
f_comm_busi,
f_4g_busi,
f_shop_card from (
select t.*,row_number()over(partition by f_user_num order by f_shop_card desc,f_comm_busi desc) rn from t_1249_target_user_his t)
where rn=1;
commit;
创建练习库
create table windowing_function_training(
id int,
studentId int,
language int,
math int,
english int,
classId string,
departmentId string
);
把数据插入到数据库
insert into table windowing_function_training values
(1,111,68,69,90,‘class1’,‘department1’),
(2,112,73,80,96,‘class1’,‘department1’),
(3,113,90,74,75,‘class1’,‘department1’),
(4,114,89,94,93,‘class1’,‘department1’),
(5,115,99,93,89,‘class1’,‘department1’),
(6,121,96,74,79,‘class2’,‘department1’),
(7,122,89,86,85,‘class2’,‘department1’),
(8,123,70,78,61,‘class2’,‘department1’),
(9,124,76,70,76,‘class2’,‘department1’),
(10,211,89,93,60,‘class1’,‘department2’),
(11,212,76,83,75,‘class1’,‘department2’),
(12,213,71,94,90,‘class1’,‘department2’),
(13,214,94,94,66,‘class1’,‘department2’),
(14,215,84,82,73,‘class1’,‘department2’),
(15,216,85,74,93,‘class1’,‘department2’),
(16,221,77,99,61,‘class2’,‘department2’),
(17,222,80,78,96,‘class2’,‘department2’),
(18,223,79,74,96,‘class2’,‘department2’),
(19,224,75,80,78,‘class2’,‘department2’),
(20,225,82,85,63,‘class2’,‘department2’);
查看联系数据库
SELECT * from autonavi_analysis_dev.windowing_function_training;
– count 开窗函数 (选择department1做为例子)
SELECT studentId
,math
,departmentId
,classId
,COUNT(math) OVER() AS count1 – 以符合条件的所有行作为窗口
,COUNT(math) OVER(PARTITION BY classId) AS count2
– 以按classId分组的所有行作为窗口
,COUNT(math) OVER(PARTITION BY classId ORDER BY math) AS count3-- 以按classId分组、按math排序的所有行作为窗口
,COUNT(math) OVER(PARTITION BY classId ORDER BY math ROWS
BETWEEN 1 PRECEDING AND 2 FOLLOWING) AS count4
– 以按classId分组、按math排序、按 当前行+往前1行+往后2行的行作为窗口
FROM windowing_function_training
WHERE departmentId = ‘department1’
一.oracle常见查询语句总结
select sum(字段) from 表名 where 条件 group by 字段
例子1.
select [distinct] | [as] [列别名],列名称 [as] [列别名]
from 表名称 [表别名]
[where 条件(s)]
[order by 排序的字段 | 列索引号 asc|desc,排序的字段2 asc|desc …]…;
执行顺序:
1、先执行from子句,确定要检索数据的来源
2、执行where子句,使用限定符对数据进行过滤
3、执行select子句,确定要检索出的数据列
4、执行order by子句排序
distinct:去除重复的列,当查询两条记录的所有的列都相同时才会去除重复
代码示例:
–查询emp表中的数据
SELECT * FROM emp;
–查询出公司员工编号,姓名,工作
select empno,ename,job from emp;
–起别名
select job as jobs from emp;
–去除重复的行记录
select distinct job as jobs from emp;
–查询出年工资,每天的工资
select empno,ename,sal12 Annual_salary,sal/30 day_salary
from emp;
2、select子句后面编写常量
1、字符串常量:使用"’"声明,如:“se”
2、数字常量:直接输出数字,如:4532
3、日期:
4、单引号:(’)
–增加货币单位的常量
select empno as 雇员编号,ename as 雇员姓名,(sal+200)*12+5000 as 年薪,‘¥’ 货币 from emp;
–连接符||的使用
select ‘编号:’ || empno||’ 的雇员姓名是:’||ename 雇员信息 from emp;
3、限定查询
3.1常用的限定查询运算符
NO 函数名称 描述
关系运算符 <,>=,<=,=,!=,<> 进行大小或相等的比较,不等于:!=和<>
判断null is null,is not null 判断某一列的内容是否为null
逻辑运算符 and,or,not and:与,or:或,not:非
范围查询 between最小值and最大值 在指定范围内查找,查找结果为:最小值<=内容<=最大值
列表范围查询 in 通过in可以指定一个范围的查询
模糊查询 like 对字段进行模糊匹配
3.2 限定查询的实例
-工资高于1200的所有与员工的信息
select * from emp where sal >1200;
–查询出所有业务员(CLEARK)雇员的信息
select * from emp where job=‘CLERK’
–查询出10部门中的激励或者20部门中业务员的信息
select * from emp
where (deptno=20 and job=‘CLEARK’) OR (deptno=10 and job=‘MANAGER’)
–查询出在1981年雇佣的全部雇员信息
select *
from emp
where hiredate between ‘01-1月-1981’ and ‘31-12月-1981’
–查询出佣金不为空的信息
select *
from emp
where comm is not null;
select *
from emp
where not comm is null;
–in的指定范围的查询
select *
from emp
where empno in(7369,7788,7566);
–现在查询除了7369,7788,7566之外的雇员的信息
select *
from emp
where empno not in(7369,7788,7566);
4、模糊查询like,not like
百分号(%):可匹配任意类型和长度(可以匹配0位,1位或多位长度)的字符
下划线(_):匹配单个任意字符,通常来限制表达式的字符长度
实例:
–查询出雇员姓名以S开头的所有雇员的信息
select *
from emp
where ename like ‘S%’
–查询出第二个字母是M的全部雇员信息
select *
from emp
where ename like ‘_M%’
– 查询出姓名中任意位置包含字母F的雇员信息
select *
from emp
where ename like ‘%F%’
–找出10部门中所有的经理(MANAGER),部门20中所有的业务员(CLEARK),既不是经理又不是业务员但薪金大于2000元的所有员工的详细资料并且要求这些雇员的西宁中包含字母S或字母K
select * from emp
where ((deptno=10 and job=‘MANAGER’)or (deptno=20 and job=‘CLERK’)
or (job not in (‘MANAGER’,‘CLEARK’)and sal >2000))
and(ename like ‘%S%’ or ename like ‘%K%’)
5、对结果进行排序
–排序的查询语句
select empno,ename,sal,job
from emp
order by 3 desc
–order by sal desc
–按照工资由高到低排序,工资相等的话按照雇佣日期由早到晚进行排序
select * from emp
order by sal desc,hiredate asc;
6.Alias(列的别名):紧跟列名,也可以在列名和别名之间加入关键字‘AS’,别名使用双引号“”,以便在别名中包含空格或特殊的字符并区分大小写。
||(关键字,连接符):把列与列,列与字符连接在一起,用 ‘||’表示,可以用来‘合成’列。
character(字符串):字符串可以是 SELECT 列表中的一个字符,数字,日期,日期和字符只能在单引号中出现,每当返回一行时,字符串被输出一次。
SELECT UserID||‘Character’||TableID AS “Alias” FROM TABLE
数据库练习
**子查询
–where
–查询子交易流水的平均数额,并降序排序
select JLORGNO,avg(JLAMT) from S_CR_PFSFTCJRN_A group by JLORGNO order by avg(JLAMT)desc
– 查询公司部门所有领导信息
select * from s_emp where id in (
select distinct manager_id from s_emp where manager_id is not null
)
–查询公司普通员工
select * from s_emp where id not in (
select distinct manager_id from s_emp where manager_id is not null
)
–having后面的子查询
–查询部门中平均工资大于32号部门平均工资的部门信息(显示部门编号和平均工资)
select avg(salary) from s_emp where dept_id=32
select dept_id部门编号,avg(salary)平均工资from s_emp group by dept_id
having avg(salary)>(
select avg(salary) from s_emp where dept_id=32
)
–from后面的子查询
–查询员工工资,条件是工资大于1400的所有员工中,5号员工是?
–select from s_emp where salary>1400
select from x where id=5
select* from (
select *from s_emp where salary>1400 where id=5
)
–小总结:三个关键字支持子查询 where… /having … /from …
多表查询*******
–内连接(inner jion)找到关系进行连接,查询多个表之间共同匹配的数据
查看员工编号,姓名及所在部门名称
–笛卡尔积:返回两张表中所有匹配的结果,没有意义,所以多表查询,必写关联条件
select s_emp.id 员工编号,first_name 姓名,name 部门名称 from s_emp,s_dept
where A表.x=B表.x
查询部门编号以及该部门负责的区域
select d.id,d.name 起名,r.name 起名 from s_dept d,s_region r
where d.region=r.id
select * from testa inner jion testb on testb.id=testa.id
等价于
select * from testa ,testb where testb.id=testa.id
----三表连接
需要两个连接条件
select 相连接那个列就写那几个列 from 表 s,表 q,表 r,
where s.xx=q.xx and q.xx=r.xx
------自链接:一张表,有多层业务含义
–谁是领导
–将s_emp表看做成两张相同的表,分别为员工表e,领导表m
select distinct m.id,m.frist_name,m.salary from s_emp e,s_emp m
where e.manager_id=m.id
–自链接用的不多,可以用子查询替代
select *from s_emp where id in(
select distinct manager_id from s_emp where manager_id is not null
)
–外连接:将主表中的数据全部查询,而从表中只会查匹配的,如果不存在就会用null替代
–(左外连接(left jion) 右连接(right jion))
–左外连接(left jion)
select * from testa left jion testb on testa.id=testb.id
–右连接(right jion)
select * from testa right jion testb on testa.id=testb.i
—分页查询
–员工表,共有25名员工,每页显示5名,计算第三页的员工狗是谁
select * from s_emp where id> 0 and id<=5
–以上的分页写法不可取,因为id列不连续,结果就不靠谱了
–只要id能连续上,套用上方法,就完成分页
–可以使用oracle中的伪列的概念,来满足表中在其一个排序的列
select rownum from E_emp
select from(
select X.,rownum from(
select * from E_emp
)X
)
where id>0 and id<=5
–******************事务
–1给2汇款50元(一起执行多条语句,每句之间用;隔开,并且按F5执行)
update bank set money=money-50 where id=1;
update bank set money=money+50 where id=2;–错误语句
–事务是作为单个逻辑工作单元执行的一系列操作
–多个操作作为一个整体向系统提交,要么执行,要么不执行–事物的概念
–事务是一个不可分割的工作逻辑单元
----使用事务解决转账问题
begin
update bank set money=money-50 where id=1;
update bank set money=money+50 where id=2;
commit; --一起生
exception
when others then
rollback; --一起死
end;
–事务的特性(ACID)
–原子性
–一致性
–隔离性
–永久性
—索引***********************索引**********************
-创建索引,创建完成以后,索引如何应用?Oracle会自动使用索引
Create index ix_表名 on 表(想要定义的字段)
–删除索引
Drop index ix_emp
–*********序列
–序列:数据库中的自增(i++)
–创建一个自增的变量、
当前值:XXX.currval
先增长再返回:nextval
–创建一个自增的变量、
Create sequence x
Insert into 表 values(x.nextval,100)
–查看当时的值
select x.currval from dual
–创建一个序列(从100开始,每次递增5)
Create sequence y
Start with 100 --从哪里开始计数
Increment by 5 --每次增加几个
Nomaxvalue --不设置最大值
–删除序列
drop seguence y
设计数据库******
数据的规范化
数据库的三范式:
第一范式 1 st NF:如果每列都是确保每列的原子性
如果每列都是不可分割的最小数据单元(也成为最小原子单元)
第二范式 2 nd NF:要求每一张表只描述一件事
第三范式 3 nd NF:如果一张表满足第二范式,并且除了主键以外的其他列都不依赖于主键列,则满足第三范式(3 nd NF) (列要和主键有直接的关系,不能有间接的关系)
plsql****
过程化SQL语言编程
declare—声明区
begin – 执行区域
exception –异常
end –结束
DECLARE
BEGIN
DBMS_OUTPUT.PUT_LINE(‘HELLO’);
END;
在数据库中+表示运算,不能用做连接
赋值符号 ‘:=’
连接符号用‘||’
+++++++++++++++++++++++++++++++++++++++++++++PL/SQL+++++++++++++++++++++++++++++++++++
在Java中
Final数据类型 变量名=初始化值;
Pl/sql中
变量名 constant (数据类型长度):=初始化值
declare
name varcher2(10);=’数据库’;
i constant number:=18;
begin
i:=20; --i不能用作被赋值的目标,因为i被常量化
dbms_output.put_line(‘我们学习,’||i);
end;
数据类型 :标量类型:数字,字符,布尔型,日期时间
Lob类型(大数据方向需要学习):BFILE,BLOB,CLOB,NCLOB
属性类型:%type,%rowtype
%type
- 引用表格字段类型
- 不需要思考,只需要知道和表中的某列一致就好
变量名 表名,字段名%type:=初始值;
declare
name varcher2(10);=’数据库’;
i constant number:=18;
money s_emp.salary%type:=1000;
begin
–i:=20; --i不能用作被赋值的目标,因为i被常量化
dbms_output.put_line(‘我们学习,’||i);
end;
recode类型 - 类似于Java中的类,吧多个不同的数据类型封装为一个自定义的类型、
- 在声明区中定义
declare --recode 声明一个类
type student is recode(
sid s_emp.id%type
sname s_emp.last_name%type
);
stu student; --类的对象
begin
stu.sid:=110; --赋值
stu.sname:=’张三’;
dbms_output.put_line(‘学号是:’||stu.sid||’,名字:’||stu.name); --引用
end;
Table类型
相当于Java学习中的map集合,是一个键值对的容器,存储的是双值
Type 类型名称 is table of 值类型index by 键类型
declare --相当于mytab< binary_integer , number >
type mytab is table of number index by binary_integer
mt mytab;
begin
mt(0):=10001; --相当于Java中的mt.put(0,10001)
mt(1):=10002;
mt(2):=10003; --赋值
dbms_output.put_line(mt(1)); --引用
dbms_output.put_line(mt.first()); --获得第一项
dbms_output.put_line(mt.last()); --获得最后一项
x:=mt.first();
dbms_output.put_line(mt.next()); --获得当前值的下一个key
end;
变量的作用域
If语句的分支结构
declare
i number :=10;
begin
if i>5 then
dbms_output.put_line(‘ok’);
end if;
end;
if else 语句分支结构
declare
i number :=10;
begin
if i>5 then
dbms_output.put_line(‘ok’);
else
dbms_output.put_line(‘no’);
end if;
end;
多分支
–考试成绩,如果大于90分,则吃鸡
–考试成绩,如果大于60分,则吃鸡屁股
–考试成绩,如果大于90分,则吃鸡骨头
declare
score number :=10;
begin
if score >90 then
dbms_output.put_line(‘吃鸡’);
elsif score >60 then
dbms_output.put_line(‘吃鸡屁股’);
else
dbms_output.put_line(‘吃鸡骨头’);
end if;
end;
null
在pl/sql中运算,null参与比较运算,不会出现结果
如果使用null参与if运算,永远进不去任何if段,必进else
Loop循环
declare
i number:=1;
begin
loop
dbms_output.put_line(‘i’);
exit when i=10; --当i=10的时候,退出循环
i:=i+1;–每次递增
end loop;
end;
普通循环 while
declare
i number:=1;
begin
while i<=10 loop
dbms_output.put_line(‘i’);
i:=i+1;–每次递增
end loop;
end;
案例
Declare
begin
while i<=100 loop
if mod(i,2)=0 then –-如果是偶数,相当于Java中的 i%2==0
dbms_output.put_line(‘i’);
end if
i:=i+1;–每次递增
end loop;
end;
智能循环
For循环
智能指的是,循环变量自动变化,循环变量只能读取,不可修改
案例:1-10
–for 循环控制的变量只能增加,不能减少
begin
For i in 1…10 loop
dbms_output.put_line(‘i’); --只是增加
– dbms_output.put_line(’11-i’); --反循环
end loop;
end ;
–反转循环
begin
For i in reverse 1…10 loop
dbms_output.put_line(‘i’); --只是增加
end loop;
end ;
案例:
当科目有低于50分的,则+10分,直到没有50分以下的同学为止
–思路解析,查看50分以下的人有几个,假设三人
对这3人+10
再次查看有几人+10
直到没有50分以下的人,停止
Declare
I number:=0;–50分以下的人
Begin
Select count()into i from result where subjectid=3 and studentresult<50;
dbms_output.put_line(‘i’);
While i>0 loop
update result set studentresult = studentresult+10 where subjectid=3 and studentresult<50;
Select count()into i from result where subjectid = 3 and studentresult<50;
End loop;
End ;
多重循环
declare
X number:=1;
Y number:=1;
begin
<>
While x<=10 loop
dbms_output.put_line(‘----’||x);
y:=1
while y<=5 loop
dbms_output.put_line(y);
if x=7 and y=3 then
exit wai;
end if;
y:=y+1;
end loop;
x:=x+1;
end loop;
end;
goto ,
不可以用goto直接跳转到结尾
–使用goto 来模拟循环,输出1-10数字
declare
I number:=1;
begin
<>
dbms_output.put_line(i);
i:=i+1;
if i<=10 then
goto a;
end if;
end;
高级特性
游标+异常+存储过程+函数+触发器
–数据库中没有数组和集合的概念,如何存储结果集,所以数据库中出现了游标的概念
什么是游标?
游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果,每一个游标区都有一个名字,用户可以通过游标逐一获取记录
- 声明游标,并且绑定一个select语句 在声明区中定义:cursor游标变量名称 is查询语句
- 打开游标 在执行区操作:open游标变量
- 提取游标,控制游标向下移动,提取一行数据 fetch游标变量into record类型变量
- 关闭游标,释放资源 close游标变量
例子:
declare
–1.声明游标 int[] arr={’a’,’b’,’c’,’d’}
cursor youbiao is select id ,first_name,salary from s_emp;
–为定义好的游标类型,声明出对象,用来接收由表中每一个对象
yb youbiao%rowtype
begin
Open youbiao ; --2.打开游标
–循环取出三条数据
for i in 1…3 loop
–3.随着每次循环,控制游标向下移动,并取出行内数据
fetch youbiao into yb;
dbms_output.put_line(yb.id||’-’yb.first_name ||‘-’||yb.slary);
end loop;
–4.关闭游标,释放资源
close youbiao;
end;
%found或%notfound在使用时限制
游标必须是打开的
并且在调用此属性时,游标必须是经过下移的!否则获取结果为null
exit when biao%notfound; --游标中没有数据了,退出
智能循环for,使用游标 - 游标自定义
- 游标自己打开
- 油表自己下移
- 游标自己关
declare
cursor biao is select *from student where sex=’女’;
begin
for stu in biao loop
dbms_output.put_line(’姓名:’||stu.studentname||’,电话’||stu.phone||’,生日’||stu.borndate);
end loop;
end;
回顾异常
在运行程序时出现错误叫做异常
发生异常后,语句将停止运行,控制权转移道程序的异常处理部分
Begin
…
Exception –当begin中出现运行时异常后,exception快自动执行
declare
lname s_emp.last_name%type;
begin
select last_name into lname from s_emp where id=120;
dbms_output.put_line(’姓名:’||lname);
dbms_output.put_line(10/0);
exception
when NO_DATA_FOUND then
dbms_output.put_line(’出错了,没有这个人!’);
when ZERO_DIVIDE then
dbms_output.put_line(’除数不能是零’);
when others then
dbms_output.put_line(’请联系管理员’);
end;
存储过程