アプリケーション開発の手引き


DB2 アプリケーションのコーディングの概説

DB2 アプリケーション・プログラムは、以下の部分で構成されています。

  1. 変数の宣言および初期化
  2. データベースへの接続
  3. 1 つ以上のトランザクション の実行
  4. データベースからの切断
  5. プログラムの終了

トランザクション とはデータベース操作の集合で、データベースにコミットされる前に正常に終了しなければなりません。組み込み SQL を使用した場合、トランザクションは暗黙に開始され、アプリケーションが COMMIT または ROLLBACK ステートメントのいずれかを実行すると終了します。トランザクションの例としては、顧客の預金の入力、および差し引き残高の更新などがあります。

一定の SQL ステートメントは、ホスト言語から組み込み SQL への変換を処理するために、プログラムの始めと終わりに使用しなければなりません。

プログラムの先頭には、以下のものが必要です。

どのプログラムの本体にも、データにアクセスして管理する SQL ステートメントが含まれています。このようなステートメントが集まってトランザクションを構成します。トランザクションには以下のステートメントが含まれていなければなりません。

アプリケーション・プログラムの終わりには、通常、次のような働きを持つ SQL ステートメントを置きます。

変数の宣言および初期化

DB2 アプリケーションをコーディングするには、まず以下を宣言する必要があります。

データベース・マネージャーと対話する変数の宣言

データベース・マネージャーと対話する変数はすべて、 SQL 宣言セクションで宣言しなければなりません。 SQL 宣言セクションは、以下の構造でコーディングする必要があります。

  1. SQL ステートメント BEGIN DECLARE SECTION
  2. 1 つ以上の変数宣言のグループ
  3. SQL ステートメント END DECLARE SECTION

SQL 宣言セクションで宣言されたホスト・プログラム変数はホスト変数 と呼ばれます。ホスト変数は SQL ステートメント内のホスト変数 参照で使用できます。 ホスト変数 は、 SQL 解説書 の構文図で使用される 1 つのタグです。 1 つのプログラムに複数の SQL 宣言セクションが含まれる場合もあります。

各ホスト変数の属性は、その変数が SQL ステートメントにおいてどのように使用されるかにより異なります。たとえば、DB2 表からデータを受け取る変数、または DB2 表にデータを保管する変数には、アクセスする列と互換性のあるデータ・タイプ属性と長さ属性がなければなりません。各変数のデータ・タイプを決定するには、 データ・タイプで説明する DB2 データ・タイプをよく理解していなければなりません。

SQL オブジェクトを表す変数の宣言

DB2 バージョン 7 では、表、別名、視点、および相関の名前の長さは、最高で 128 バイトです。列名の長さは、最高で 30 バイトです。 DB2 バージョン 7 では、スキーマ名の長さは、最高で 30 バイトです。今後のリリースでは、列名および SQL オブジェクトの他の識別子の長さが最高 128 バイトまで増える可能性があります。 SQL オブジェクトを表す変数を、128 バイトよりも短い長さで宣言する場合、 SQL オブジェクト識別子の長さが今後増えると、アプリケーションの安定度に影響が及ぶ可能性があります。たとえば、 C++ アプリケーションでスキーマ名を保持するために変数 char[9]schema_name を宣言する場合、アプリケーションは、DB2 バージョン 6 で許可されているスキーマ名 (最大長が 8 バイト) に対しては正しく機能します。

   char[9] schema_name; /* holds null-delimited schema name of up to 8 bytes;
    works for DB2 Version 6, but may truncate schema names in future releases */

しかし、データベースを DB2 バージョン 7 に移行し、そのバージョンがスキーマ名の最大長として 30 バイトを受け入れている場合、アプリケーションは、スキーマ名 LONGSCHEMA1LONGSCHEMA2 を区別することができません。データベース・マネージャーは LONGSCHE の限度である 8 バイトでスキーマ名を切り捨て、アプリケーション内のステートメントのうち、スキーマ名を区別しなければならないものはすべて失敗します。アプリケーションを長期間使用するためには、次のように、スキーマ名変数を 128 バイトの長さで宣言してください。

    char[129] schema_name; /* holds null-delimited schema name of up to 128 bytes 
                              good for DB2 Version 7 and beyond */

