条件制御文は、さまざまな条件に基づいてプログラムコードのセットを実行または無視します。これは 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