Oracle_PL/SQL(2) 过程控制
0.检索单行数据
0.1使用标量变量接受数据
例1: 7788
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
select ename,sal into v_ename,v_sal from emp where empno=&no;
dbms_output.put_line('职员号:'||&no||' 职员名:'||v_ename);
end;
0.2嵌入SELECT语句注意事项:
使用SELECT INTO语句时,必须要返回一条数据,并且只能返回一条数据
no_date_found:
select into没有返回数据
too_many_rows:
select into返回多条数据
例2:
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
select ename,sal into v_ename,v_sal from emp where deptno=&deptno;
dbms_output.put_line('部门编号:'||&deptno||' 职员名:'||v_ename);
end;
where子句使用注意事项:
使用的变量名不能与列名相同,否则触发TOO_MANY_ROWS例外.
例3:
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
empno emp.empno%type;
begin
empno:=&no;
select ename,sal into v_ename,v_sal from emp where empno=empno;
dbms_output.put_line('职员编号:'||&no||' 职员名:'||v_ename);
end;
PL/SQL控制结构
1.按顺序执行语句
declare
v_sal number;
v_avg number;
begin
select avg(sal) into v_avg from emp;
dbms_output.put_line('平均工资:'||v_avg);
select sal into v_sal from emp where empno=7788;
dbms_output.put_line('职员号7788人员的工资:'||v_sal);
end;
2.条件分支语句
2.1简单条件判断
语法1:
if 逻辑表达式1 then
语句1;
end if;
例1:
declare
v_sal number;
v_avg number;
begin
select avg(sal) into v_avg from emp;
select sal into v_sal from emp where empno=7788;
if v_sal>v_avg then
dbms_output.put_line('职员号7788人员的工资'||v_sal||'大于平均工资'||v_avg);
end if;
end;
例2:接收参数
declare
v_sal number(6,2);
begin
select sal into v_sal from emp where lower(ename)=lower('&name');
dbms_output.put_line('输入的员工姓名是:'||'&name');
if v_sal<2000 then
update emp set sal=v_sal+200 where lower(ename)=lower('&name');
dbms_output.put_line('给员工:'||'&name'||'工资增加了200.');
end if;
end;
2.2二重条件分支
语法2:
if 逻辑表达式1 then
语句1;
else
语句2;
end if;
例1:
declare
v_sal number;
v_avg number;
begin
select avg(sal) into v_avg from emp;
select sal into v_sal from emp where empno=7788;
if v_sal>v_avg then
dbms_output.put_line('职员号7788人员的工资'||v_sal
||'大于平均工资'||v_avg);
else
dbms_output.put_line('职员号7788人员的工资'||v_sal
||'小于等于平均工资'||v_avg);
end if;
end;
例2:接收参数 7788
declare
v_comm number(6,2);
begin
select comm into v_comm from emp where empno=&no;
dbms_output.put_line('输入的员工编号是:'||'&no');
if v_comm is null then
update emp set comm=200 where empno=&no;
dbms_output.put_line('给员工编号是:'||'&no'||'的发200奖金.');
else
update emp set comm=comm+100 where empno=&no;
dbms_output.put_line('给员工编号是:'||'&no'||'奖金增加了100.');
end if;
end;
2.3多重条件分支
语法3:
if 逻辑表达式1 then
语句1;
elsif 逻辑表达式2 then
语句2
...
else
语句3;
end if;
例1:
declare
v_sal number;
v_avg number;
begin
select avg(sal) into v_avg from emp;
select sal into v_sal from emp where empno=7788;
if v_sal>v_avg then
dbms_output.put_line('职员号7788人员的工资'||v_sal
||'大于平均工资'||v_avg);
elsif v_sal<v_avg then
dbms_output.put_line('职员号7788人员的工资'||v_sal
||'小于平均工资'||v_avg);
else
dbms_output.put_line('职员号7788人员的工资'||v_sal
||'等于平均工资'||v_avg);
end if;
end;
例2:接收参数 7788
declare
v_empno number;
v_job emp.job%type;
begin
v_empno:=&no;
select lower(job) into v_job from emp where empno=v_empno;
dbms_output.put_line('输入的员工编号是:'||'&no');
if v_job='manager' then
update emp set comm=nvl(comm,0)+200 where empno=v_empno;
dbms_output.put_line('按照员工的职位'||v_job||'给员工编号是:'
||v_empno||'奖金增加了200.');
elsif v_job='analyst' then
update emp set comm=nvl(comm,0)+100 where empno=v_empno;
dbms_output.put_line('按照员工的职位'||v_job||'给员工编号是:'
||v_empno||'奖金增加了100.');
else
update emp set comm=nvl(comm,0)+50 where empno=v_empno;
dbms_output.put_line('按照员工的职位'||v_job||'给员工编号是:'
||v_empno||'奖金增加了50.');
end if;
end;
2.4 CASE语句:
在CASE语句中使用单一选择符进行等值比较
语法1:
case 表达式
when 表达式1 then 语句1; --表达式与表达式1相等时执行语句1
when 表达式2 then 语句2; --同上
...
else
默认语句; --表达式与上述各表达式都不相等时执行默认语句
end case;
例1:
declare
v_deptno emp.deptno%type;
begin
v_deptno:=&no;
dbms_output.put_line('输入的部门编号是:'||v_deptno);
case v_deptno
when 10 then
update emp set comm=100 where deptno=v_deptno;
dbms_output.put_line('给部门编号'||v_deptno||'的职员是发100元奖金');
when 20 then
update emp set comm=80 where deptno=v_deptno;
dbms_output.put_line('给部门编号'||v_deptno||'的职员是发80元奖金');
when 30 then
update emp set comm=50 where deptno=v_deptno;
dbms_output.put_line('给部门编号'||v_deptno||'的职员是发50元奖金');
else
dbms_output.put_line('部门编号不存在');
end case;
end;
2.5 在CASE语句中使用多种条件比较
语法2:
case
when 逻辑表达式1 then 语句1; --逻辑表达式1为真时执行语句1
when 逻辑表达式2 then 语句2; --同上
...
else
默认语句; --上述各逻辑表达式都不为真时执行默认语句
end case;
例2:
declare
v_empno emp.empno%type;
v_sal emp.sal%type;
begin
v_empno:=&no;
dbms_output.put_line('输入的职员编号是:'||v_empno);
select sal into v_sal from emp where empno=v_empno;
case
when v_sal<1000 then
update emp set comm=100 where empno=v_empno;
dbms_output.put_line('给工资'||v_sal||'小于1000的职员发100元奖金');
when v_sal<2000 then
update emp set comm=80 where empno=v_empno;
dbms_output.put_line('给工资'||v_sal||'小于2000的职员发80元奖金');
when v_sal<3000 then
update emp set comm=50 where empno=v_empno;
dbms_output.put_line('给工资'||v_sal||'小于3000的职员发50元奖金');
else
dbms_output.put_line('给工资大于等于3000的职员不发奖金');
end case;
end;
3.循环语句
分类:loop循环,while循环,for循环
create table temp_table (
num_col number(8),
char_col varchar2(200)
);
3.1 loop循环
语法:
loop
语句;
end loop;
loop循环没有退出条件,语句被无限次地执行。
一定要包含EXIT语句,定义循环控制变量,并在循环体内改变循环控制变量的值。
循环退出exit
exit when 条件;
if 条件 then
exit;
end if;
declare
v_counter number:=1;
begin
loop
insert into temp_table values (v_counter,'loop循环');
v_counter:=v_counter+1;
if v_counter>=10 then
exit;
end if;
--exit when v_counter>50;
end loop;
end;
3.2 while循环
语法:
while 条件 loop
语句;
end loop;
每次循环前对条件进行判断,条件为真则语句被执行;否则循环终止。
declare
v_counter number:=1;
begin
while v_counter<=50 loop
insert into temp_table values (v_counter,'while循环');
v_counter:=v_counter+1;
end loop;
end;
while中仍可以使用exit退出循环。
declare
v_counter number:=1;
begin
while v_counter<=50 loop
insert into temp_table values (v_counter,'while循环exit');
v_counter:=v_counter+1;
exit when v_counter>20;
end loop;
end;
3.3 数字式FOR循环
使用FOR循环时,ORACLE会隐含定义循环控制变量.
语法:
for counter in[reverse] lower_bound..upper_bound loop
statement1;
statement2;
.......
end loop;
counter是循环控制变量,并且该变量由ORACLE隐含定义,不需要显示定义;
lower_bound和upper_bound分别对应循环控制变量的上下界值.
默认情况下,FOR循环,每次会自动增一,指定REVERSE选项时,每次循环控制变量会减一
例1:
begin
for v_counter in 1..10 loop
insert into temp_table values (v_counter,'for循环');
end loop;
end;
例2:reverse 从大向小循环
begin
for v_counter in reverse 1..10 loop
insert into temp_table values (v_counter,'for循环reverse');
end loop;
end;
3.4 隐式游标for循环
begin
for rs in (select * from emp) loop
insert into temp_table values (rs.empno,rs.ename);
end loop;
end;
begin
for rs in (select * from emp where deptno=10 ) loop
if rs.deptno=10 then
update emp set sal=sal*1.1 where empno=rs.empno;
end if;
end loop;
end;
3.5 嵌套循环
例1:2层for循环
declare
result number;
begin
for i in 1..10 loop
for j in 1..10 loop
result:=i*j;
dbms_output.put_line(i||' * '||j||' = '||result);
end loop;
end loop;
end;
例2:乘法口诀表
declare
n_result number;
v_result varchar2(2);
begin
for i in 1..9 loop
for j in 1..i loop
n_result:=j*i;
if n_result<10 and j<>1 then
v_result:=n_result||' ';
else
v_result:=n_result;
end if;
dbms_output.put(j||'*'||i||'='||v_result||' ');
end loop;
dbms_output.put_line('');
end loop;
end;
4.退出循环
4.1 continue 退出本次循环(10G以上版本)
begin
for v_counter in 1..50 loop
if v_counter>20 and v_counter<=30 then
continue;
else
insert into temp_table values (v_counter,'for循环continue');
end if;
end loop;
end;
4.2 exit 退出本层循环
begin
for v_counter in 1..50 loop
if v_counter>10 then
exit;
else
insert into temp_table values (v_counter,'for循环exit');
end if;
end loop;
end;
嵌套循环和标号:通过在嵌套循环中使用标号,可以区分内层循环和外层循环,
并且可以在内层循环中直接退出外层循环
例3:
declare
n_result number;
begin
<<outer>>
for i in 1..10 loop
<<inter>>
for j in 1..10 loop
n_result:=i*j;
dbms_output.put_line('内层循环内输出:'||n_result);
-- exit inter when j=8;
-- exit outer when n_result=30;
end loop inter;
dbms_output.put_line('内、外层循环间输出:'||n_result);
end loop outer;
dbms_output.put_line('外层循环外输出:'||n_result);
end;
4.3 goto 用于跳转到特定标号处去执行语句.
declare
i int :=1;
begin
loop
insert into temp_table values(i,'loop循环+goto');
if i=10 then
goto end_loop;
end if;
i:=i+1;
end loop;
<<end_loop>>
dbms_output.put_line('循环结束');
end;
5.操纵数据
5.1使用VALUES子句插入数据
declare
v_deptno dept.deptno%type;
v_dname dept.dname%type;
begin
v_deptno:=&no;
v_dname:='&name';
insert into dept (deptno,dname) values(v_deptno,v_dname);
end;
5.2使用子查询插入数据
--复制表结构,不带数据
create table employee as select * from emp where 1=2;
--
declare
v_deptno emp.deptno%type:=&no;
begin
insert into employee select * from emp where deptno=v_deptno;
end;
5.3更新数据
使用表达式更新列值
declare
v_deptno dept.deptno%type:=&no;
v_loc dept.loc%type:='&loc';
begin
update dept set loc=v_loc where deptno=v_deptno;
end;
5.4使用子查询更新列值 MILLER
declare
v_ename emp.ename%type:='&name';
begin
update employee set (sal,comm) =
(select sal,comm from emp where ename=v_ename)
where job = (select job from emp where ename=v_ename)
end;
5.5删除数据
使用变量删除数据
declare
v_deptno dept.deptno%type:=&no;
begin
delete from dept where deptno=v_deptno;
end;
5.6使用子查询删除数据
declare
v_ename emp.ename%type:='&name';
begin
delete from employee where deptno=
(select deptno from emp where ename=v_ename);
end;
6.事务控制语句
事务控制语句包括commit,rollback以及savepoint等三种语句
例1:
declare
v_sal emp.sal%type:=&salary;
v_ename emp.ename%type:='&name';
begin
update emp set sal=v_sal where lower(ename)=v_ename;
select sal into v_sal from emp where ename=v_ename;
dbms_output.put_line(v_sal);
commit;
exception
when others then
--dbms_output.put_line('发生了运行时异常');
--raise_application_error(-20001,'发生了运行时异常');
rollback;
end;
例2:
declare
begin
insert into temp_table values(1,'事务控制语句');
savepoint a1;
insert into temp_table values(2,'事务控制语句');
savepoint a2;
insert into temp_table values(3,'事务控制语句');
savepoint a3;
rollback to a2;
commit;
end;
Oracle_PL/SQL(2) 过程控制的更多相关文章
- Oracle_PL/SQL(10) 定时器job
定时器job1.定义 定时器指在特定的时间执行特定的操作. 可以多次执行.说明:特定的操作:指一个完成特定功能的存储过程.多次执行:指可以每分钟.每小时.每天.每周.每月.每季度.每年等周期性的运行. ...
- Oracle_PL/SQL(9) 例外处理
例外处理1.例外分类:预定义例外,非预定义例外,自定义例外三种传递例外:如果在例外处理部分exception没有捕捉例外,oracle会将例外传递到调用环境.捕捉并处理例外:使用例外处理部分完成exc ...
- Oracle_PL/SQL(8) 动态sql
动态sql0.pl/sql块的限制 不能执行ddl操作(create.drop.alter): 不能执行部分dcl操作(grant.revoke). 1.语法动态sql:在执行时才能确定要执行的sql ...
- Oracle_PL/SQL(7) 集合
pl/sql集合处理单行单列数据,可以使用标量变量:处理单行多列的数据,可以使用pl/sql记录(%rowtype,record):处理单列多行数据,可以使用pl/sql集合. pl/sql集合类型是 ...
- Oracle_PL/SQL(6) 触发器(序列、视图)
序列1.创建序列create sequence seq_alog start with 1 increment by 1 maxvalue 999999999999999999999999999 mi ...
- Oracle_PL/SQL(5) 包
包1.定义:包用于逻辑组合相关的PL/SQL类型,项和子程序,由包规范和包体组成 建立包规范:包规范是包与应用程序之间的接口,用于定义包的公用组件, 包括常量,变量,游标,过程,函数等 建立包体:用于 ...
- Oracle_PL/SQL(4) 过程和函数
create table s_sc ( SNAME VARCHAR2(20) primary key, c_grade NUMBER(6), m_grade NUMBER(6), e_grade NU ...
- Oracle_PL/SQL(3) 游标
引言:PLSQL数据类型标量数据类型:数字类.字符类.日期类.布尔类(boolean).复合数据类型:记录(%rowtype).表.数组引用类型:REF CURSORLOB类型:BLOB.CLOB 1 ...
- Oracle_PL/SQL(1) 匿名块
1. PL/SQL 简介PL/SQL是一种比较复杂的程序设计语言, 用于从各种环境中访问Oracle数据库.为什么使用PL/SQL?Orade是一种关系型数据库, 用来访问关系型数据库的语言是 “结构 ...
随机推荐
- 24 week 4 安装 docker
安装docker 出现问题 解决办法https://blog.csdn.net/VOlsenBerg/article/details/70140211 发现链接超时,然后就https://blog.c ...
- Django使用自定义的authentication登录认证
import ldap class LDAPMgmt(): def __init__(self): self.ldap_host = 'xxx' self.ldap_base_dn = 'ou=xx, ...
- 无法加载ISAPI 筛选器 当前配置只支持加载为 AMD64 处理器体系结构创建的映像
无法加载ISAPI 筛选器 当前配置只支持加载为 AMD64 处理器体系结构创建的映像 2011-11-9 0:18:49来源:本站原创作者:清晨320我要评论(0) 今天服务器的伪静态死活加载不上去 ...
- CSS 边框图像
border-image border-image 可以将图像应用到盒子的边框上. border-image 属性需要3个值同时存在: URL 图片的地址 切割图片的位,4个边需要写4个值 如何处理边 ...
- SSM商城项目(三)
1. 学习计划 1.商品类目选择 2.图片上传 a) 图片服务器FastDFS b) 图片上传功能实现 3.富文本编辑器的使用KindEditor 2. 商品类目选择 2.1. 原型 2.2. 功能分 ...
- vue.js入门操作
1.vue框架是经典的MVVM模式, .vue文件是模板文件模板文件又分为3个部分一 <template></template>(html部分)二 <script> ...
- Rx操作符
[Rx操作符] 1.Observable.from()方法,它接收一个集合作为输入,然后每次输出一个元素给subscriber: Observable.from("url1", & ...
- jvisual中添加jstatd远程监控
visualVM远程监控: jvisual中需要增加插件安装. 在执行Java 应用程序的服务器上先生成一个jstatd.all.policy grant codebase "file:${ ...
- Java基础学习笔记(三)
18.2.1无参无返回值的方法 18.2.1.1定义方法的语法格式 public static void 方法名称(){ 方法体 } 方法调用 类名.方法名称(); 注意:在Java中,同一个类中的方 ...
- oracle 一致读原理
在Oracle数据库中,undo主要有三大作用:提供一致性读(Consistent Read).回滚事务(Rollback Transaction)以及实例恢复(Instance Recovery). ...