アプリケーションの操作を将来的にさらに向上させるには、アプリケーションで SQL オブジェクト名を表す変数を 128 バイトの長さで宣言することを考慮してください。互換性を向上させることの利点と、変数名を長くすることで必要になるシステム資源とを、比較検討する必要があります。

このコーディング練習の使用を簡単なものとし、 C/C++ アプリケーション・コードをわかりやすくするために、 C マクロ展開を使用して、SQL オブジェクト識別子の長さを宣言することを考慮してください。インクルード・ファイル sql.h は、SQL_MAX_IDENT が 128 になるように宣言しているため、 SQL_MAX_IDENT マクロを使用すれば、SQL オブジェクト識別子を簡単に宣言することができます。以下に例を示します。

#include <sql.h>
    char[SQL_MAX_IDENT+1] schema_name;
    char[SQL_MAX_IDENT+1] table_name;
    char[SQL_MAX_IDENT+1] employee_column;
    char[SQL_MAX_IDENT+1] manager_column;

C マクロ展開の詳細については、C マクロ展開を参照してください。

ホスト変数と SQL ステートメントの関連付け

ホスト変数を使用して、データベース・マネージャーからデータを受け取ったり、ホスト・プログラムからデータベース・マネージャーにデータを転送したりすることができます。データベース・マネージャーからデータを受け取るホスト変数は出力ホスト変数、ホスト・プログラムからデータベース・マネージャーにデータを転送するホスト変数は入力ホスト変数 です。

次の SELECT INTO ステートメントを例にとります。

     SELECT HIREDATE, EDLEVEL
       INTO :hdate, :lvl
       FROM EMPLOYEE
       WHERE EMPNO = :idno

このステートメントには、hdatelvl の 2 つの出力ホスト変数と、入力ホスト変数 idno が含まれています。データベース・マネージャーは、ホスト変数 idno に保管されているデータを使用して、 EMPLOYEE 表から検索する行の EMPNO を決めます。検索基準を満たす行が見つかると、 hdatelvl はそれぞれ HIREDATE 列と EDLEVEL 列に保管されたデータを受け取ります。上記のステートメントは、EMPLOYEE 表の列を使用したホスト・プログラムとデータベース・マネージャー間の対話の例です。

表の各列には、CREATE TABLE ステートメントで定義されたデータ・タイプが割り当てられます。このデータ・タイプをホスト言語データ・タイプに関連付ける必要があります。ホスト言語データ・タイプは、本書の各言語に関する章のサポートされる SQL データ・タイプ の節で定義されています。たとえば、INTEGER データ・タイプは 32 ビットの符号付き整数です。これは、各ホスト言語による以下のようなデータ記述項目に対応しています。

C/C++:
sqlint32 variable_name;

Java:
int variable_name;

COBOL:
01 variable-name PICTURE S9(9) COMPUTATIONAL-5.

FORTRAN:
INTEGER*4 variable_name

サポートされる SQL データ・タイプのリストと、それに対応するホスト言語データ・タイプについては、以下を参照してください。

ある列に使用するホスト変数の定義方法を正確に決定するには、その列の SQL データ・タイプを調べなければなりません。データベース内に作成された表すべてに関する情報を含んだ視点の集合である、システム・カタログを照会してこれを調べてください。 SQL 解説書 では、システム・カタログについて説明しています。

データ・タイプを決定したら、それぞれのホスト言語の章にある変換表を参照して、適切な宣言をコーディングできます。宣言生成プログラム・ユーティリティー (db2dclgn) を使用して、データベース内の指定された表に、適切な宣言を生成することもできます。 db2dclgn の詳細については、 宣言生成プログラム - db2dclgn およびコマンド解説書 を参照してください。

表 4 は、サポートされるホスト言語による宣言の例を示しています。 REXX アプリケーションは、 LOB ロケーターおよびファイル参照変数以外のホスト変数を宣言する必要はないことに注意してください。他のホスト変数のデータ・タイプとサイズは、変数の内容に基づいて実行時に決定されます。

