PLSQL——03、结构控制

喜夏-厌秋 提交于 2020-02-01 00:03:49

使用IF语句按条件判断,控制PL/SQL执行流程

格式如下:
if-then-end if;
if-then-else-end if;
if-then-elsif-then-else-end if;

演示:

set serveroutput on
declare
  v_hire_date date := to_date('1995-01-15','yyyy-mm-dd');
  v_five_years boolean;
begin
    if months_between(sysdate,v_hire_date)/12 > 5 then
      v_five_years := true;
      dbms_output.put_line('true');
    else
      v_five_years := false;
      dbms_output.put_line('false');
  end if;
end;
/

使用CASE表达式

格式1:

set serveroutput on
define p_grade='a'
declare
  v_grade char(1) := upper('&p_grade');
  v_appraisal varchar2(20);
begin
  v_appraisal :=
    case v_grade
        when 'A' then 'excellent'
        when 'B' then 'very good'
        when 'C' then 'good'
        else 'no such grade!'
    end;
  dbms_output.put_line ('grade: '|| v_grade || ' appraisal ' || v_appraisal);
end;
/

格式2:

DECLARE
  v_grade CHAR(1) := UPPER('&p_grade');
  v_appraisal VARCHAR2(20);
BEGIN
  v_appraisal :=
  CASE --省略
  WHEN v_grade='A' THEN 'Excellent'
  WHEN v_grade='B' THEN 'Very Good'
  WHEN v_grade='C' THEN 'Good'
  ELSE 'No such grade'
  END;
  DBMS_OUTPUT.PUT_LINE ('Grade: '|| v_grade || ' Appraisal ' || v_appraisal);
END;
/

循环遍历控制

跳出整个循环:exit
跳出本次循环:continue (11g之后新加,10g没有此关键字)

continue演示:

declare
  total int:=0;
begin
  for i in 1..10 loop
     if mod(i,2)=0 then
        continue;
     end if;
     total:=total+i;
  end loop;
  dbms_output.put_line(total);
end;
/

循环演示

基本LOOP循环:

set serveroutput on
declare
  i integer :=1;
begin
  loop
    dbms_output.put_line(i);
    i := i+1;
    exit when i>10;
  end loop;
end;
/

while循环

declare
  i integer :=1;
begin
  while i<=10 loop
    dbms_output.put_line(i);
    i := i+1;
  end loop;
end;
/

数字for循环

begin
  for i in 1..10 loop        --其中i不用声明就可以使用
    dbms_output.put_line(i);
  end loop;
end;
/


begin
  for i in reverse 1..10 loop    --反向循环
    dbms_output.put_line(i);
  end loop;
end;
/

实现双重循环

演示:
      外循环和内循环都执行5次.
      内外计数器变量名相同:i
      显示内循环的计数器和外循环的计数器的乘积
      当乘积超过15时候,退出

declare
  v_plus number(10);
begin
  <<outer_loop>>
   for i in 1..5 loop
     <<inner_loop>>
     for i in 1..5 loop
        v_plus:=i*outer_loop.i;
        exit when v_plus>15;
        dbms_output.put_line(v_plus);
     end loop inner_loop;
   end loop outer_loop;
end;
/

标号和goto

declare
   v_counter number := 1;
begin
   loop 
       dbms_output.put_line('in loop V_counter current value:'||V_counter);
       v_counter := v_counter + 1;
     if v_counter > 10 then
       goto l_ENDofLOOP;
      end if;
   end loop;
   <<l_ENDofLOOP>>
   dbms_output.put_line('end loop V_counter current value:'||V_counter);
end;
/

练习

1、写一个PL/SQL块
向dept表中循环插入5条记录,每一条记录的deptno 值比表中最大的deptno 值增加1,dname分别为"Test1" "Test2"..."Test5",loc列的值都为空。

declare
   v_deptno scott.dept.deptno%type;
   v_loop number(1):=1;
begin
   for i in 1..5 loop
    select MAX(deptno) into v_deptno from dept; 
    insert into dept(deptno,dname)
    values ((v_deptno+1),('Test'||to_char(i)));
    commit;
   end loop;
end;
/

2、事务处理控制语句(COMMIT 和 ROLLBACK)

CREATE TABLE T1(ID INT);
/*(批量提交,减少log file sync提高效率!)*/
DECLARE 
V_NUM NUMBER := 0;
BEGIN
FOR V_LOOPCOUNTER IN 1..500 LOOP
    INSERT INTO T1 VALUES (V_LOOPCOUNTER);
    V_NUM := V_NUM + 1;
    IF V_NUM = 50 THEN
      COMMIT;
      V_NUM := 0;
    END IF;
  END LOOP;
  COMMIT;
END;
/

3、Plsql表+record+循环打印结果集(dept表的所有行所有列)

declare
  TYPE CharacterTab IS TABLE OF dept%rowtype index by binary_integer;
  v_Character CharacterTab;
  v_max number;
  v_deptno number;
begin
 select count(*) into v_max from dept;
 for i in 1..v_max loop
   select deptno 
   into v_deptno
   from
   (select rownum rn,d.* from dept d)
   where rn=i;
   select * 
   into v_Character(i) 
   from dept 
   where deptno=v_deptno;
  end loop;   
   for i in 1..v_max loop
     dbms_output.put_line(v_Character(i).deptno||' '||v_Character(i).dname||' '||v_Character(i).loc);
   end loop;
end;
/

4、新建一张表(只有一列数字),插入1..520个数,每50个一提交。

declare
  j number :=1;
begin
      for i in 1..520 loop
         insert into t7 values(i);
         if i-50*j=0 then
            commit;
            j :=j+1;
         end if;
      end loop;
      commit;
end;
/

5、for + pl/sql_table + record 实现将dept表所有行保存到pl/sql_table + record结构里并输出

declare
      type dept_table_type is table of dept%rowtype index by binary_integer;
      dept_table dept_table_type;
      v_max number;
begin
      select count(*) into v_max from dept;
      for i in 1..v_max loop
         select deptno,dname,loc into dept_table(i)
            from (select rownum rn,deptno,dname,loc from dept) where rn=i;
         dbms_output.put_line(dept_table(i).deptno||' '||dept_table(i).dname||' '||dept_table(i).loc);
      end loop;
end;
/
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!