16.20 - 例: INOUTパラメータでのメモリ オーバーフロー エラーの防止 - Teradata Database - Teradata Vantage NewSQL Engine

Teradata Vantage™ SQLデータ操作言語

Product
Teradata Database
Teradata Vantage NewSQL Engine
Release Number
16.20
Release Date
2019年3月
Content Type
プログラミング リファレンス
Publication ID
B035-1146-162K-JPN
Language
日本語 (日本)

INOUTパラメータに返される出力値のサイズが、システムがそのパラメータの入力値に割り当てたメモリより大きい場合、CALLリクエストは失敗し、要求元にオーバーフロー エラーが返されます。入力/出力パラメータを指定するためのルールを参照してください。

次の例はこれを表わしています。INOUTパラメータを使用してmyintzという名前のSQLストアド プロシージャを作成したとします。

例1:

     BTEQ -- Enter your DBC/SQL request or BTEQ command:
     CALL myintz(32767);

32,767に適合する最も小さいデータ型はSMALLINTなので、システムはパラメータに2バイトを割り当て、そのデータ型をSMALLINTに設定します。プロシージャの作成時にINOUTパラメータに割り当てられたデータ型は考慮されません。このCALLが32,768以上の値を返した場合、システムはこの結果をSMALLINT変数のメモリ オーバーフローとして処理し、エラーを返します。

例2:

     BTEQ -- Enter your DBC/SQL request or BTEQ command:
     CALL myintz(CAST ('32767' AS INTEGER));

この場合、明示的なキャストによってシステムは入力値がINTEGER値であると認識するので、システムはそのパラメータに4バイトを割り当てます。したがって、CALLが32,768をINOUTパラメータに返したとき、この値はINTEGERの範囲内なので、リクエストは正常に完了し、メモリ割り当てエラーは発生しません。

     CALL myintz(cast ('32767' AS INTEGER));
      *** Procedure has been executed.
      *** Total elapsed time was 42 seconds.
         '32767'
     -----------
           32768

同様に、プロシージャを呼び出すクライアント プログラム コードでパラメータのデータ型を明示的に定義し、その指定されたデータ型が入力値のデフォルト型よりも大きい出力値を格納できる場合は、リクエストは正常に完了します。

次の例では、Javaクライアント アプリケーションから呼び出したmyint2という名前のJava外部ストアド プロシージャを使用しています。基本原則は、外部ストアド プロシージャだけでなく、すべてのストアド プロシージャに適用されます。どちらの場合もINOUTパラメータに返される値は32,768であることを想定しています。

例3:

次のようにJavaの外部ストアド プロシージャmyint2を呼び出すとします。

     stmt.executeUpdate("call myint2(32767);");

この呼び出しの結果、メモリ オーバーフロー エラーが発生します。これは、最初の例で説明した状況と同じです。

例4:

Javaクライアント プログラムが次のようにJava外部ストアド プロシージャを呼び出すとします。

      StringBuffer prepCall = new StringBuffer("CALL myint2(?);");
      System.out.println(prepCall.toString());

      CallableStatement cStmt = con.prepareCall(prepCall.toString());

      cStmt.setInt(1, integerVar[0]);
      cStmt.registerOutParameter(1, Types.INTEGER);

      // Making a procedure call
      System.out.println("Before executeUpdate()...");

      cStmt.executeUpdate();
      System.out.println("Value after executeUpdate(): "
                         + cStmt.getInt(1));

      integerVar[0] = cStmt.getInt(1);

呼出し側のJavaプログラムはINOUTパラメータを明示的にINTEGERデータ型として定義しているので、システムはINTEGER入力値に適切なメモリを割り当てることができます。このため、このCALLは成功します。その結果、返される値はINTEGER型に割り当てられたメモリに収まるのでオーバーフロー エラーは発生しません。