表 4 には、 BEGIN DECLARE SECTION および END DECLARE SECTION ステートメントも示されています。 SQL ステートメントの区切り文字と各言語の区切り文字の違いに気を付けてください。これらのステートメントの配置、連結、および区切りの正しい規則については、本書の各言語別の章を参照してください。

エラーおよび警告の処理

SQL 連絡域 (SQLCA) については、この章で後ほど詳しく説明します。この節では概要を説明します。 SQLCA を宣言するには、プログラムに INCLUDE SQLCA ステートメントをコーディングします。

各言語でのステートメントを以下に示します。 C または C++ アプリケーションの場合、

     EXEC SQL INCLUDE SQLCA;

Java アプリケーションの場合、Java では明示的に SQLCA を使用することはしません。その代わりに、SQLException インスタンス・メソッドを使用して、 SQLSTATE および SQLCODE 値を入手します。詳細については、Java の SQLSTATE および SQLCODE 値を参照してください。

COBOL アプリケーションの場合、

     EXEC SQL INCLUDE SQLCA END-EXEC.

FORTRAN アプリケーションの場合、

     EXEC SQL INCLUDE SQLCA

プログラムを前処理する際に、データベース・マネージャーは INCLUDE SQLCA ステートメントの代わりにホスト言語変数宣言を挿入します。システムは、警告標識、エラー・コード、および診断情報の変数を使用してプログラムと連絡します。

各 SQL ステートメントを実行すると、システムは SQLCODE および SQLSTATE の両方の戻りコードを戻します。 SQLCODE はステートメントの実行を要約した整数値で、 SQLSTATE は IBM のリレーショナル・データベース製品に共通のエラー・コードを示す文字フィールドです。 SQLSTATE は ISO/ANS SQL92 標準、および FIPS 127-2 標準にも準拠しています。
注: FIPS 127-2 とは、Federal Information Processing Standards Publication 127-2 for Database Language SQL のことです。 ISO/ANS SQL92 とは、American National Standard Database Language SQL X3.135-1992 および International Standard ISO/IEC 9075:1992, Database Language SQL を指します。

0 未満の SQLCODE は、エラーが発生してステートメントが処理されなかったことを示していることに注意してください。 1 以上の SQLCODE は、警告が出されたものの、ステートメントの処理は継続していることを示します。 SQLCODE と SQLSTATE のエラー状態のリストについては、 メッセージ解説書 を参照してください。

各 SQL ステートメントを実行した後のエラー・チェックをシステムで制御したい場合には、 WHENEVER ステートメントを使用します。
注:Java Embedded SQL (SQLJ) アプリケーションは、WHENEVER ステートメントを使用できません。 Java の SQLSTATE および SQLCODE 値で説明されている SQLException メソッドを使用して、 SQL ステートメントが戻したエラーを処理してください。

次の WHENEVER ステートメントは、負の SQLCODE が戻された場合にシステムが行う動作を指定します。

     WHENEVER SQLERROR GO TO errchk

つまり、SQL エラー・コードが発生すると、プログラムの制御が errchk などのラベルの後に続くコードに移ります。このコードには、SQLCA のエラー標識を分析するロジックを組み込んでおきます。 ERRCHK 定義に従って、次の順次プログラム命令を実行したり、特殊関数を実行したり、ほとんどの状況で現行のトランザクション をロールバックしてプログラムを終了するなどの処置がとられます。トランザクションの詳細については トランザクションのコーディング、アプリケーション・プログラムのエラー・チェックの詳細については 診断処理と SQLCA 構造を参照してください。

WHENEVER SQLERROR ステートメントを使用するときには十分注意してください。アプリケーションのエラー処理コードに SQL ステートメントがあり、それらで元のエラーを処理している間にエラーが発生する場合、アプリケーションで無限のループが実行される可能性があります。この状態での障害追及は困難です。 WHENEVER SQLERROR の宛先を示す最初のステートメントは、必ず WHENEVER SQLERROR CONTINUE にしてください。このステートメントはエラー・ハンドラーをリセットします。このステートメントの後であれば、安心して SQL ステートメントを使用できます。

