PL/SQL程序结构

PL/SQL程序结构

本文将介绍PL/SQL的程序结构,将会涉及到分支和顺序结构,循环结构,异常处理等。

我写这篇文章的目的是为了在我阅读《Oracle.PL.SQL程序设计》一书是做些笔记,并分享给其他同学。


PL/SQL的分支和顺序结构

IF 结构

PL/SQL的IF结构主要是if…then…end if 结构,衍生出 if-else 还有 if-elsif-else等结构。

IF - THEN 结构
create or replace procedure demo1(num1 in number,num2 out number)
is
begin
  IF num1<5
    THEN  num2 := num1;
  END IF;

end;

在IF-THEN结构中 IF 后是一个布尔类型的变量,常量或者表达式,当结果为TRUE时执行THEN后面的语句,当结果为FALSE 或者 NULL时,结束IF语句。

在这里要说一下布尔表达式的三值逻辑,通常我们理解的布尔表达式的结果只有TRUE 以及 FALSE。 在PL/SQL中,如果一个表达式包含NULL值时,布尔表达式的结果为NULL。如果我们想避免NULL值的出现,可以采取以下方式,虽然我认为没有什么意义。

IF num1<5 OR num1 is not null
    THEN  num2 := num1;
  END IF;
IF - THEN -ELSE结构

这类结构通常是用于两个互斥选择,类似“或者…或者…”。

create or replace procedure demo2(num1 in number,num2 out number)
is
begin
  IF num1<5 or num1 >10
    THEN  num2 := num1;
  ELSE
    num2 := null;
  END IF;

end;
IF - THEN -ELSIF 结构

如果你的选择有很多分支,这个结构是一个不错的选择。

create or replace procedure demo3(num1 in number,num2 out number)
is
begin
  IF num1<5 or num1 >10
    THEN  num2 := num1;
  ELSIF num1 is null
    Then num2 := 0;
  ELSE
    num2 := 6;
  END IF;

end;
IF 的嵌套
create or replace procedure demo4(num1 in number,num2 out number)
is
begin
  IF num1<5 or num1 >10
    THEN 
      IF num1 >0
        then num2 := num1;
      ELSE
        num2 := (0-num1);
      END IF;
  ELSIF num1 is null
    Then num2 := 0;
  ELSE
    num2 := 6;
  END IF;

end;
IF 语法值得注意的地方
  • 每个IF都要匹配一个END IF; 这个就像是HTML中的标签,既然有< 就要有 />。
  • ELSIF 没有E,这个地方常常被我忽视。
  • 每个ELSIF 都要有THEN ,只有ELSE不需要THEN,
  • 短路求值,这个特性和其他语言一样,如果A AND B , 当A为false时,B不必执行,因为整个表达式的结果已经被确定。
PL/SQL的CASE结构

case结构用于在多个可能的情况下选择一种处理方式。PL/SQL从Oracle 9i 才支持case结构的。

简单CASE结构
create or replace procedure demo5(num1 in number,num2 out number)
is
begin
 case num1
   when 1 then num2 :=(0-num1);
   when 2 then num2 :=(0-num1);
   when 3 then num2 :=(0-num1);
   when 4 then num2 :=(0-num1);
   else num2 := 0;
 end case;  
end;

可能大家了解过java,在java中的switch结构和这里的case有些类似,不同的地方时switch是由case选择入口顺序执行下去,直至遇到break等跳出switch,而我们PL/SQL中的case是根据表达式选择一种情况执行。

选择型CASE结构

一个选择型的case对应一系列的布尔表达式,当某一个表达式结果为TRUE时,则处理对应的逻辑。

create or replace procedure demo6(num1 in number,num2 out number)
is
begin
 case 
   when num1>1 then num2 :=1;
   when num1>2 then num2 :=2;
   when num1>3 then num2 :=3;
   when num1>4 then num2 :=4;
   else num2 := 0;
 end case;  
end;
case表达式

case表达式只返回一个单独的值。

create or replace procedure demo7(num1 in number,num2 out number)
is
begin
  num2 := case 
            when num1=1 then 1
            when num1=2 then 2
            when num1=3 then 3
            when num1=4 then 4
            else 0
           end;  
