PL/SQL制御構造

制御構造は、SQLに対するPL/SQLの拡張機能です。TimesTenでは、Oracle Databaseと同じ制御構造がサポートされています。

この項では、次の制御構造について説明します。

条件制御

条件制御の例としては、IF-THEN-ELSEおよびCASE構造があげられます。

次の例では、IF-THEN-ELSE構造を使用して、現在の給与を基に従業員の昇給を決定します。また、従業員のjob_idに基づいて実行する処理のコースを選択するために、CASE構造も使用します。

Command> DECLARE
           jobid employees.job_id%TYPE;
           empid employees.employee_id%TYPE := 115;
           sal employees.salary%TYPE;
           sal_raise NUMBER(3,2);
         BEGIN
           SELECT job_id, salary INTO jobid, sal from employees
             WHERE employee_id = empid;
           CASE
             WHEN jobid = 'PU_CLERK' THEN
               IF sal < 3000 THEN sal_raise := .12;
               ELSE sal_raise := .09;
               END IF;
             WHEN jobid = 'SH_CLERK' THEN
               IF sal < 4000 THEN sal_raise := .11;
               ELSE sal_raise := .08;
               END IF;
             WHEN jobid = 'ST_CLERK' THEN
               IF sal < 3500 THEN sal_raise := .10;
               ELSE sal_raise := .07;
               END IF;
             ELSE
               BEGIN
                 DBMS_OUTPUT.PUT_LINE('No raise for this job: ' || jobid);
               END;
           END CASE;
         DBMS_OUTPUT.PUT_LINE ('Original salary ' || sal);
         -- Update
         UPDATE employees SET salary = salary + salary * sal_raise
         WHERE employee_id = empid;
         END;
         /
Original salary 3100
 
PL/SQL procedure successfully completed.

反復制御

反復制御構造では、指定した条件がTRUEであるかぎり、文のシーケンスが繰り返し実行されます。反復操作の実行にはループ構造が使用されます。

次の3つのタイプのループがあります。

  • 基本ループ

  • FORループ

  • WHILEループ

基本ループは、全体にわたる条件を使用しないで反復処理を実行します。FORループは、カウントに基づいて反復処理を実行します。WHILEループは、条件に基づいて反復処理を実行します。

この例では、WHILEループを使用します。

Command> CREATE TABLE temp (tempid NUMBER(6),
         tempsal NUMBER(8,2),
         tempname VARCHAR2(25));
Command> DECLARE
           sal employees.salary%TYPE := 0;
           mgr_id employees.manager_id%TYPE;
           lname employees.last_name%TYPE;
           starting_empid employees.employee_id%TYPE := 120;
         BEGIN
           SELECT manager_id INTO mgr_id
             FROM employees
             WHERE employee_id = starting_empid;
           WHILE sal <= 15000 LOOP -- loop until sal > 15000
             SELECT salary, manager_id, last_name INTO sal, mgr_id, lname
               FROM employees WHERE employee_id = mgr_id;
           END LOOP;
           INSERT INTO temp VALUES (NULL, sal, lname);  -- insert NULL for tempid
           COMMIT;
         EXCEPTION
           WHEN NO_DATA_FOUND THEN
             INSERT INTO temp VALUES (NULL, NULL, 'Not found');  -- insert NULLs
             COMMIT;
         END;
         /
 
PL/SQL procedure successfully completed.
 
Command> SELECT * FROM temp;
< <NULL>, 24000, King >
1 row found.

CONTINUE文

CONTINUE文を使用すると、ループ内の制御を新しい反復に移すことができます。

この例では、ループの10回の反復のそれぞれで、最初のv_totalの代入が実行されます。2つ目のv_totalの代入は、ループの最初の5回の反復で実行されます。CONTINUE文はループ内の制御を新しい反復に移すため、ループの最後の5回の反復では2つ目のv_totalの代入は実行されません。最終的なv_totalの値は、70になります。

Command> DECLARE
           v_total  SIMPLE_INTEGER := 0;
         BEGIN
           FOR i IN 1..10 LOOP
             v_total := v_total + i;
             DBMS_OUTPUT.PUT_LINE ('Total is : ' || v_total);
             CONTINUE WHEN i > 5;
             v_total := v_total + i;
             DBMS_OUTPUT.PUT_LINE ('Out of loop  Total is: ' || v_total);
           END LOOP;
         END;
         /
Total is : 1
Out of loop  Total is: 2
Total is : 4
Out of loop  Total is: 6
Total is : 9
Out of loop  Total is: 12
Total is : 16
Out of loop  Total is: 20
Total is : 25
Out of loop  Total is: 30
Total is : 36
Total is : 43
Total is : 51
Total is : 60
Total is : 70

PL/SQL procedure successfully completed.