C または C++ 言語で作成された DB2 アプリケーションの場合、アプリケーションが複数のソース・ファイルで構成されているなら、 SQLCA の多重定義を回避するため、 EXEC SQL INCLUDE SQLCA ステートメントを組み込むのはその中の 1 つのファイルだけにしてください。それ以外のソース・ファイルには、次の行を組み込みます。

     #include "sqlca.h"
     extern struct sqlca sqlca;

ご使用のアプリケーションが、 ISO/ANS SQL92 または FIPS 127-2 標準に準拠する必要がある場合は、上記のステートメントや INCLUDE SQLCA ステートメントを使用しないでください。 ISO/ANS SQL92 および FIPS 127-2 標準の詳細については、 FIPS 127-2 および ISO/ANS SQL92 の定義を参照してください。上記のステートメントのコーディングに代わる方法については、以下を参照してください。

その他の非実行ステートメントの使用

一般に、その他の非実行 SQL ステートメントもプログラムのセットアップ部分に含まれます。 SQL 解説書 および本書のこの後の章では、非実行ステートメントについて説明しています。非実行ステートメントの例を以下に示します。

データベース・サーバーへの接続

実行可能な SQL ステートメントを実行するには、その前に宛先データベース・サーバーへの接続を確立しておかなければなりません。この接続により、プログラムを実行しているユーザーの許可 ID、およびプログラムが稼働しているデータベース・サーバーの名前を識別します。一般に、アプリケーション・プロセスが一度に接続できるデータベース・サーバーは 1 つだけです。このサーバーを現行サーバー といいます。しかし、複数サイト更新環境内であれば、複数のデータベース・サーバーに接続することができます。この場合、ただ 1 つのサーバーだけが現行サーバーになります。複数サイト更新の詳細については、複数サイト更新を参照してください。

プログラムは、以下のいずれかの方法でデータベース・サーバーと接続を確立することができます。

接続状況および CONNECT ステートメントの使用方法については、 SQL 解説書 を参照してください。初期化時に、アプリケーション・リクエスターが省略時のデータベース・サーバーを確立します。暗黙接続が使用可能になっている場合は、初期化後に開始されるアプリケーション・プロセスにより、省略時のデータベース・サーバーへの接続が暗黙的に行われます。アプリケーション・プログラムが最初に実行する SQL ステートメントを CONNECT ステートメントとして使用することは、良い方法です。そうすれば、省略時のデータベースに対して不用意に SQL ステートメントを実行しないようにすることができます。

接続が確立されてから、プログラムから次のような SQL ステートメントを発行できます。

接続は、CONNECT RESET、CONNECT TO、または DISCONNECT ステートメントが発行されるまで設定されたままとなります。複数サイト更新環境では、接続は DB2 RELEASE およびそれに続いて DB2 COMMIT が発行されるまで続きます。複数サイト更新 (複数サイト更新参照) を使用している場合、 CONNECT TO ステートメントでは接続は終了しません。

トランザクションのコーディング

トランザクションは一連の SQL ステートメント (途中にホスト言語コードが割り込む) からなり、データベース・マネージャーはこれらのステートメントを一まとまりとして扱います。トランザクションの代わりに、同じ意味として作業単位 という用語がよく使われます。

トランザクション・レベルでのデータの一貫性を確保するために、システムは、トランザクション内の操作がすべて 完了するか、 まったく行われなかった かのいずれかの状態を保ちます。たとえば、ある口座から現金を引き出し、それを別の口座に入れるとします。この 2 つの更新が単一のトランザクションで行われる場合、これらの処理中にシステム障害が発生すると、システムの再起動時にそのデータはトランザクションが開始される前の状態に自動的に復元されます。プログラム・エラーが発生した場合は、エラーになったステートメントによる変更がすべて元の状態に復元されます。トランザクション内でエラーになったステートメントの実行前に行われた作業は、特にロールバックを行わなければ復元されません。

