目的
指定された条件式または2つのオペランドの等価性に基づいた、文の条件付きの実行の手段となります。
CASE文は、式の結果を戻すSQL CASE式とは異なります。
呼び出し
実行可能な
ストアド プロシージャのみ。
構文1
CASE operand_1 when_clause [...] [ ELSE statement [...] ] END CASE ;
- when_clause
WHEN operand_2 THEN statement [...]
構文2
CASE when_clause [...] [ ELSE statement [...] ] END CASE ;
- when_clause
WHEN conditional_expression THEN statement [...]
- statement
{ SQL_statement | compound_statement | assignment_statement | condition_statement | [ label_name : ] iteration_statement [ label_name ] | ITERATE label_name | LEAVE label_name }
- compound_statement
[ label_name : ] BEGIN [ local_declaration ] [...] [ cursor_declaration ] [...] [ condition_handler ] [...] [ statement; ] [...] END [ label_name ] ;
- assignment_statement
SET assignment_target = assignment_source
- condition_statement
{ CASE_statement | IF_statement }
- iteration_statement
{ WHILE conditional_expression DO statement; [...] | LOOP statement; [...] END LOOP | FOR for_loop_variable AS [ cursor_name CURSOR FOR ] cursor_specification DO statement; [...] END FOR | REPEAT statement; [...] UNTIL conditional_expression END REPEAT }
- local_declaration
DECLARE { variable_name [,...] data_type [ DEFAULT { literal | NULL } ] | condition_name CONDITION [ FOR SQLSTATE [VALUE] sqlstate_cod ] } ;
- cursor_declaration
DECLARE cursor_name [ [NO] SCROLL ] CURSOR [ WITHOUT RETURN | WITH RETURN [ONLY] [ TO { CALLER | CLIENT } ] ] [ FOR { cursor_specification [ FOR { READ ONLY | UPDATE } ] | statement_name } ] ;
- IF_statement
- <IF>を参照してください。
- CASE_statement
- CASE文のいずれかの形式。
- condition_handler
DECLARE { CONTINUE | EXIT } HANDLER FOR { { SQLSTATE [ VALUE ] sqlstate_code | condition_name } [,...] | { SQLEXCEPTION | SQLWARNING | NOT FOUND } [,...] } handler_action_statement ;
- cursor_specification
SELECT cursor_spec [,...] FROM { table_name [,...] | table_name { INNER | { LEFT | RIGHT | FULL } OUTER } JOIN table_name ON condition }
- cursor_spec
{ column_name [ [AS] alias_name ] | expression [AS] alias_name | * }
構文要素 | 指定内容 |
---|---|
operand_1とoperand_2 | 値式または算術式および列の式。 ストアド プロシージャのローカル変数、ステータス変数、INまたはINOUTパラメータ、リテラル、およびFORループ列の名前と相関名を値式内に指定することができます。 OUTパラメータと副クエリーは使えません。 operand_1とoperand_2のデータ型は、互いに互換性がなければなりません。 |
statement | 次のいずれか。
|
conditional_expression | THEN句内の1つ以上の文を実行するかどうかを決めるために使用されるブール条件。 ストアド プロシージャのローカル変数、ステータス変数、INまたはINOUTパラメータ、リテラル、およびFORループ列の名前と相関名をconditional_expression内に指定できます。 OUTパラメータと副クエリーは使えません。 条件リストにローカル変数、パラメータ、またはカーソル別名が含まれている場合は、INおよびNOT IN演算子を使用することはできません。 |
ANSI準拠
CASEは、ANSI/ISO SQL:2011に準拠しています。
許可
なし。
CASE文とCASE式との意味上の相違点
ストアド プロシージャのCASE文と通常の対話式SQLのCASE式の意味は異なります。例えば、式には値を保持できますが、文には値を保持できません。式は実行できませんが、文は実行できます。式は他の式と組み合わせることができますが、文は組み合わせることができません。<Teradata Vantage™ - SQL関数、式、および述部、B035-1145>の「CASE式」を参照してください。
CASE文の形式
形式 | 文の条件付き実行の基準 |
---|---|
単純 | オペランドが等価かどうか。 いくつかの値のうちのいずれかに式が一致するかどうかがテストされてから、結果に応じて分岐が行なわれます。 |
検索 | 条件式の評価。 |
CASE文を使う代わりに、IF-THEN-ELSEIF-ELSE文を使うこともできます。
一般的に、複数の条件または値を検査するのに望ましい文はCASE文のほうです。
単純なCASE文
この形式の条件付き文では、operand_1 (値式)がoperand_2 (値式)に等しいかどうかに応じて、最大限1つのWHEN句またはELSE句に関連したSQL制御文などのSQL文のリストを実行することができます。
WHEN句は、CASE文内に指定されている順序で評価されます。評価のプロセスは次のとおりです。
- 最初のWHEN句が評価されます。
- CASE句で指定されている値式(operand_1)がWHEN句内の値式(operand_2)に等しければ、そのWHEN句の文が実行されます。
- ストアド プロシージャ内の次の文に制御権が渡されます。値式が等しくない場合に、次のWHEN句が存在すればその句が評価されます。
- 後続のすべてのWHEN句は、ステップ1で説明した方法で評価されます。
- 評価するWHEN句がなくなった場合に、ELSE句が存在すればそれが新たな対象とされ、そのELSE句の文が実行されます。ストアド プロシージャ内の次の文に制御権が渡されます。
- ELSE句がない場合にCASE句内の値式が、WHEN句のどれにも一致しなければ、
- 実行時例外(”Case not found for CASE statement”, SQLSTATE=’20000’, SQLCODE = 7601)が発生します。
- CASE文の実行が終了します。
検索CASE文
この形式のCASE文は、WHEN句内の条件式の評価が真となると文のリストを実行します。最大限1つのWHEN句またはELSE句に関連した文を実行できます。
WHEN句は、CASE文内に指定されている順序で評価されます。評価のプロセスは次のとおりです。
- 最初のWHEN句が評価されます。
- WHEN句に指定されている条件式が真であれば、そのWHEN句の文が実行されます。
- ストアド プロシージャ内の次の文に制御権が移動します。
値式が真ではない場合、次のWHEN句が存在すればその句が評価されます。
- 後続のすべてのWHEN句は、ステップ1で説明した方法で評価されます。
- 評価するWHEN句がもうなくなった場合に、ELSE句が存在すればそれが新たな対象とされ、そのELSE句の文が実行されます。
ストアド プロシージャ内の次の文に制御権が移動します。
- ELSE句がない場合に、どのWHEN句内の条件式の評価も真とならなかったときは、
- 実行時例外(”Case not found for CASE statement”, SQLSTATE=’20000’, SQLCODE = 7601)が発生します。
- CASE文の実行が終了します。
CASE文での例外処理
WHEN句またはELSE句の後に続く文で例外が生じた場合に例外条件を処理するハンドラーがストアド プロシージャ内に備えられているときの処置行動は、IFまたはWHILE文内で発生した例外の場合と同じです。
CASE文の値式または条件式が例外を生じた場合に例外条件を処理するCONTINUEハンドラーがストアド プロシージャに備えられているときは、条件ハンドラーの処置が正常に完了した後で、END CASEの後に続く文に制御権が移動します。
例: 簡単なCASE
以下のストアド プロシージャには単純なCASE文が組み込まれています。
CREATE PROCEDURE spSample(IN pANo INTEGER, IN pName CHARACTER(30), OUT pStatus CHARACTER(50)) BEGIN DECLARE vNoOfAccts INTEGER DEFAULT 0; SELECT COUNT(*) INTO vNoOfAccts FROM Accounts; CASE vNoOfAccts WHEN 0 THEN INSERT INTO Accounts (pANo, pName); WHEN 1 THEN UPDATE Accounts SET aName = pName WHERE aNo = pANo; ELSE SET pStatus = 'Total ' || vNoOfAccts || 'customer accounts'; END CASE; END;
上記の例では、ローカル変数vNoAcctsの値に応じて、WHEN句の該当するSET文が実行されます。
vNoAcctsの値 | 一致する句 | 実行される文 |
---|---|---|
0 | 最初のWHEN句 | INSERT INTO Accounts (pANo, pName); |
1 | 2番目のWHEN句 | UPDATE Accounts SET aName = pName WHERE aNo = pANo; |
その他の数値 | ELSE句 | SET pStatus = 'Total ' || vNoAccts || ' customer accounts'; |
例: 検索CASE
以下のストアド プロシージャには検索CASE文が組み込まれています。
CREATE PROCEDURE spSample (IN pANo INTEGER, IN pName CHARACTER(30), OUT pStatus CHARACTER(50)) BEGIN DECLARE vNoAccts INTEGER DEFAULT 0; SELECT COUNT(*) INTO vNoAccts FROM Accounts; CASE WHEN vNoAccts = 0 THEN INSERT INTO Accounts (pANo, pName); WHEN vNoAccts = 1 THEN UPDATE Accounts SET aName = pName WHERE aNo = pANo; WHEN vNoAccts > 1 THEN SET pStatus = 'Total ' || vNoAccts || ' customer accounts'; END CASE; END;
上記の例では、ローカル変数vNoAcctsの値に応じて、WHEN句の該当するSET文が実行されます。
vNoAcctsの値 | 真となる条件式を持つ句 | 実行される文 |
---|---|---|
0 | 最初のWHEN句 | INSERT INTO Accounts (pANo, pName); |
1 | 2番目のWHEN句 | UPDATE Accounts SET aName = pName WHERE aNo = pANo; |
>1 | 3番目のWHEN句 | SET pStatus = ’Total’ || vNoAccts || ’customer accounts’; |
vNoAcctsの値がNULLの場合にELSE句がないと、ストアド プロシージャで実行時例外(”Case not found for CASE statement”, SQLSTATE=’20000’, SQLCODE = 7601)が発生します。ただし、この例の値設定のようにvNoAcctsをNULLに設定することはできません。
例: 検索CASEでのFORループ別名の使用
以下の例は、検索CASE文の条件式でFORループ別名を使用する様子を示しています。
CREATE PROCEDURE spSample() Label1:BEGIN FOR RowPointer AS c_employee CURSOR FOR SELECT DeptNo AS c_DeptNo, employeeid AS c_empid FROM Employee DO CASE WHEN RowPointer.c_DeptNo > 10 THEN INSERT INTO Dept VALUES (RowPointer.c_DeptNo, RowPointer.c_empid) ; WHEN RowPointer.c_DeptNo <= 10 THEN UPDATE Employee SET DeptNo = RowPointer.c_DeptNo + 10 ; INSERT INTO Dept VALUES (RowPointer.c_DeptNo, RowPointer.c_empid) END CASE; END FOR; END Label1;
関連トピック
- 単純なCASE文については、ITERATEを参照してください。
- 検索CASE文ついては、ITERATEを参照してください。
- IF-THEN-ELSEIF-ELSE文については、IFを参照してください。
- 例外条件に関する例とルールについては、ストアド プロシージャのDDL文を参照してください。