[DB][DB2] SQLCODE -818 SQLSTATE 51003

整合性トークンの不一致
が原因


そもそもの話

■パッケージ
一群の情報で
静的SQLステートメントのコンパイルを制御し
動的SQLステートメントのコンパイルを部分的に制御して
そのスコープ内で発行されたSQL要求の実行に影響するものを言う。
パッケージの情報には
コンパイル時に使用する最適化レベル
実行時に適格カーソルにブロッキングを使用するかどうか
実行時にどの程度のへ黄処理を使用するか
等の項目がある。
これらの情報は全て
syscat.packagesカタログ・テーブルにパッケージを表すエントリとして格納される。
静的SQLステートメントの場合
1つのステートメントに対して
パッケージがそれ自体に関連付けされた1つのセクションを持つ。
セクションは
SQLステートメントのDB2 UDBで実行可能なバージョンである。
パッケージは
DB2 UDBによる基本的な認証制御ポイントとして使用される。
パッケージの実行または保守をある人に許可する場合には
必要に応じてパッケージに対する特権の付与と取り消しを行える。
この情報は
syscat.packageauthに反映される。

■セクション・エントリー
アプリに静的SQLと動的SQLがあるのと同じように
パッケージにも静的なものと動的なものがある。
個々のSQLステートメントのコンテキストを明確にし
且つ要求毎にこの情報を提供しなくても済むように
DB2 UDBはパッケージを
セクション・エントリー
と呼ばれる小さなユニットに分割する。
セクション・エントリーには
SQLステートメント自体についての情報と
SQLステートメントがアプリ内部においてどのようなcontextで存在するか
という情報が格納される。
例えば
カーソルの場合
セクション・エントリーには
カーソルの名前
WITH HOLDカーソルであるかどうか
カーソルが定義されたFOR UPDATEかどうか
の情報が格納される。
実行時には
セクション・エントリーが
それ自体に関連付けられたセクションの現在のステータスに関する情報を格納する。
動的SQLステートメントの場合には、
パッケージと共に保存されるセクション・エントリーは空で
単にブックマークの役割をするだけ。

アプリにある固有のPREPARE、DECLARE CURSORS
または静的SQLの個々に対して
固有のセクション・エントリーが1つ存在する。
また
EXECUTE IMMEDIATE要求がアプリで見つかると
固有のエントリーが1つ追加される。
このエントリーは
同じアプリ内の他の全てのEXECUTE IMMEDIATE要求により共有される。

DB2 UDBによるSQL要求の処理は
個々の要求が
DB2 UDB内の特定のパッケージ内の特定のセクション・エントリーにマッピングされる。

■パッケージの存在理由
同じパッケージ内であれば
DB2 UDBが静的SQLと動的SQLがどのように混在していても対応できることにある。
アプリの開発時に使用されるSQLは
純粋な静的SQL
静的SQLと動的SQLの混在
純粋な動的SQL
のいずれかがあり得る。
パッケージを使用することにより
DB2 UDB内部でこうしたアプローチの全てに対応することが出来る。
パッケージを使用することには
組み込みSQLアプリを開発する時に
開発者
アプリ開発に使用されているのと同じモジュール式プログラミング手法を使えるという利点もある。
開発者は
アプリの異なる部分からのSQL要求について
それぞれに異なるパッケージ
つまり
異なるSQLコンテキストを対応させられる。
パッケージの存在は
アプリの認証制御をより厳密にするのにも役立つ。
パッケージへの認証を使って
どのユーザに
アプリの全部または一部の実行を許可するかを制御できる。
また
静的SQLステートメントを使うことで
パッケージ・バインダのアクセス権限を
一時的に利用することでは通常実行できない要求をユーザが実行できる。
ただし
あくまでもそのパッケージのコンテキストの範囲内に限る。

■セクション
SQLステートメントの実行可能な実体である。
セクションには
指定された結果を生成するために
DB2 UDBが必要とするロジック・アクセス・メソッドとデータ・アクセス・メソッド
が格納されている。
セクションを構成するのは
データ・アクセスの実行順序と
最適操作を説明した一連の演算子と
関連付けされたオペランド
である。
演算子は
データにアクセスし操作する低レベルDB2 UDB関数に対応してる。
オペランドは
行やテーブル、インデックス等のデータ要素と制御構造を表す。
セクションは
SQLステートメントのコンパイルの最終結果である。
SQLコンパイラは
SQLステートメントを満たすのに最も効率的なアプローチを判断して
そのプランを実装するセクションを生成する。
結果
セクションがステートメント実行時に最高の派フォーますを確実に得られる。

■パッケージの作成プロセス
①プリコンパイル
 プリコンパイルの最終結果は
 ソース・ファイルの変更バージョンと
 ソース・ファイルから抽出されたSQLステートメントと
 変数
 である。
②バインディング
 アプリケーション・ソース・ファイルから
 抽出されたSQL情報が分析され
 DB2 UDBカタログ・テーブルに書き込まれるステップである。
 パッケージと
 セクション・エントリーと
 ホスト変数に関する情報は
 SYSCAT.PACKAGESカタログ・テーブルに直接書き込まれる。
 静的SQLステートメントは
 それに対応するセクションを生成するためにSQLコンパイラーに通され
 そのあとSYSCAT.STATEMENTSカタログ・テーブルに書き込まれる。
 静的SQLステートメントに対して生成されたセクションは
 SYSIBM.SYSSECTIONテーブルに書き込まれる。
 成功したバインドの最終結果が、DB2 UDBパッケージである。

変更されたアプリケーション・ソース・ファイルは
コンパイルして
実行可能ファイルにリンクできる。
あるSQLステートメントに対応する関数呼び出しが実行されると
その関数呼び出しの含まれるアプリケーション部分に対応する
特定のパッケージ中の特定のセクション・エントリーに対して
特定のアクションを実行するようDB2 UDBが要求される。
アプリケーション内部でコンテキストの識別に使用されるのは
セクション・エントリー番号のみであるため
変更後のソース・ファイルとパッケージは緊密にリンクされる。
したがって、
参照するコンテキストが常に同じでないとダメ。
このために、
変更後のソース・ファイルには
整合性トークン(タイムスタンプ)
が埋め込まれ
DB2 UDB内部のパッケージ情報にも同じ値が格納される。
アプリケーションからのすべての要求に
この整合性トークンが付属する。
着信した値とカタログ・テーブルの値が比較され
相違がある場合
ロード・モジュール・タイムスタンプと整合性トークンが異なっていれば
「タイムスタンプ」(SQLCODE -818)エラーになる。

アプリケーション・ソース・ファイルに変更が必要なときは
整合性トークンがロード・モジュールとDB2セクションで同一となるように
ファイルを再度プリコンパイルし
バインドを使ってパッケージ情報を再作成する必要がある。
単純なSQLプログラミング以外の変更を変更済みソース・ファイルで行えるが
次回のプリコンパイル実行時に
変更済みソース・ファイルが上書きされて変更が失われるため
推奨されない。


ref:
Paul Bird, DB2 Universal Databaseの内側:SQLステートメントの寿命と時間, IBM, 2004/11/26
http://www.ibm.com/developerworks/jp/data/library/dataserver/techdoc/sqllife.html

tag : DB2 SQLCODE

2009-10-06 23:40 : 開発 : コメント : 0 : トラックバック : 0 :
コメントの投稿
非公開コメント

« next  ホーム  prev »

search

ad



counter


tag cloud

category cloud