単一のアプリケーション・プログラム内の 1 つまたは複数のトランザクションをコード化することができます。さらに単一のトランザクション内から複数のデータベースにアクセスすることが可能です。複数のデータベースにアクセスするトランザクションは、複数サイト更新と呼ばれます。これらのトピックについては、 リモート作業単位および複数サイト更新を参照してください。

トランザクションの開始

トランザクションは先頭の実行可能 SQL ステートメントにより暗黙的に開始され、 COMMIT ステートメントか ROLLBACK ステートメント、またはプログラムの末尾で終了します。

一方、以下の 6 つのステートメントは実行可能ステートメントではないため、トランザクションを開始しません

     BEGIN DECLARE SECTION          INCLUDE SQLCA
     END DECLARE SECTION            INCLUDE SQLDA
     DECLARE CURSOR                 WHENEVER

実行可能 SQL ステートメントは常にトランザクション内に現われます。トランザクションが終了した後でプログラムに実行可能 SQL ステートメントが含まれている場合は、新しいトランザクションを自動的に開始します。

トランザクションの終了

トランザクションを終了するには、次のいずれかを行ってください。

COMMIT ステートメントの使用

このステートメントは、現行トランザクションを終了します。現行トランザクションで行われたデータベースの変更が、他の処理でも認識されるようになります。

アプリケーションの要件に応じて、できるだけ早く変更がコミットされるようにしてください。特に、端末からの入力を待機している間、コミットされていない変更を保留することがないようなプログラムを作成してください。それが原因で、データベース資源が長い間保留にされないようにするためです。これらの資源を保留してしまうと、同じくこれを必要とする他のアプリケーションが実行できなくなります。

COMMIT ステートメントは、ホスト変数の内容には影響を与えません。

アプリケーション・プログラムが、終了処理の前にすべてのトランザクションを明示的に終わらせるようにしてください。トランザクションを明示的に終わらせないと、 DB2 はトランザクションが保留されていた間のすべての変更を、プログラムが正常に終了した時点で自動的にコミットします。ただし、Windows 32 ビットのオペレーティング・システムではコミットは行われません。 DB2 は以下の条件のときに、変更をロールバックします。

Windows 32 ビットのオペレーティング・システムの場合は、トランザクションを明示的にコミットしないなら、データベース・マネージャーがその変更を必ずロールバックするようにします。

プログラムの終了については、プログラムの終了および診断処理と SQLCA 構造を参照してください。

ROLLBACK ステートメントの使用

このステートメントは現行トランザクションを終了して、トランザクションが開始される前の状態にデータを復元します。

ROLLBACK ステートメントは、ホスト変数の内容には影響を与えません。

エラーまたは警告があったために実行されることになったルーチン内で ROLLBACK ステートメントと SQL WHENEVER ステートメントを使用している場合は、 ROLLBACK ステートメントの前に WHENEVER SQLERROR CONTINUE および WHENEVER SQLWARNING CONTINUE を指定します。これは、エラーまたは警告により ROLLBACK が失敗した場合にプログラムがループするのを防ぎます。

重大エラーの場合には、ROLLBACK ステートメントでは発行できないというメッセージが表示されます。クライアントとサーバー・アプリケーション間の通信の損失や、データベースの破損などの重大エラーが発生した場合は、 ROLLBACK ステートメントを発行しないでください。重大エラーが発生した後で発行できるステートメントは CONNECT ステートメントだけです。

プログラムの終了

プログラムを正しく終了させるには、以下のステップに従ってください。

  1. COMMIT ステートメントまたは ROLLBACK ステートメントを明示的に発行して、現行トランザクション (処理中のものがある場合) を終了する。
  2. CONNECT RESET ステートメントを使用して、データベース・サーバーへの接続を解放する。
  3. プログラムが使用した資源の終結処置を行う。たとえば、使用した一時記憶域またはデータ構造をすべて解放します。
注:プログラム終了時に、現行トランザクションがまだ活動中であると、 DB2 は暗黙にそのトランザクションを終了させます。トランザクションを暗黙に終了させる際の DB2 の動作はプラットフォーム固有なので、プログラム終了前に COMMIT か ROLLBACK ステートメントを発行して、すべてのトランザクションを明示的に終了するようにしてください。 DB2 が暗黙的にトランザクションを終了させる方法の詳細については、 トランザクションの暗黙終了を参照してください。

