PL/SQL 知识 (个人笔记)(三)
个人笔记
接上篇
PL/SQL 知识 (个人笔记)(一)
PL/SQL 知识 (个人笔记)(二)
**
11.循环 loop,while,for
--loop循环:
delcare
--定义循环变量,循环变量会跟着循环每次改变
begin
loop
要执行的动作;
循环变量自加;
循环退出控制;
end loop;
end;
范例:
declare
i number(3) := 0;
begin
loop
dbms_output.put_line(i);
i := i + 1;
exit when i = 10;
end loop;
end;
执行以下三段代码,理解循环:
declare
i number(3) := 0;
begin
loop
i := i + 1;
dbms_output.put_line(i);
exit when i = 10;
end loop;
end;
declare
i number(3) := 0;
begin
loop
dbms_output.put_line(i);
exit when i = 10;
i := i + 1;
end loop;
end;
declare
i number(3) := 0;
begin
loop
dbms_output.put_line(i);
i := i + 1;
exit when i = 10;
end loop;
end;
--while循环:
declare
--定义循环变量
begin
while 判断循环退出 loop
执行动作;
循环变量自加;
end loop;
end;
范例:
declare
i number(3) := 0;
begin
while i < 10 loop
dbms_output.put_line(i);
i := i + 1;
end loop;
end;
for循环:
(1).人为设置循环
语法:
declare
begin
for i in 循环范围 loop
循环体
end loop;
end;
范例:
declare
begin
for i in 1..9 loop
dbms_output.put_line(i);
end loop;
end;
注意:
1.i不需要人为定义;
2.i的范围就是1-9,每次自增1;
(2).自主遍历
语法:
declare
begin
for 循环变量名 in(查询或者范围) loop
循环体;
end loop;
end;
范例:
declare
begin
for v in (select * from dept) loop
dbms_output.put_line('DEPTNO:' || v.deptno || ', DNAME:' || v.dname ||', LOC:' || v.loc);
end loop;
end;
declare
V_sal emp_0213.sal%type;
begin
for a in (select * from emp_0213) loop
if a.sal <= 1000 then V_sal := a.sal + 500;
elsif a.sal > 1000 and a.sal <= 1500 then V_sal := a.sal + 550;
elsif a.sal > 1500 and a.sal < 3000 then V_sal := a.sal + 600;
else
V_sal := a.sal * 1.2;
end if;
update emp_0213 set sal = V_sal where empno = a.empno and sal=a.sal;
end loop;
commit;
end;
declare
begin
for v in (select * from emp) loop
dbms_output.put_line(rpad(v.empno, 4, ' ') || ',' ||
nvl(rpad(v.ename, 10, ' '), ' ') || ',' ||
nvl(rpad(v.job, 9, ' '), ' ') || ',' ||
nvl(rpad(v.mgr,4,' '),' ') || ',' ||
to_char(v.hiredate, 'YYYYMMDD') || ',' ||
nvl(rpad(v.sal, 7, ' '), ' ') || ',' ||
nvl(rpad(v.comm, 7, ' '), ' ') || ',' ||
nvl(rpad(v.deptno, 2, ' '), ' '));
end loop;
end;
注意:
(1). 循环变量v不需要额外定义,直接沿用in中查询或者范围的类型;
(2). 打印时,打印方式是 循环变量名.列名 列名即后面查询语句中的列或者表中的列;
练习:
(1).键盘输入一个年份,判断是否是闰年;(能被4整除而不能被100整除或者能被100和400同时整除,满足其一即可);
declare
v_year number(4) := &请输入一个年份;
begin
if mod(v_year, 4) = 0 and mod(v_year, 100) <> 0 then
dbms_output.put_line(v_year || '年是闰年');
elsif mod(v_year, 100) = 0 and mod(v_year, 400) = 0 then
dbms_output.put_line(v_year || '年是闰年');
else
dbms_output.put_line(v_year || '年不是闰年');
end if;
end;
declare
v_year number(4) := &请输入一个年份;
begin
if (mod(v_year, 4) = 0 and mod(v_year, 100) <> 0) or
(mod(v_year, 100) = 0 and mod(v_year, 400) = 0) then
dbms_output.put_line(v_year || '年是闰年');
else
dbms_output.put_line(v_year || '年不是闰年');
end if;
end;
(2).键盘输入一个deptno,将全部门的人的信息打印出来;
declare
v_deptno number(2) := &请输入一个部门编号;
begin
for v in (select * from emp where deptno = v_deptno) loop
dbms_output.put_line('empno:' || v.empno || ', ename:' || v.ename ||
', job:' || v.job || ', mgr:' || v.mgr ||
', hiredate:' || to_char(v.hiredate, 'YYYYMMDD') ||
', sal:' || v.sal || ', comm:' || v.comm ||
', deptno:' || v.deptno);
end loop;
end;
(3).键盘输入一个empno,将同部门的人的信息全部打印;
declare
v_empno number(4) := &请输入一个员工编号;
begin
for v in (select * from emp where deptno =(select deptno from emp where empno=v_empno)) loop
dbms_output.put_line('empno:' || v.empno || ', ename:' || v.ename ||
', job:' || v.job || ', mgr:' || v.mgr ||
', hiredate:' || to_char(v.hiredate, 'YYYYMMDD') ||
', sal:' || v.sal || ', comm:' || v.comm ||
', deptno:' || v.deptno);
end loop;
end;
(4).键盘介入三个值,并按照从大到小依次打印;
declare
v1 number(38,5) :=&第一个数;
v2 number(38,5) :=&第二个数;
v3 number(38,5) :=&第三个数;
begin
if v1>=v2 and v2>=v3 then
dbms_output.put_line(v1||','||v2||','||v3);
elsif v1>=v2 and v3>=v2 and v1>=v3 then
dbms_output.put_line(v1||','||v3||','||v2);
elsif v1<=v2 and v3<=v1 then
dbms_output.put_line(v2||','||v1||','||v3);
elsif v1<=v2 and v3>=v1 and v3<=v2 then
dbms_output.put_line(v2||','||v3||','||v1);
elsif v3>=v1 and v3>=v2 and v1>=v2 then
dbms_output.put_line(v3||','||v1||','||v2);
else
dbms_output.put_line(v3||','||v2||','||v1);
end if;
end;
declare
v1 number(38,5) :=&第一个数;
v2 number(38,5) :=&第二个数;
v3 number(38,5) :=&第三个数;
a number(38,5);
b number(38,5);
c number(38,5);
begin
select greatest(v1,v2,v3) into a from dual;
select least(v1,v2,v3) into c from dual;
select (v1+v2+v3-a-c) into b from dual;
dbms_output.put_line(a||','||b||','||c);
end;
declare
a number(5) := &a;
b number(5) := &b;
c number(5) := &c;
begin
dbms_output.put_line(greatest(a, b, c) || '>' ||
(a + b + c -greatest(a, b, c) - least(a, b, c)) || '>' ||
least(a, b, c));
end;
(5).某公司要根据雇员的职位来加薪,公司决定按下列加薪结构处理:
Designation | Raise |
---|---|
clerk | 500 |
salseman | 1000 |
analyst | 1500 |
otherwise | 2000 |
编写一个程序块,接受一个雇员名,从emp表中实现上述加薪处理
declare
v_ename varchar2(30) :=&请输入一个雇员名;
begin
for v in(select * from emp_0217 where ename=v_ename) loop
if v.job='CLERK' then
update emp_0217 set sal=sal+500 where empno=v.empno;
elsif v.job='SALESMAN' then
update emp_0217 set sal=sal+1000 where empno=v.empno;
elsif v.job='ANALYST' then
update emp_0217 set sal=sal+1500 where empno=v.empno;
else
update emp_0217 set sal=sal+2000 where empno=v.empno;
end if;
end loop;
commit;
end;
(6).计算下面级数当末项小于0.001时的部分和。
1/(12)+1/(23)+1/(34)+…+1/(n(n+1))+ ……
declare
i number(20) :=1;
s number(38,10) :=0;
begin
loop
s :=s+1/(i*(i+1));
exit when 1/(i*(i+1))<0.001;
i:=i+1;
end loop;
dbms_output.put_line('i是:'||i||', s是:'||to_char(s,'fm999999990.999999999'));
end;
1.为什么使用loop循环而不是for或者while
2.为什么自加在exit之后执行;
3.为什么注释掉的输出结果是不对的;
4.测试到0.1,0.01;
(7).计算s=12+23+…+N*(N+1),当N=50的值
declare
s number(38):=0;
begin
for i in 1..50 loop
s :=s+i*(i+1);
dbms_output.put_line(i||','||s);
end loop;
end;
declare
i number(10) := 1;
s number(10) := 0;
begin
while i<=50 loop
s := s + i * (i + 1);
i :=i+1;
end loop;
dbms_output.put_line(i-1 || ',' || s);
end;
declare
s number(10):=0;
begin
for i in 1..50 loop
s:=s+i*(i+1);
dbms_output.put_line(i);
end loop;
dbms_output.put_line(s);
--dbms_output.put_line(i|| ',' || s);--错误的
end;
–循环变量:
用loop或者while的时候,是在声明部分定义循环变量,这个时候的变量是全局的;
在for循环中,循环变量i只在循环中定义,所以i的作用范围只在循环内部,也叫局部变量;
(8).编程序求满足不等式 1+32+52+…+N^2>2000的最小N值
declare
s number(38):=0;
i number(10):=1;
begin
loop
s:=s+power(i,2);
exit when s>2000;
i :=i+2;
end loop;
dbms_output.put_line(i||','||s);
end;
declare
s number(38):=0;
i number(10):=1;
begin
loop
s:=s+power((2*i-1),2);
exit when s>2000;
i:=i+1;
end loop;
dbms_output.put_line((2*i-1)||','||s);
end;
(9).计算S=1!+2!+…+10!(阶乘, 1!=1, 2!=1x2, 3!=1x2x3)
1:先实现阶乘;
2:实现阶乘求和;
正向:
declare
i number(2) := 1;
j number(2);
t number(20);
s number(20) := 0;
begin
loop
t:=1;
j:=1;
loop
t := t * j;
exit when j = i;
j := j + 1;
end loop;
s := s + t;
dbms_output.put_line(t);
exit when i = 10;
i := i + 1;
end loop;
dbms_output.put_line(s);
end;
反向:
declare
i number(10) := 10;
j number(10);
s number(38) := 0;
t number(38) := 0;
begin
loop
s := s + t;
j := i;
loop
exit when j < 2;
if(j=i) then
t := j * (j - 1);
end if;
if(j<i) then
t := t * (j - 1);
end if;
j := j - 1;
end loop;
i := i - 1 ;
exit when i = 1;
end loop;
dbms_output.put_line(t);
dbms_output.put_line(s+3);
end;
**
12.退出循环 exit continue return
**
exit:退出循环,即不再执行循环体
continue:退出本次循环,执行下一次循环;
return:遇到return,直接退出程序;
范例:
declare
begin
for i in 1 .. 9 loop
if i = 5 then
exit;
end if;
dbms_output.put_line(i);
end loop;
dbms_output.put_line('循环体外打印');
end;
declare
begin
for i in 1 .. 9 loop
if i = 5 then
continue;
end if;
dbms_output.put_line(i);
end loop;
dbms_output.put_line('循环体外打印');
end;
declare
begin
for i in 1 .. 9 loop
if i = 5 then
return;
end if;
dbms_output.put_line(i);
end loop;
dbms_output.put_line('循环体外打印');
end;