pl/sql 之三大循环的完全学习指南

1 循环的概述

        每个循环包括两个部分:循环边界和循环体。其中,循环边界由一些pl/sql保留字组成。位于循环体外部的代码不应该知道循环内部的工作。但是,循环是把双刃剑,程序的性能问题很容易定位到循环。

    2 循环的类型

        2.1 简单循环

              语法

  1. loop 
  2. 可执行的语句 
  3. end loop; 
  loop
   可执行的语句
  end loop;


              属性

属性描述
why

1)不能确定循环会执行多少次

2)要求循环至少执行一次

whenexit或者exit when发生时结束
how通过exit或者exit when来结束

              注释

                     1)离了exit或者exit when,简单循环便是死循环

                     2)exit when和exit的运用场景:

                          只有一个条件表达式决定循环是否应该结束时,使用exit when

  1. loop 
  2. balance_remaining := account_balance(account_id); 
  3. exit when balance_remaining<1000; 
  4. apply_balance(account_id,balance_remaining); 
  5. end loop; 
     loop
     balance_remaining := account_balance(account_id);
     exit when balance_remaining<1000;
     apply_balance(account_id,balance_remaining);
     end loop;


                          需要根据不同的退出条件来设置“返回值”时,在case语句中,使用exit

  1. loop 
  2. case 
  3. when salary>=10000 and salary<=20000 
  4. then  
  5.   give_bonus(employee_id,1500); 
  6.   exit; 
  7. when salary>2000 and salary<40000 
  8. then  
  9.   give_bonus(employee_id,1000); 
  10.   exit; 
  11. when salary>=40000  
  12. then  
  13.   give_bonus(employee_id,500); 
  14.   exit; 
  15. else  
  16.   give_bonus(employee_id,0); 
  17.   exit; 
  18. end case
  19. end loop; 
     loop
     case
     when salary>=10000 and salary<=20000
     then 
       give_bonus(employee_id,1500);
       exit;
     when salary>2000 and salary<40000
     then 
       give_bonus(employee_id,1000);
       exit;
     when salary>=40000 
     then 
       give_bonus(employee_id,500);
       exit;
     else 
       give_bonus(employee_id,0);
       exit;
     end case;
     end loop;


        2.2 while循环

              语法

  1. while condition 
  2.   loop 
  3.     可执行语句 
  4.   end loop; 
  while condition
    loop
      可执行语句
    end loop;


              属性

属性描述
why

1)事先无法确定循环的次数

2)你想通过条件来终止循环

3)循环体不是必须要执行的

when条件判断是在循环边界处发生,每次进入循环体前都要进行这个判断
how循环边界的布尔表达式的求值结果是false 、null

              注释

                      1)while循环是依赖于条件的,倘若condition是false或者null,那么控制权就交割不到循环体手上

             例子

  1. while mask_index <= mask_count 
  2. loop 
  3.   begin 
  4.   retval :=to_date(value_in,fmts(mask_index)); 
  5.   date_converted :=true
  6.   exception 
  7.   when OTHERS 
  8.   then 
  9.     mask_index :=mask_index+1; 
  10.   end
  11. end loop; 
  while mask_index <= mask_count
  loop
    begin
    retval :=to_date(value_in,fmts(mask_index));
    date_converted :=true;
    exception
    when OTHERS
    then
      mask_index :=mask_index+1;
    end;
  end loop;


        2.3 for循环

              2.3.1 数值型for循环

              语法

  1. for loop_index in [reverse] lowest_number..highest_number 
  2. loop 
  3.   可执行语句 
  4. end loop; 
  for loop_index in [reverse] lowest_number..highest_number
  loop
    可执行语句
  end loop;


             属性

属性描述
why如果只想有限次数的执行循环,但又不想过早的退出
when循环索引超过循环上边界时
how数值型for循环只要达到范围区指定的循环次数,就会无条件结束

             注释

                      1)loop_index会自动、隐士的被pl/sql引擎用一个int型的局部变量声明
                      2)范围部分使用的表达式,当且仅当循环开始时被求值一次,然后在整个生命周期内有效
                      3)循环体内改变范围表达式使用的变量,对循环边界没任何作用
                      4)循环体内不要改变loop_index或者范围边界值,这是个相当不好的编程习惯

             例子

  1. for loop_index in 1..100 
  2. loop 
  3.   if mod(loop_index,2)=0 
  4.   then 
  5.     calc_values(loop_index); 
  6.   end if; 
  7. end loop; 
  for loop_index in 1..100
  loop
    if mod(loop_index,2)=0
    then
      calc_values(loop_index);
    end if;
  end loop;

             2.3.2 游标型for循环

             语法

  1. for record in {cursor_name | select子句} 
  2. loop 
  3.   可执行语句 
  4. end loop; 
  for record in {cursor_name | select子句}
  loop
    可执行语句
  end loop;


             属性

属性描述
why当要依次取出一个游标中的每一行记录并处理时
when每次循环体执行后,pl/sql引擎会执行一个取数据的操作,如果游标中的%NOTFOUND属性为TRUE时,循环便结束
how当游标中的所有记录都取出后,游标型for循环就无条件结束

            注释

                     1)record由pl/sql引擎隐士声明,请不要再显示的声明一个循环索引同名的record了
                     2)如果declare cursor时,select子句中一列是表达式,则必须为这个表达式指定别名
                     3)在循环体内访问游标记录的特定值是通过句点表示法
                     4)循环执行次数为游标所取的记录数

             例子
             --动态重建索引

  1. declare 
  2.   cursor ind is select index_name from user_indexes; 
  3. begin 
  4.   for cur in ind 
  5.   loop 
  6.     execute immediate 
  7.     'alter index '||cur.index_name||' rebuild'
  8.   end loop; 
  9. end
  declare
    cursor ind is select index_name from user_indexes;
  begin
    for cur in ind
    loop
      execute immediate
      'alter index '||cur.index_name||' rebuild';
    end loop;
  end;


    3 循环的标签

            定义:循环的别名

            语法:<<tag_name>>


                   作用
                  1)使用tag可以明确的把循环的开头和结束绑定在一起,提高了嵌套循环的可读性
                  2)让循环的index_loop更具规范化,无论是一条记录还是一个值


                   例子

  1. <<year_loop>> 
  2. for year_number in 2012..2014 
  3. loop 
  4.   <<month_loop>> 
  5.   for month_number in 1..12 
  6.   loop 
  7.     if year_loop.year_number=2012  
  8.     then .. 
  9.     end if; 
  10.   end loop month_loop; 
  11. end loop year_loop; 
<<year_loop>>
for year_number in 2012..2014
loop
  <<month_loop>>
  for month_number in 1..12
  loop
    if year_loop.year_number=2012 
    then ..
    end if;
  end loop month_loop;
end loop year_loop;


    4 循环的技巧

                 1)index_loop使用可以自我说明的名称
                 2)从已关闭的游标中获取循环执行信息

                 例子

  1. declare 
  2. book_count number :=0 
  3. for book_rec in book_cur (author_in => 'THINK,WATER'
  4. loop 
  5.   ..process data.. 
  6.   book_count := book_cur%ROWCOUNT; 
  7. end loop; 
  8. if book_count > 10 
  9. then .. 
   declare
   book_count number :=0
   for book_rec in book_cur (author_in => 'THINK,WATER')
   loop
     ..process data..
     book_count := book_cur%ROWCOUNT;
   end loop;
   if book_count > 10
   then ..

原文地址:http://blog.youkuaiyun.com/linwaterbin/article/details/7885718

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值