控制结构

控制结构

流程控制是PL/SQLSQL的最重要的扩展。PL/SQL不仅能让我们操作Oracle数据,还能让我们使用条件、循环和顺序控制语句来处理数据,如IF-THEN-ELSECASEFOR-LOOPWHILE-LOOPEXIT-WHENGOTO等。

  • 条件控制

我们经常需要根据环境来采取可选择的行动。IF-THEN-ELSE语句能让我们按照条件来执行一系列语句。IF用于检查条件;THEN决定在条件值为true的情况下执行;ELSE在条件值为falsenull的情况才执行。

看一下下面的例子,这个程序用于处理银行事务。在我们从账户3取走$500元之前,它会先确认是否有足够的资金供我们支配。如果余额足够,程序就会更新账户(accounts)表的信息,否则的话,程序会向审核(audit)表插入一条余额不足的提示信息。

DECLARE
  acct_balance         
NUMBER(11, 2);
  acct        
CONSTANT NUMBER
(4)     := 3;
  debit_amt   
CONSTANT NUMBER
(5, 2)  := 500.00;
BEGIN

  
SELECT        bal
           
INTO
 acct_balance
           
FROM
 accounts
          
WHERE
 account_id = acct
  
FOR UPDATE OF
 bal;

  
IF acct_balance >= debit_amt THEN

    
UPDATE accounts
       
SET
 bal = bal - debit_amt
     
WHERE
 account_id = acct;
  
ELSE

    
INSERT INTO temp
         
VALUES (acct, acct_balance, 'Insufficient funds'
);
    
-- insert account, current balance, and message

  
END IF;

  
COMMIT
;
END;

要从多个条件值中选出对应的操作时,我们可以使用CASE结构。CASE表达式会计算条件值,然后相应的操作(这个操作有可能是一个完整的PL/SQL)

CASE
  
WHEN shape = 'square' THEN
    area    := side * side;
  
WHEN shape = 'circle' THEN
    
BEGIN
      area    := pi *(radius * radius);
      DBMS_OUTPUT.put_line(
'Value is not exact because pi is irrational.');
    
END
;
  
WHEN shape = 'rectangle' THEN

    area    := LENGTH * width;
  
ELSE
    
BEGIN
      DBMS_OUTPUT.put_line(
'No formula to calculate area of a' || shape);
      
RAISE
 PROGRAM_ERROR;
    
END
;
END CASE;

  • 循环控制

LOOP语句能让我们多次执行一系列语句。LOOP循环以关键字LOOP开头,END LOOP结尾i。下面语句就是最简单的LOOP循环:

LOOP
  
-- sequence of statements
END LOOP;

FOR-LOOP语句可以指定整数的范围,然后范围内每一个数字执行一次。例如,下面的循环将向数据库表插入500个数字和它们的平方根:

FOR num IN 1 .. 500 LOOP
  
INSERT INTO roots
       
VALUES
 (num, SQRT(num));
END LOOP;

WHILE-LOOP语句会按照某个条件值执行。每次循环条件值都会被计算一次,如果条件值为true,循环内的语句就会被执行,然后再次回到循环顶部,重新计算条件值。如果条件值为false或是null的话,循环就会停止,控制权被移交给下一语句。

下面的例子中,我们要找出第一个工资高于$2500的且行政级别高于雇员编号7499雇员的员工:

DECLARE
  salary           emp.sal%
TYPE     := 0;
  mgr_num          emp.mgr%
TYPE
;
  last_name        emp.ename%
TYPE
;
  starting_empno   emp.empno%
TYPE
   := 7499;
BEGIN

  
SELECT mgr
    
INTO
 mgr_num
    
FROM
 emp
   
WHERE
 empno = starting_empno;

  
WHILE salary <= 2500 LOOP

    
SELECT sal, mgr, ename
      
INTO
 salary, mgr_num, last_name
      
FROM
 emp
     
WHERE
 empno = mgr_num;
  
END LOOP
;

  
INSERT INTO
 temp
       
VALUES (NULL
, salary, last_name);

  
COMMIT
;
EXCEPTION

  
WHEN NO_DATA_FOUND THEN
    
INSERT INTO temp
         
VALUES (NULLNULL'Not found'
);

    
COMMIT
;
END;

EXIT-WHEN语句可以在需要继续执行循环的情况下退出循环。当遇到EXIT语句时,WHEN子句中的条件值就会被计算。如果条件为true,循环就会结束,控制权交给下一条语句。下面的例子中,在total的值超过2500时,循环就会结束:

LOOP
  ...
  total    := total + salary;
  
EXIT WHEN total > 25000;   -- exit loop if condition is true
END LOOP;
-- control resumes here

  • 顺序控制

GOTO语句能让我们无条件地跳转到一个标签。标签就是一个用双尖括号夹起来的未声明标示符,它必须在一个可执行语句或是PL/SQL块之前。执行时,GOTO语句将控制权交给用标签作了标记的语句或块,如下例所示:

IF rating > 90 THEN
  
GOTO calc_raise;   -- branch to label
END IF;

<<calc_raise>>
IF job_title = 'SALESMAN' THEN   -- control resumes here

  amount    := commission * 0.25;
ELSE
  amount    := salary * 0.10;
END IF;

8、模块化

模块化可以让我们把程序分成多个部分,这样可以把复杂的问题划分开来,更好的解决问题。PL/SQL为我们提供了块、子程序和包三个程序单元来用于模块化处理。

  • 子程序

子程序有两种,分别是函数和过程。子程序很像一段小型的程序,由可选的声明部分,执行控制部分和可选的异常控制部分组成。

PROCEDURE award_bonus(emp_id NUMBERIS
  bonus          
REAL;
  comm_missing   
EXCEPTION
;
BEGIN   -- executable part starts here

  
SELECT comm * 0.15
    
INTO
 bonus
    
FROM
 emp
   
WHERE
 empno = emp_id;

  
IF bonus IS NULL THEN

    
RAISE comm_missing;
  
ELSE

    
UPDATE payroll
       
SET
 pay = pay + bonus
     
WHERE
 empno = emp_id;
  
END IF
;
EXCEPTION   -- exception-handling part starts here

  
WHEN comm_missing THEN
    ...
END award_bonus;

调用时,这个过程接受一个雇员编号。它使用编号来查询雇员的commission,同时计算出15%的奖金。然后,它检查bonus总值。如果奖金为空,就会抛出异常,否则雇员的工资记录就会被更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值