メニューボタン
IBMi海外記事2017.02.23

RPG と BLOB

Michael Sansoterra 著

こんにちは、マイク: SELECT/INTO 組み込み SQL ステートメントを BLOB(20K) 列を含む表にアクセスする RPG プログラムで使いたいと考えています。INTO ターゲットは、表に基づく外部定義データ構造です。ただし、表から BLOB 列を削除しない限りコンパイラー・エラーが発生します。一体どうなっているのでしょうか?
--Four Hundred Guru 読者

RPG には BLOB と同等のネイティブ・データ型 (ついでに言えば、その他の大規模オブジェクト型 CLOB/DBCLOB) がないことが問題です。この理由として、大規模オブジェクト型のサイズは RPG の現在の最大可変サイズである 16MB よりはるかに大きく、最大 2GB であるためです。

BLOB を含む以下の表定義を考えてみてください。

技術情報code01

RPG プログラム内には、外部記述データ構造 dsTest (上記の表を参照する) および以下の組み込み SQL ステートメントがあります。

技術情報code02

BLOB を含む外部記述データ構造を使用している場合、RPG コンパイラーは以下のような見苦しい警告を発します。

技術情報code03

(RNF7575 データ構造には、データ型が未知のフィールドがあります。このフィールドは無視されます。)

この警告は RPG コンパイラーは BLOB データ型列をどう処理してよいかわからないため、無視することを示しています。コンパイラー・リストのデータ構造定義には MY_IMAGE はありません。つまり、組み込み SQL ステートメントは 3 つの列の値を取得しようとしていますが、外部記述データ構造はストレージ用に 2 つの値のみ提供します。データ構造は SELECT ステートメントのフィールド・リストと一致ないため、RPG コンパイラーは表の定義に応じて、データ型の不一致などに関連した、任意の数のエラーを生成する場合があります。

RPG プログラムで BLOB データにアクセスする必要がない場合、この回避方法の 1 つとしては、単にデータ構造と SELECT INTO を手作業でコーディングし、大規模オブジェクト・データ型列を省略します。ただし、表に多数の列がある場合、このやり方は魅力的な方法ではありません。

BLOB 列を省略する表でビューを作成し、外部記述データ構造でビューを参照するというオプションもあります。さらに、開発者が自分の外部定義データ構造で適切に作業できるよう、BLOB を自分の表に移動させるというオプションもあります。

RPG プログラムで BLOB データが必要な場合は、データ構造を手動で定義しなければなりません。この例は 20K 長の BLOB を使用しているだけなので、(特殊 SQLTYPE を使用して定義された) 1 つの RPG 変数に読み込むことができます。

技術情報code04

正確に解釈すると、上記のような SQLTYPE を使用する必要はなく、実際コンパイラーは MY_IMAGE を 20480A VARYING CCSID(65535) として定義するだけです。

BLOB のサイズが 16MB より大きな場合、「ロケーター」変数を使用して BLOB データを参照する必要があります。ロケーター変数は DB2 の巨大なメモリー管理内にある位置への単なるポインターです。ここでは DB2 が大規模オブジェクト・データを追跡し、RPG プログラムは追跡していません。

技術情報code05

トランザクション排他設定レベルが *NONE 以外の値に設定されていない場合は、ロケーターの使用は許可されません。SET OPTION ステートメントはこの設定を変更する手段の 1 つです。

技術情報code06

DB2 は、 RPG プログラムに代わって大規模オブジェクト・データを「収容」しているため、BLOB のすべての操作は組み込み SQL を使用して行う必要があります。

技術情報code07

結論として、 RPG プログラムが最大サイズ 2GB の大規模オブジェクト・データ列を作業するのは魅力的な方法ではありません。

あわせて読みたい記事

PAGE TOP