条件制御文は、異なる条件に基づいてプログラムコードの一部を実行または無視します。これは、IF または CASE を使用して実現できます。
適用対象
この内容はOceanBaseデータベースEnterprise Editionにのみ適用されます。OceanBaseデータベースCommunity EditionはMySQLモードのみを提供します。
その中で、IF ステートメントには以下のような形態も含まれます:
IF THENIF THEN ELSEIF THEN ELSIF
CASE ステートメントは一連の条件から選択し、対応するステートメントを実行します。CASE ステートメントには以下の形式があります:
シンプル型。単一の式の値を計算し、複数の潜在的な値と比較します。
リサーチ型。複数の条件を計算し、最初に
TRUEとなる条件を選択します。
CASE ステートメントは、複数の分岐があるアプリケーションシナリオに適しています。
IF THENステートメント
IF THEN ステートメントの構造は以下のとおりです:
IF condition THEN
statements
END IF;
condition が TRUE の場合、statements を実行します。
例:
obclient> CREATE TABLE employees(
employee_id NUMBER(4,0),
name VARCHAR(10),
salary NUMBER(7,2)
);
Query OK, 0 rows affected
obclient> INSERT INTO employees (employee_id,name,salary)VALUES(105,'Adam',15000);
Query OK, 1 row affected
obclient> DECLARE
V_EMP_NAME employees.name%TYPE := 'Adam';
V_EMP_SAL employees.salary%TYPE;
V_bonus number := 0;
BEGIN
SELECT salary INTO V_EMP_SAL FROM employees
WHERE name=V_EMP_NAME;
IF V_EMP_SAL > 10000 THEN
V_bonus := V_EMP_SAL * 0.4;
END IF;
DBMS_OUTPUT.PUT_LINE(V_EMP_NAME||'''bonus: '||V_bonus);
END;
/
Query OK, 0 rows affected
Adam'bonus: 6000
プログラム設計時には、次の例のような長すぎる IF ステートメントを避ける必要があります。
IF new_weight < minimum_weight THEN
isHealthy := TRUE;
ELSE
isHealthy := TRUE;
END IF;
最適化された書き方では、ブール式を直接代入できます:isHealthy:= new_weight < minimum_weight;
ブール変数は TRUE、FALSE、または NULL を格納でき、条件判断に直接使用できます。そのため、次の例の書き方は避ける必要があります。
IF isHealthy = FALSE THEN
RAISE start_one_month_diet;
END IF;
最適化された書き方は次のとおりです:
IF NOT isHealth THEN
RAISE start_one_month_diet;
END IF;
IF THEN ELSEステートメント
IF THEN ELSE ステートメントの構造は以下のとおりです:
IF condition THEN
statements
ELSE
else_statements
END IF;
condition が TRUE の場合、statements を実行し、そうでない場合は else_statements を実行します。
例:
obclient> CREATE TABLE employees(
employee_id NUMBER(4,0),
name VARCHAR(10),
salary NUMBER(7,2)
);
Query OK, 0 rows affected
obclient> INSERT INTO employees (employee_id,name,salary)VALUES(105,'Adam',15000);
Query OK, 1 row affected
obclient> DECLARE
V_EMP_NAME employees.name%TYPE := 'Adam';
V_EMP_SAL employees.salary%TYPE;
V_bonus number := 0;
BEGIN
SELECT salary INTO V_EMP_SAL FROM employees
WHERE name=V_EMP_NAME;
IF V_EMP_SAL < 10000 THEN
V_bonus := V_EMP_SAL * 0.4;
ELSE
V_bonus := V_EMP_SAL * 0.25;
END IF;
DBMS_OUTPUT.PUT_LINE(V_EMP_NAME||'''bonus: '||V_bonus);
END;
/
Query OK, 0 rows affected
Adam'bonus: 3750
IF THEN ELSIF ステートメント
IF THEN ELSEF ステートメントの構造は以下のとおりです:
IF condition_1 THEN
statements_1
ELSIF condition_2 THEN
statements_2
[ ELSIF condition_3 THEN
statements_3
]...
[ ELSE
else_statements
]
END IF;
condition_1 の値が TRUE の場合、statements_1 ステートメントを実行してプログラムを終了します。そうでない場合、condition_2 の値が TRUE の場合、statements_2 ステートメントを実行してプログラムを終了します。これを condition_n すべてが TRUE でないまで繰り返し、最後に else_statements ステートメントを実行してプログラムを終了します。
IF THEN ステートメントはネスト可能であるため、IF THEN ELSIF と IF THEN ELSE の2つのステートメントは等価です。
IF THEN ELSIF ステートメントは以下のとおりです:
IF condition_1 THEN statements_1;
ELSIF condition_2 THEN statements_2;
ELSIF condition_3 THEN statement_3;
END IF;
IF THEN ELSE ステートメントは以下のとおりです:
IF condition_1 THEN
statements_1;
ELSE
IF condition_2 THEN
statements_2;
ELSE
IF condition_3 THEN
statements_3;
END IF;
END IF;
END IF;
例:
obclient> CREATE TABLE employees(
employee_id NUMBER(4,0),
name VARCHAR(10),
salary NUMBER(7,2)
);
Query OK, 0 rows affected
obclient> INSERT INTO employees (employee_id,name,salary)VALUES(105,'Adam',4000);
Query OK, 1 row affected
obclient>DECLARE
V_EMP_NAME employees.name%TYPE := 'Adam';
V_EMP_SAL employees.salary%TYPE;
V_bonus number := 0;
BEGIN
SELECT salary INTO V_EMP_SAL FROM employees
WHERE name=V_EMP_NAME;
IF V_EMP_SAL > 10000 THEN
V_bonus := V_EMP_SAL * 0.4;
ELSIF V_EMP_SAL > 5000 THEN
V_bonus := V_EMP_SAL * 0.25;
ELSE
V_bonus := V_EMP_SAL * 0.1;
END IF;
DBMS_OUTPUT.PUT_LINE(V_EMP_NAME||'''bonus: '||V_bonus);
END;
/
Query OK, 0 rows affected
Adam'bonus: 400
シンプルCASEステートメント
最もシンプルなCASE文は、単一の式の値を計算し、複数の潜在的な値と比較します。
シンプルなCASEステートメントの構造は次のとおりです:
CASE selector
WHEN selector_value_1 THEN statements_1
WHEN selector_value_2 THEN statements_2 ...
WHEN selector_value_n THEN statements_n
[ ELSE
else_statements ]
END
CASE;
上記の例では、selectorは式であり、各selector_valueはリテラル値または式にすることができます。シンプルなCASEステートメントは、selectorの値を順番にselector_valueと比較し、最初に等しいselector_valueが見つかると、他のselector_valueとの比較は行われません。等しいselector_valueが見つからない場合、CASEはelse_statementsを実行します。この時点でelse_statementsが存在しない場合、プログラムはエラーを報告します。
例:
obclient> DECLARE
grade CHAR(1);
BEGIN
grade := 'B';
CASE grade
WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('PASS');
WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('SUSPEND');
WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('FAIL');
ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
END CASE;
END;
/
Query OK, 0 rows affected
SUSPEND
プログラムがエラーを報告する例:
obclient> DECLARE
grade CHAR(1);
BEGIN
grade := 'D';
CASE grade
WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('PASS');
WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('SUSPEND');
WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('FAIL');
-- ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
END CASE;
END;
/
OBE-00600: internal error code, arguments: -5571, Case not found for CASE statement
サーチ型CASEステートメント
サーチ型CASE文では、CASEの後に計算する式はなく、代わりにWHENの後にそれぞれ異なるブール式が続きます。サーチ型CASEは複数のブール式を計算し、最初にTRUEとなる分岐を選択します。
サーチ型CASEステートメントの構造は以下のとおりです:
CASE
WHEN condition_1 THEN statements_1
WHEN condition_2 THEN statements_2 ...
WHEN condition_n THEN statements_n
[ ELSE
else_statements ]
END CASE;
サーチ型CASEステートメントは、最初のconditionがTRUEとなるstatementを実行し、その後他のstatementsは実行されません。すべてのconditionがTRUEでない場合は、else_statementsが実行されます。この時点でelse_statementsが存在しない場合、プログラムはエラーを報告します。
単純なCASEステートメントに対応するサーチ型CASEステートメントの例は以下のとおりです:
obclient> DECLARE
grade CHAR(1);
BEGIN
grade := 'D';
CASE
WHEN grade = 'A' THEN DBMS_OUTPUT.PUT_LINE('PASS');
WHEN grade = 'B' THEN DBMS_OUTPUT.PUT_LINE('SUSPEND');
WHEN grade = 'C' THEN DBMS_OUTPUT.PUT_LINE('FAIL');
ELSE DBMS_OUTPUT.PUT_LINE('UNEXPECTED');
END CASE;
END;
/
Query OK, 0 rows affected
UNEXPECTED