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是一种关系型数据库, 用来访问关系型数据库的语言是 “结构 ...
随机推荐
- 原生js上传文件,使用new FormData()
当创建一个内容较多的表单,表单里面又有了文件上传,文件上传也需要表单提交,单一的上传文件很好操作: <form action="接口" enctype="multi ...
- SQLServer 的数据分页:
假设现在有这样的一张表:CREATE TABLE test( id int primary key not null identity, names varchar(20))然后向里面插入大约1000 ...
- Linux下设置动态库的方法
库文件在连接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的. 一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使 ...
- C#中的 new Random()
在C#中,产生随机数常用大方法是 new Random().Next(1,10)等方法. 但是仔细发现会有个问题: 看代码: ; i < ;i++ ) { Console.WriteLine(, ...
- 启用Flash Player 11.3的全屏键盘输入注意事项
启用Flash Player 11.3的全屏键盘输入,注意以下事项: 1. HTML代码<param name=”allowFullScreenInteractive” value=”true” ...
- ubuntu16.04 64bit 升级到 python3.6
https://blog.csdn.net/zhao__zhen/article/details/81584933 https://www.codetd.com/article/1967538 htt ...
- java 集成友盟推送
原文:https://blog.csdn.net/Athena072213/article/details/83414743 最近应公司业务需求需要完善友盟推送,认真看了官方文档后其实很简单,只需要细 ...
- Centos新增group和user
新增group groupadd hadoop 新增用户 useradd -d /usr/hadoop -g hadoop -m hadoop 设置密码 passwd hadoop
- Java 读取Excel 文件内容
在一个项目中,有一个需求,是把excel文件的内容转换为xml格式展示.在学习如何操作的过程中,首先是如何获取excel文件,其中操作的代码如下: 1.首先是导入需要的 jar, 下载地址:https ...
- java多线程与并发笔记
0.多线程,主要用来提高程序效率,处理耗时的操作. 多个线程写在同一个类里调用,并不是说写在前面的线程就会先运行.各个线程会进行争抢,能抢到系统资源的才会先运行. 因此,同一个程序,多个线程运行,可能 ...