CASE - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQLストアド プロシージャおよび埋め込みSQL

Product
Advanced SQL Engine
Teradata Database
Release Number
17.05
17.00
Published
2020年6月
Language
日本語
Last Update
2021-03-30
dita:mapPath
ja-JP/xqq1557098602407.ditamap
dita:ditavalPath
ja-JP/xqq1557098602407.ditaval
dita:id
B035-1148
Product Category
Software
Teradata Vantage

目的

指定された条件式または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_1operand_2 値式または算術式および列の式。

ストアド プロシージャのローカル変数、ステータス変数、INまたはINOUTパラメータ、リテラル、およびFORループ列の名前と相関名を値式内に指定することができます。

OUTパラメータと副クエリーは使えません。

operand_1operand_2のデータ型は、互いに互換性がなければなりません。

statement 次のいずれか。
  • ストアド プロシージャで使用できるDML、DDL、またはDCL文。これには、動的SQL文が含まれます。
  • 制御文、BEGIN…ENDを含む。
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文内に指定されている順序で評価されます。評価のプロセスは次のとおりです。

  1. 最初のWHEN句が評価されます。
    • CASE句で指定されている値式(operand_1)がWHEN句内の値式(operand_2)に等しければ、そのWHEN句の文が実行されます。
    • ストアド プロシージャ内の次の文に制御権が渡されます。値式が等しくない場合に、次のWHEN句が存在すればその句が評価されます。
  2. 後続のすべてのWHEN句は、ステップ1で説明した方法で評価されます。
  3. 評価するWHEN句がなくなった場合に、ELSE句が存在すればそれが新たな対象とされ、そのELSE句の文が実行されます。ストアド プロシージャ内の次の文に制御権が渡されます。
  4. ELSE句がない場合にCASE句内の値式が、WHEN句のどれにも一致しなければ、
  • 実行時例外(”Case not found for CASE statement”, SQLSTATE=’20000’, SQLCODE = 7601)が発生します。
  • CASE文の実行が終了します。

検索CASE文

この形式のCASE文は、WHEN句内の条件式の評価が真となると文のリストを実行します。最大限1つのWHEN句またはELSE句に関連した文を実行できます。

WHEN句は、CASE文内に指定されている順序で評価されます。評価のプロセスは次のとおりです。

  1. 最初のWHEN句が評価されます。
    • WHEN句に指定されている条件式が真であれば、そのWHEN句の文が実行されます。
    • ストアド プロシージャ内の次の文に制御権が移動します。

    値式が真ではない場合、次のWHEN句が存在すればその句が評価されます。

  2. 後続のすべてのWHEN句は、ステップ1で説明した方法で評価されます。
  3. 評価するWHEN句がもうなくなった場合に、ELSE句が存在すればそれが新たな対象とされ、そのELSE句の文が実行されます。

    ストアド プロシージャ内の次の文に制御権が移動します。

  4. 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文を参照してください。