トランザクションの暗黙終了

現行トランザクションを終了せずにプログラムを終わらせた場合、 DB2 は暗黙に現行トランザクションを終了します (プログラムに適した終了方法の詳細については、 プログラムの終了を参照してください)。 DB2 はアプリケーション終了時に、 COMMIT または ROLLBACK ステートメントのどちらかを発行することにより、現行トランザクションを暗黙に終了します。 DB2 が COMMIT と ROLLBACK のどちらを発行するかは、以下の要因によって決まります。

サポートされているほとんどのオペレーティング・システムの場合

正常に終了した場合、DB2 はトランザクションを暗黙にコミットしますが、異常終了の場合は、トランザクションを暗黙にロールバックします。プログラムが異常終了とみなすものでも、データベース・マネージャーは異常終了とみなさない場合があることに注意してください。たとえば、アプリケーションが予期しないエラーを察知したときに、アプリケーションを即座に終了するように、 exit(-16) をコーディングすることができます。データベース・マネージャーは、この状況を正常終了とみなして、トランザクションをコミットします。一方、データベース・マネージャーは、例外やセグメント化違反などを異常終了とみなします。

Windows 32 ビットのオペレーティング・システムの場合

COMMIT ステートメントを使用して、トランザクションを明示的にコミットしない限り、アプリケーションの終了が正常か異常かに関係なく、DB2 は必ずトランザクションをロールバックします。

DB2 文脈 API を使用する場合

アプリケーションは DB2 API を用いてセットアップし、 マルチスレッドのデータベースのアクセスで説明されているようにスレッド間でアプリケーション文脈を渡すことができます。アプリケーションで DB2 API を使用している場合には、アプリケーションの終了が正常か異常かに関係なく、 DB2 は暗黙にトランザクションをロールバックします。 COMMIT ステートメントを使用して、トランザクションを明示的にコミットしない限り、トランザクションはロールバックされます。

疑似コードによるアプリケーションの枠組み

プログラムのコーディングのための疑似コードによる枠組みに、 DB2 アプリケーション・プログラムの一般的な枠組みを疑似コード形式で要約します。もちろん、実際に使用するプログラムに合うようにこの枠組みを調整することが必要です。

プログラム開始
EXEC SQL BEGIN DECLARE SECTION                                |
  DECLARE USERID FIXED CHARACTER (8)                          |
  DECLARE PW FIXED CHARACTER (8)                              |
                                                              | アプリケーションの
  (その他のホスト変数宣言)                                    | セットアップ
                                                              |
EXEC SQL END DECLARE SECTION                                  |
EXEC SQL INCLUDE SQLCA                                        |
EXEC SQL WHENEVER SQLERROR GOTO ERRCHK                        |
  (プログラムのロジック)
EXEC SQL CONNECT TO database A USER :userid USING :pw         |
EXEC SQL SELECT ...                                           |
EXEC SQL INSERT ...                                           | 最初の
  (SQL ステートメントが続く)                                  | 作業単位
EXEC SQL COMMIT                                               |
  (プログラムのロジックが続く)
EXEC SQL CONNECT TO database B USER :userid USING :pw         |
EXEC SQL SELECT ...                                           |
EXEC SQL DELETE ...                                           | 2 番目の
  (SQL ステートメントが続く)                                  | 作業単位
EXEC SQL COMMIT                                               |
  (プログラムのロジックが続く)
EXEC SQL CONNECT TO database A                                |
EXEC SQL SELECT ...                                           |
EXEC SQL DELETE ...                                           | 3 番目の
  (SQL ステートメントが続く)                                  | 作業単位
EXEC SQL COMMIT                                               |
  (プログラムのロジックが続く)
EXEC SQL CONNECT RESET                                        |
ERRCHK                                                        |
                                                              | アプリケーションの
  (SQLCA のエラー情報を検査する)                              | 終結処置
                                                              |
プログラム終了


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]