PL/SQL 知识 (个人笔记)(三)

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;

猜你喜欢

转载自blog.csdn.net/yang_z_1/article/details/111880097