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