end;
case结构值得注意的是:
  • else 是可选的,但是没有else 而且 没有对应的情况发生时,会报错为 : CASE_NOT_FOUNT(case表达式除外,它会返回null)。
  • case表达式中的结果是一个值,并且不需要以分号结尾。
  • case表达式的结尾为 end,而不是 end case。
NULL语句

一般而言,我们写语句,都希望让它干点什么,无论是什么,但是null语句是个相反,可能它比较懒吧。它的最好搭档就是GOTO语句了。因为GOTO语句可以让你少执行一部分语句。但是GOTO语句后面必须有可执行语句,但是当我们又没有什么可执行的使用,就可以写NULL啦。

create or replace procedure demo8
is
begin
       dbms_output.put_line('test the goto');
       goto the_point;
       dbms_output.put_line('这条语句不会输出');
       <<the_point>>
       null;
end;

PL/SQL的循环结构

简单循环 LOOP
create or replace procedure demo9(s_num in number,e_num in number,onum out number)
is
subnum number;
start_num number;
begin
       subnum :=0;
       start_num := s_num;
      LOOP
        /*if start_num = e_num
          then exit;
        end if;
        */
        EXIT WHEN start_num = e_num;
        subnum := subnum + start_num;
        start_num:=start_num+1;
      end loop;
      onum := subnum;
end;

在LOOP循环中 以LOOP开头,以end loop 结尾,退出循环只能依靠EXIT 或者 EXIT WHEN… 。

while 循环

while循环是一个条件循环,当满足条件是循环,脂质无法满足条件。

create or replace procedure demo10(s_num in number,e_num in number,onum out number)
is
subnum number;
start_num number;
begin
       subnum :=0;
       start_num := s_num;
      WHILE start_num<e_num
        LOOP
          subnum := subnum + start_num;
          start_num := 1+ start_num;
        END LOOP;
        ONUM := subnum;
end;

我们也可以使用LOOP循环搭配EXIT WHEN实现类似循环过程。

数值型for循环

for循环是一种计数循环,它的迭代次数在循环一开始就界定好了,在循环中不允许更改循环计数的起始边界和终止边界。REVERSE关键字可以实现从终止边界递减计数至其实边界。

create or replace procedure demo12(
onum out number)
is
subnum number;
begin
       subnum := 0;
       FOR var IN reverse 1..5
       LOOP
         subnum := var + subnum;       
       END LOOP;

         ONUM := subnum;
end;

值得注意的是,使用REVERSE时不必颠倒起始边界和终止边界,也必须把大值放到小值前面。数值型for循环无法改变步长(如何增长),步长只能为1,所以我们只能通过改变索引的方式进行我们的操作。

游标型for循环

游标型for循环是和一个显示的游标或者一个在边界中写入的SELECT语句。

当我们没有for循环时,通常是这样子:

create or replace procedure demo14
is
CURSOR M_CURSOR IS
       select * from emp;

      EMP_INFO M_CURSOR%ROWTYPE;
begin

       OPEN M_CURSOR;
       LOOP   
         FETCH M_CURSOR INTO EMP_INFO;
         EXIT WHEN M_CURSOR%NOTFOUND;
         dbms_output.put_line(EMP_INFO.empno);
       END LOOP;
       close M_CURSOR;

end;

首先我们声明了一个游标和一个记录,开启游标以后,我们循环的把游标里的数据放入记录中,并在屏幕中打印出empno,直至游标结尾。

当我们使用for循环就不用那么麻烦了。

create or replace procedure demo14
is
CURSOR M_CURSOR IS
       select * from emp;
begin
      FOR EMP_INFO IN M_CURSOR 
         LOOP
          dbms_output.put_line(EMP_INFO.empno);
         END LOOP; 

end;

我们还可以直接写select语句,但是那样显得不那么规范。

create or replace procedure demo13
is

begin

       FOR var IN (select * from emp)
       LOOP
         dbms_output.put_line(var.empno);
       END LOOP;

end;

在使用for循环时,我们可以用标签来给每个for循环命名以方便后期维护代码,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值