OpenESQL プリプロセッサを使用すると、COBOL プログラム内に記述された埋め込み SQL 文から ODBC ドライバを通じてリレーショナルデータベースにアクセスできます。
個別のプリプロセッサとは異なり、OpenESQL は、アプリケーションのコンパイル時に SQL 指令を指定して制御します。
ODBC を使用するには、次の操作を行う必要があります。
Net Express の ODBC サポートを使用するには、ODBC マネージャでデータソース名 (DSN) を設定する必要があります。ODBC マネージャは、Windows デスクトップの [コントロール パネル] の [管理ツール] を使用して開くことができます。適切な [32ビット ODBC] アイコンをクリックします。[システム DSN] タブをクリックします。
「ODBC データソースアドミニストレータ」ダイアログボックスが開きます。
DSN の割り当て方法の詳細は、「ODBC データソースアドミニストレータ」ダイアログボックスの [ヘルプ] ボタンをクリックしてください。
注:64 ビットバージョンの Windows 上で実行している場合に、32 ビットアプリケーション用の DSN を作成する場合は、32 ビットバージョンの ODBC データ ソース アドミニストレータ ユーティリティを実行する必要があります。このユーティリティを実行するコマンドは odbcad32 です。odbcad32.exe ファイルは、windowsdir¥syswow64 フォルダ内にあります。
OpenESQL では、開発者は ORACLE OCI インターフェイス形式で ORACLE データソースを使用することもできます。このインターフェイスを使用する場合は、次の指令でアプリケーションをコンパイルする必要があります。
sql(targetdb=ORACLEOCI)
Oracle サーバに接続するときには、CONNECT 文で ODBC データソース名のかわりに Oracle Net8 サービス名を使用します。ORACLE Net8 サービスの設定方法については、Oracle のマニュアルを参照してください。
Oracle OCI を使用する場合は、次の OpenESQL 機能がサポートされないことに注意してください。
メインフレームから移行する場合には、有効な移行ツールとして OpenESQL を使用できます。OpenESQL は、わかりやすい移行機能を提供し、しかも効率的です。OpenESQL の機能を次に示します。
詳細は、『SQL コンパイラ指令』の節にある BEHAVIOR と TRACELEVEL、『デモンストレーションアプリケーション』の節にあるデモアプリケーション behavior.app を参照してください。
埋め込み SQL 文を含むプログラムをコンパイルする場合には、SQL コンパイラ指令と適切なオプションを指定する必要があります。プログラムから呼び出す ODBC ドライバは、アクセスする特定のデータソースによって決定されます。
他のコンパイラ指令が指定できるところであればどこにでも SQL 指令を指定できます。指定できる箇所の例を次に示します。
$set sql(dbman=odbc, autocommit)
cobol testconn.cbl anim SQL(DBMAN=ODBC)
IDE から SQL 指令を設定する方法の詳細は、ヘルプトピックの『SQL コンパイラ指令オプションの設定』を参照してください。
注:複数の SQL 指令を指定できますが、お奨めしません。複数の SQL 指令オプションを指定すると、特定のオプションが原因で競合を起こし、意図しないキャンセルや上書きが発生します。
SQL コンパイラ指令は、オプションのセットで構成されています。詳細は、ヘルプトピックの『SQL コンパイラ指令』を参照してください。使用可能なオプションの詳細は、ヘルプトピックの『SQL コンパイラ指令オプション』を参照してください。
プログラムのコンパイル時にサポート窓口に問い合わせする必要のあるエラーが発生した場合には、サポート窓口の担当者は、問題の原因を特定するために追加のデバッグファイルの提供を求める場合があります。これらのデバッグファイルは、追加の SQL コンパイラ指令を指定して作成します。これらの指令のいくつかを指定すると、独自でデバッグする場合に役に立ちます。次の指定があります。
指令 | 作成ファイル | ファイル内の情報 |
---|---|---|
CHKECM(CTRACE) | ecmtrace.txt | EXEC SQL 文を置き換えるために生成されるコードを示す擬似 COBOL コードです。このファイルは、OpenESQL ODBC プリコンパイラからの出力ファイルと等価です。 |
CHKECM(TRACE) | ecmtrace.txt | ODBC ECM とコンパイラの間で受け渡される情報の詳細。無効な構文を生成するエラーが発生した場合に、このファイルを使用して、問題が発生した箇所を分離できます。 |
SQL(CTRACE) | sqltrace.txt | OpenESQL プリコンパイラサービスに渡される情報の詳細なリストとその結果。このファイルは、エラーが OpenESQL ECM のみでなく OpenESQL ランタイムのバグに関連する場合にも役に立ちます。 |
ECMLIST | program-name.lst | EXEC SQL 文を置き換えるために生成されるコードを示す擬似 COBOL コードを含む、標準の COBOL リストファイルです。CHKECM(CTRACE) 指令と LIST 指令を使用してプログラムをコンパイルする必要があります。 |
プログラムからデータベース内のデータにアクセスするには、その前にデータベースへの接続を確立する必要があります。
プログラムは、次の 2 通りの方法でデータベースに接続できます。
通常、次のどちらかに該当する場合は CONNECT 文を使用します。
通常、プログラムがコンパイル時に特定の 1 つのデータベースに接続する場合のみに使用します。SQL コンパイラ指令の INIT オプションを指定すると、SQL コンパイラ指令の DB オプションでデータソースに PASS オプションで指定されたログイン情報を使用して自動接続する呼び出しが、コンパイラによってプログラムの開始時に挿入されます。
アプリケーションによるデータベース操作が完了するときには、アプリケーションはデータベースとの接続を解除する必要があります。この処理には、DISCONNECT 文を使用します。
暗黙的接続を使用している場合には、プログラムの終了時に OpenESQL によってデータソースとの接続が自動的に解除されます。
プログラムの異常終了時に、OpenESQL に接続の解除とロールバックを暗黙的に実行させるには、SQL コンパイラ指令の INIT=PROT オプションを指定します。
OpenESQL では数多くのキーワードが予約されています。これらのキーワードはプログラム内で他の用途に使用することはできません。予約されているキーワードの完全なリストの詳細は、ヘルプトピックの『キーワード』を参照してください。
OpenESQL アプリケーションをビルドするには、次の操作を行う必要があります。
Net Express の基本インストールディレクトリのディレクトリ source には、sqlca.cpy と sqlda.cpy のコピーファイルが提供されており、通常の方法でプログラムにインクルードできます。
Net Express を使用して .exe を作成する場合は、SQL(GEN-CC2) 指令でプログラムをコンパイルしていない限り、必要なオブジェクトファイルがすべて自動的にリンクされます。
注:作成したアプリケーションを他のシステムに移動する場合には、移動先のシステムに適切なファイルが存在することを確認してください。
環境 | ファイル |
---|---|
32 ビット | odbcrw32.dll |
64 ビット | odbcrw64.dll |
システムの基本インストールディレクトリにある openesql ディレクトリには、さまざまなデモンストレーションアプリケーションが提供されています。
デモンストレーションアプリケーションを使用するには、1 つ以上の ODBC ドライバと、デモンストレーションに使用するために作成した DNS をインストールする必要があります。
デモンストレーションアプリケーションの中には、接続しているデータベースに EMP というテーブルが存在することを要求するものもあります。
すべての OpenESQL デモンストレーションアプリケーションではコンソールログが作成され、処理の進行状況を表示し、クエリー結果を表示する場合もあります。処理中にエラーが発生する場合は、エラーメッセージを表示して終了します。
次のアプリケーションが用意されています。
データソース名 LocalServer に接続するには、Microsoft SQL Server ODBC ドライバを使用します。これを行うには、ヘルプトピックの『ODBC データソース名の設定』を参照してください。
behavior プログラムは、behavior.cbl と behavsub.cbl によって、表を作成し格納します。表の作成後に、BEHAVIOR 指令が同じ不定 COBOL カーソル宣言である、読み取り専用 (behavior.cbl) と 更新可能 (behavsub.cbl) をどのように作成するかを確認します。
これは、プロジェクトディレクトリのトレースファイル OpenESQLTrace.processID.log で検証できます。ログファイルは、behavior.cbl の TRACELEVEL 指令で生成されます。
「SQL データソース」ダイアログが表示されます。名前を選択するか、または入力し、[OK] をクリックします。「ログイン」ダイアログが表示されます。ログイン名として「admin」を入力し、パスワードは空欄のまま [OK] をクリックします。3 種類のデータディクショナリクエリーが実行され、結果が出力されます。
データベースソース名、ユーザ名、およびパスワードの入力を求めます。作成したデータベース名とユーザ名「admin」を入力し、パスワードは空欄のまま Enter キーを押します。異なる構文オプションを使用した 4 種類の接続および接続解除テストが実行されます。5 番目のテストでは、「SQL データソース」ダイアログが表示されます。「マシンデータソース」リストから適切な名前を選択し、[OK] をクリックします。「ログイン」ダイアログが表示されます。ログイン名として「admin」を入力し、パスワードは空欄のまま [OK] をクリックします。5 番目のテストが実行され、プログラムが終了します。
サンプルデータベースに接続し、顧客コードの入力を求めます。メッセージに表示された BLUEL を入力します。該当の顧客コードの 2 つのフィールドが表示され、顧客コードの入力が再要求されます。ここで Enter キーを押します。地域の入力が求められます。メッセージに表示された CA を入力します。その地域の顧客が一覧表示され、さらに地域の入力が求められます。ここで、Enter キーを押すと、プログラムが終了します。
この 2 つのアプリケーションは、複数の同じテストを異なる SQL 構文オプションで実行します。どちらを起動しても、データソースとユーザ名の入力を求められます。テスト順序は次のとおりです。
2 番目のテストではエラーメッセージが表示されることがありますが、これは意図的に生成されたものであり、プログラムは続行されます。最後のテストでもエラーメッセージが表示されますが、これについても同様です。逆に、この段階で ODBC エラーが表示されない場合には、テストは失敗です。
接続を試行して、エラーメッセージを表示します。「SQL データソース」ダイアログが表示されます。DSN 名を選択し、[OK] をクリックします。「ログイン」ダイアログが表示されます。ログイン名として「admin」を入力し、パスワードは空欄のまま [OK] をクリックします。意図的にエラーが生成され、2 つのエラーメッセージが表示されます。
OpenESQL では、COMMIT 文と ROLLBACK 文を使用して、ODBC のトランザクション管理機能を制御できます。ODBC では各文の実行後にトランザクションが標準で自動コミットされるように指定しても、OpenESQL では他の SQL システムとの互換性を考慮して、この機能は無効化されています。この機能が必要な場合は、SQL コンパイラ指令の AUTOCOMMIT オプションを指定してください。
注:トランザクション処理機能を実装していない ODBC ドライバもあります。そのようなドライバでは、データベースの更新が直ちに確定されない可能性があります。 詳細は、使用しているデータベースドライバのマニュアルを参照してください。
ヘルプトピックの『SQL/COBOL データ型マッピング』には、SQL のデータ型と COBOL データ形式を変換する際に OpenESQL で使用する対応関係を示す表が記載されています。
ODBC では、日付は yyyy-mm-dd、時刻は hh:mm:ss 形式で表記されます。これらの形式は、使用するデータソースのネイティブな日付や時刻の表記形式と一致しない可能性があります。入力文字ホスト変数には、データソースのネイティブな日付日時形式を使用できます。ほとんどのデータソースでは、PICTURE 句 PIC X(29) を使用することをお奨めします。次に例を示します。
01 mydate PIC x(29). ... EXEC SQL INSERT INTO TABLE1 VALUES (1,'1997-01-24 12:24') END-EXEC ... EXEC SQL SELECT DT INTO :mydate FROM TABLE1 WHERE X = 1 END-EXEC display mydate
また、ODBC エスケープシーケンスを使用することもできます。ODBC では、日付、時刻、およびタイムスタンプの各定数用のエスケープシーケンスが定義されています。これらのエスケープシーケンスは、ODBC ドライバによって認識され、データソース側の構文に変換されます。
エスケープシーケンスによる、日付、時刻、およびタイムスタンプの各定数の表記方法は、次のとおりです。
日付 |
{d 'yyyy-mm-dd'} |
時刻 |
{t 'hh:mm:ss'} |
タイムスタンプ |
{ts yyyy-mm-dd hh:mm:ss[.f...] |
日付、時刻、およびタイムスタンプのエスケープシーケンスを使用したコード例を、次に示します。
working-storage section. EXEC SQL INCLUDE SQLCA END-EXEC 01 date-field1 pic x(29). 01 date-field2 pic x(29). 01 date-field3 pic x(29). procedure division. EXEC SQL CONNECT TO 'Net Express 4.0 Sample 1' USER 'admin' END-EXEC * テーブルが存在する場合は削除します。 EXEC SQL DROP TABLE DT END-EXEC * DATE、TIME、および DATE/TIME のカラムをもつテーブルを作成します。 * 注:Access では、これら 3 つのカラムのかわりに DATETIME を使用します。 * 専用のカラム型を使用するデータベースもあります。 * 別のデータソースに DATE/TIME カラムを作成する場合には、 * 該当データベースのマニュアルでカラムの定義方法を * 確認してください。 EXEC SQL CREATE TABLE DT ( id INT, myDate DATE NULL, myTime TIME NULL, myTimestamp TIMESTAMP NULL) END-EXEC * ODBC エスケープシーケンスを使用してテーブルに挿入します。 EXEC SQL INSERT into DT values (1 , {d '1961-10-08'}, *> 日付を設定します。 {t '12:21:54' }, *> 時刻を設定します。 {ts '1966-01-24 08:21:56' } *> 日付と時刻を設定します。 ) END-EXEC * 挿入した値を取り込みます。 EXEC SQL SELECT myDate ,myTime ,myTimestamp INTO :date-field1 ,:date-field2 ,:date-field3 FROM DT where id = 1 END-EXEC * 取り込み結果を表示します。 display 'ここに日付が設定されています :' date-field1 display 'ここに時刻が設定されています :' date-field2 display '注:ほとんどのデータソースは、日付に対して' 'デフォルトが設定されます' display 'ここに日付と時刻が設定されています :' date-field3 * テーブルを削除します。 EXEC SQL DROP TABLE DT END-EXEC * データソースから接続を解除します。 EXEC SQL DISCONNECT CURRENT END-EXEC stop run.
または、日付 / 時刻変数に SQL TYPE で定義されたホスト変数を使用できます。 次のホスト変数を定義できます。
01 my-id pic s9(08) COMP-5. 01 my-date sql type is date. 01 my-time sql type is time. 01 my-timestamp sql type is timestamp.
INSERT 文を次のコードに書き換えます。
*> SQL TYPE ホスト変数を使用したテーブルへの挿入 move 1 to MY-ID move "1961-10-08" to MY-DATE move "12:21:54" to MY-TIME move "1966-01-24 08:21:56" to MY-TIMESTAMP EXEC SQL INSERT into DT value ( :MY-ID ,:MY-DATE ,:MY-TIME ,:MY-TIMESTAMP ) END-EXEC
SQLCA データ構造体は、システムの基本インストールディレクトリ内の source ディレクトリにある sqlca.cpy ファイルで定義されています。SQLCA をプログラムで使用するには、データ部に次の文を記述します。
EXEC SQL INCLUDE SQLCA END-EXEC
この文を記述しない場合でも、COBOL コンパイラによって自動的に領域が割り当てられますが、プログラムではその領域にはアクセスできません。ただし、SQLCODE または SQLSTATE のデータ項目を宣言する場合は、各 EXEC SQL 文の後に SQLCA の対応フィールドをユーザ定義フィールドにコピーするコードが COBOL コンパイラによって生成されます。
MFSQLMESSAGETEXT データ項目を宣言した場合には、SQLCODE にゼロ以外の値が検出されるたびに、例外条件の説明によって同データ項目が更新されます。MFSQLMESSAGETEXT は、文字列データ項目 PIC x(n) として宣言します。n には、有効値を入力します。ODBC エラーメッセージは、70 バイトの SQLCA メッセージフィールドを超えることがあるので、MFSQLMESSAGETEXT データ項目は特に有用です。
注:SQLCA、SQLCODE、SQLSTATE、または MFSQLMESSAGETEXT はホスト変数として宣言する必要はありません。
OpenESQL では、次の 2 つの文をストアドプロシージャとともに使用できます。
OCBC ストアドプロシージャの呼び出しに対する一般的なサポートを提供します。
Micro Focus Embedded SQL Toolkit for Microsoft SQL Server との下位互換性を提供します。
ストアドプロシージャでは、次の処理を実行できます。
注:ストアドプロシージャの機能はデータベースベンダごとに大きく異なり、各ベンダは上記の機能を部分的に提供しています。このため、データベース間でのストアドプロシージャの呼び出しは、OpenESQL 文に比べて汎用性がありません。
ストアドプロシージャの呼び出し時には、コンマで区切られたリストとしてパラメータが渡されます。これらのパラメータはかっこで囲むこともできます。パラメータには、ホスト変数、定数、または CURSOR キーワードが使用できます。CURSOR キーワードで渡されたパラメータはバインドが解除されるため、結果集合を返す Oracle 8 ストアドプロシージャのみで使用してください。
パラメータがホスト変数の場合は、その後にパラメータタイプを表す語句 (IN、INPUT、INOUT、OUT、OUTPUT) を指定できます。パラメータタイプを指定しない場合は、INPUT が使用されます。
ホスト変数パラメータは、正式なパラメータ名と等号記号をホスト変数の直前に指定することで、キーワードパラメータとして渡すこともできます。
EXEC SQL CALL myProc (keyWordParam = :hostVar) END-EXEC
移植性を重視する場合には、ホスト変数のみをパラメータに指定し、定数パラメータは使用しないでください。また、呼び出しに渡されたパラメータは通常の位置指定パラメータとキーワードパラメータのどちらかのみとして扱い、これらの両方として処理しないでください。サーバによっては両方のパラメータがサポートされていますが、その場合でもキーワードパラメータは常にすべての位置指定パラメータの後に渡される必要があります。キーワードパラメータはコードの記述の明確化に役立ち、サーバがデフォルトのパラメータ値とオプションパラメータをサポートする場合に効果的です。
結果集合を返すストアドプロシージャの呼び出しは、カーソル宣言で使用する必要があります。次に例を示します。
EXEC SQL DECLARE cursorName CURSOR FOR storedProcecureCall
この場合には、ストアドプロシージャは他のタイプのカーソルと同様に、カーソルの OPEN 処理と結果集合行の FETCH 処理によって呼び出されます。
現バージョンの OpenESQL は、単一の結果集合のみをサポートしています。
ODBC パラメータは、Oracle 配列パラメータと異なります。パラメータ配列を使用する場合は、配列の各要素に同じ文を繰り返し実行した場合と同じ結果を得られます。ストアドプロシージャ呼び出しで 1 つのパラメータを配列として渡すと、他のすべての引数も同じ数の要素を含む配列として渡されます。ストアドプロシージャでは、これらのパラメータの各「行」で呼び出された場合と同様の処理が実行されます。パラメータで渡される行数は、呼び出しの直前に FOR :hvar を指定することによって、配列の上限サイズを超えない数に制限することができます (:hvar は、渡すべき行の数を含む整数型のホスト変数です)。
注:Net Express のオンラインヘルプには、CALL 文と EXECSP 文の両方の構造体と例が記載されています([ヘルプ] メニューの [ヘルプトピック] をクリックします。[索引] タブをクリックし、[CALL] または [EXECSP] をクリックします)。
動的 SQL のデモンストレーションアプリケーション dynamic.app は、次のディレクトリに格納されています。
Examples¥Net Express IDE¥odbcesql
このプロジェクトを開き、必要に応じてプロジェクトをリビルドした後に、[アニメート] メニューから [ステップ実行] を選択すると、アプリケーションがステップ実行され、COBOL プログラムでの動的 SQL の使用方法が具体例を通じて示されます。
ODBC は、位置指定更新をサポートします。位置指定更新では、カーソルを使用して最後に取り込まれた行が更新されます。ただし、位置指定更新をサポートしないドライバもあります。
注:位置指定更新ではホスト配列を使用できません。
ODBC ドライバによっては、位置指定更新を有効にするために、カーソルで使用される SELECT 文に FOR UPDATE 句を含める必要があります。多くのデータソースでは、SET 文または DECLARE CURSOR 文のどちらかで SCROLLOPTION と CONCURRENCY の特定の組み合わせを指定することが必要です。これが機能しない場合は、ODBC カーソルライブラリにより、位置指定更新が制限されて実装されます。この位置指定更新は、指令 SQL(USECURLIB=YES) および SCROLLOPTION STATIC と CONCURRENCY OPTCCVAL (または OPTIMISTIC) を使用してコンパイルすると有効化できます。ODBC カーソルライブラリを使用しているときに複数の行が更新されないようにするには、カーソルクエリーで、更新するテーブルに主キーカラムを含めます。
$SET SQL(usecurlib=yes) WORKING-STORAGE SECTION. EXEC SQL INCLUDE SQLCA END-EXEC *> SQL エラーが発生する場合は、ここに詳細なメッセージテキストが示されます。 01 MFSQLMESSAGETEXT PIC X(250). 01 IDX PIC X(04) COMP-5. EXEC SQL BEGIN DECLARE SECTION END-EXEC *> 他の COBOL コンパイラに移植する必要がある場合は、 *> ここにホスト変数を記述します。 EXEC SQL INCLUDE Products END-EXEC EXEC SQL END DECLARE SECTION END-EXEC PROCEDURE DIVISION. EXEC SQL WHENEVER SQLERROR perform OpenESQL-Error END-EXEC *> ACCESS データソースを使用して位置指定更新を行うデモです。 EXEC SQL CONNECT TO 'Inventory' USER 'admin' END-EXEC *> プログラムロジックと SQL 文をここに記述します。 EXEC SQL DECLARE CSR679 CURSOR FOR SELECT A.ProductID ,A.ProductName ,A.UnitPrice FROM Products A WHERE ( A.ProductID < 3 ) END-EXEC EXEC SQL SET SCROLLOPTION static END-EXEC EXEC SQL SET CONCURRENCY optccval END-EXEC EXEC SQL OPEN CSR679 END-EXEC PERFORM UNTIL SQLSTATE >= "02000" EXEC SQL FETCH CSR679 INTO :ProductID ,:ProductName:ProductName-NULL ,:UnitPrice:UnitPrice-NULL END-EXEC *> FETCH 処理のデータを処理します。 IF SQLSTATE = "00000" *> 価格を 10% 上げます。 compute unitprice = unitprice * 1.10 EXEC SQL UPDATE Products SET UnitPrice = :UnitPrice:UnitPrice-NULL WHERE CURRENT OF CSR679 END-EXEC END-IF END-PERFORM EXEC SQL CLOSE CSR679 END-EXEC EXEC SQL COMMIT END-EXEC EXEC SQL DISCONNECT CURRENT END-EXEC EXIT PROGRAM. STOP RUN. *> デフォルトの SQL エラールーチン。 *> 必要に応じて修正してプログラムを停止します。 OpenESQL-Error Section. display "SQL エラー = " sqlstate " " sqlcode display MFSQLMESSAGETEXT *> 実行を停止します。 exit.
ここでは、IIS、MTS、COM+、CICS、Tuxedo などの Web サーバおよびアプリケーションサーバで制御される環境で OpenESQL を使用するときに実行する作業について説明します。
サーバの種類は異なりますが、ここでは、すべてのサーバに共通の内容を説明します。
OpenESQL はスレッドセーフです。通常、アプリケーション内のすべてのスレッドは、接続やカーソルなどの SQL リソースを共有します。ただし、アプリケーションサーバで実行している場合には、スレッドは、異なるユーザからの要求を処理できるようにスケジュールされます。このため、次の指令を使用します。
SQL(THREAD=ISOLATE)
これにより各スレッドのリソースをそれぞれ分離する必要があります。
注:OpenESQL では、スレッドごとに 72KB のオーバーヘッドをもちます。このメモリは、アプリケーションが終了するまで解放されません。
多くの環境では、アプリケーションサーバが接続プールを管理します。つまり、データベースに対して実際の接続と接続解除の要求を行うことはほとんどありません。アプリケーションが実行されると、既存の接続が再使用されます。多くの場合には、接続プーリングは ODBC ドライバマネージャで管理され、アプリケーションに対して透過的です。アプリケーションサーバ自体が接続プールを管理する場合は、アプリケーションは他の処理を実行する前に「SET CONNECTION」文を使用する必要があります。
アプリケーションで OpenESQL の CONNECT 文と DISCONNECT 文を使用し、アプリケーションサーバ自体が ODBC 接続プーリングを有効化しているか不明な場合は、SQL(CONNECTIONPOOL=...) 指令を使用することもできます。ただし、この方法を使用することはほとんどありません。
多くの場合には、アプリケーションサーバはトランザクション管理を提供します。これは、構成要素をアプリケーションサーバの制御下に置くときに決定されます。アプリケーションサーバがトランザクション管理を提供していない場合は、OpenESQL の COMMIT 文と ROLLBACK 文を使用してトランザクションを管理する必要があります。ただし、アプリケーションサーバでトランザクション管理を提供する場合は、次の作業を実行する必要があります。
MTS または COM+ を使用している場合は、アプリケーションサーバがトランザクションを管理しているときに、デフォルトのトランザクション分離レベルをシリアル化できます。これによって、過剰なロックが行われたり、並行性が低下したりすることがあります。アプリケーションサーバでデッドロックを解決しようとすると異常終了するトランザクションを処理できるようにアプリケーションを準備する必要があります。これらの問題を解決するには、次の文を使用します。
exec sql set transaction isolation read committed end-exec
これにより厳格性の低い分離レベルを設定します。この場合は、この文を、CONNEDT 文の直後に実行する文にする必要があります。SQL(AUTOCOMMIT) が使用されていない場合は、SET TRANSACTION ISOLATION 文を実行する直前にコミットまたはロールバックを実行する必要があります。
アプリケーションサーバ環境で実行する場合は、アプリケーションを実行するユーザアカウントが、開発用のアカウントと異なることがあります。このため、ユーザデータソースとして設定された ODBC データソースが使用できない場合があります。実装システムでデータソースをシステムデータソースとして設定すると便利な場合があります。ファイルベースのデータソースを使用する場合は、アプリケーションサーバで使用されるアカウントでデータベースファイルにアクセスできるようにする必要があります。データベースへのアクセス時、特に統合セキュリティが使用されている場合 (DBMS がオペレーティングシステムと同じアカウント番号を使用している場合) には、デフォルトのスキーマが、開発時に使用されていたスキーマと異なる場合があります。開発および実装にそれぞれ別のスキーマ名が使用されている場合には、これは意図的なものである可能性があります。また、テーブルがアプリケーションに表示されていないことを意味する場合もあります。明示的なオーナー修飾語を使用するか、または、データベース固有の文を実行する場合は、正しいスキーマがデフォルトとして選択されます。
次に、OCX ウィザードで生成されたトランザクションラッパーの例を示します。このトランザクションラッパーは、MS SQL Server データソースを使用して次のシナリオを処理する OpenESQL ロジックを含めるために変更されています。
$set ooctrl(+p) sql(thread=isolate autocommit) *>----------------------------------------------------------- *> クラスの記述 *>----------------------------------------------------------- class-id. cblsqlwrapper inherits from olebase. object section. class-control. cblsqlwrapper is class "cblsqlwrapper" *> OCWIZARD - クラスの一覧表示の開始 objectcontext is class "objectcontext" olebase is class "olebase" oleSafeArray is class "olesafea" oleVariant is class "olevar" *> OCWIZARD - クラスの一覧表示の終了 *>---USER-CODE。次のクラス名を追加します。 *>----------------------------------------------------------- working-storage section. *> グローバルデータの定義 *>----------------------------------------------------------- *>----------------------------------------------------------- class-object. *> クラスデータとメソッドの定義 *>----------------------------------------------------------- object-storage section. *> OCWIZARD - 標準クラスメソッドの開始 *>----------------------------------------------------------- *> クラスに関する詳細情報を返します。 *> タイプライブラリがある場合は、この theClassId と theInterfaceId *> が一致する必要があります。 *> theProgId はこのクラスのレジストリエントリと一致する必要があります。 *> (ゼロ長文字列はクラスファイル名を暗黙で使用します。) *> theClassId はレジストリに保存された CLSID と一致する必要があります。 *> theVersion は現在無視されています (デフォルトの 1 を使用)。 *>----------------------------------------------------------- method-id. queryClassInfo. linkage section. 01 theProgId pic x(256). 01 theClassId pic x(39). 01 theInterfceId pic x(39). 01 theVersion pic x(4) comp-5. 01 theDescription pic x(256). 01 theThreadModel pic x(20). procedure division using by reference theProgId by reference theClassId by reference theInterfceId by reference theVersion by reference theDescription by reference theThreadModel. move z"{3EADD92C-06C5-46F2-A2E0-7EB0794C14DF}" to theClassId move z"{5BF3F966-9932-4835-BFF6-2582CA2592AD}" to theInterfceId move z"Description for class cblsqlwrapper" to theDescription move z"Apartment" to theThreadModel exit method. end method queryClassInfo. *>----------------------------------------------------------- *> タイプライブラリの詳細を返します。使用しない場合は、削除してください。 *> theLocale は現在無視されています (デフォルトの 0 を使用). *> theLibraryName は自動登録に使用する NULL 終了文字列で、 *> 次の値をサポートします。 *> <no string> - このバイナリにはライブラリが埋められます。 *> <number> - 上記と同様に、このリソース番号が使用されます。 *> <Path>Path> - ライブラリはこの (完全なパスの) *> 位置にあります。 *>----------------------------------------------------------- method-id. queryLibraryInfo. linkage section. 01 theLibraryName pic x(512). 01 theMajorVersion pic x(4) comp-5. 01 theMinorVersion pic x(4) comp-5. 01 theLibraryId pic x(39). 01 theLocale pic x(4) comp-5. procedure division using by reference theLibraryName by reference theMajorVersion by reference theMinorVersion by reference theLibraryId by reference theLocale. move 1 to theMajorVersion move 0 to theMinorVersion move z"{24207F46-7136-4285-A660-4594F5EE7B87}" to theLibraryId exit method. end method queryLibraryInfo. *>----------------------------------------------------------- *> OCWIZARD - 標準クラスメソッドの終了 end class-object. *>----------------------------------------------------------- object. *> インスタンスデータとメソッドの定義 *>----------------------------------------------------------- object-storage section. *> OCWIZARD - 標準インスタンスメソッドの開始 *> OCWIZARD - 標準インスタンスメソッドの終了 *>----------------------------------------------------------- method-id. "RetrieveString". working-storage section. 01 mfsqlmessagetext pic x(400). 01 ESQLAction pic x(100). COPY DFHEIBLK. COPY SQLCA. *> トランザクションプログラム名 01 transactionPgm PIC X(7) VALUE 'mytran'. local-storage section. 01 theContext object reference. 01 transactionStatusFlag pic 9. 88 transactionPassed value 1. 88 transactionFailed value 0. *>---USER-CODE。次の必要な局所場所項目を追加します。 01 ReturnValue pic x(4) comp-5. 88 IsNotInTransaction value 0. 01 transactionControlFlag pic 9. 88 TxnControlledByMTS value 0. 88 TxnNotControlledByMTS value 1. linkage section. *> トランザクションに渡される情報 01 transaction-Info. 05 transaction-Info-RC pic 9. 05 transaction-Info-data pic x(100). *> トランザクションから返される情報 01 transaction-Info-Returned pic x(100). procedure division using by reference transaction-Info returning transaction-Info-Returned. *> 初期化コード perform A-Initialise perform B-ConnectToDB if TxnNotControlledByMTS perform C-SetAutoCommitOff end-if *> 分離レベルを設定して、SQLServer のデフォルト、 *>...serialize を上書きします。 perform D-ResetDefaultIsolationLevel *> カーソルタイプを設定し、OpenESQL のデフォルト *>...dynamic+lock を上書きします。 perform E-ResetDefaultCursorType *> トランザクションを呼び出します。 perform F-CallTransaction *> コードの終了 - MTS/COM+ で制御されていない場合は、Commit/Rollback を *> 実行します。 if TxnNotControlledByMTS if transactionPassed perform X-Commit else perform X-Rollback end-if end-if perform Y-Disconnect *> トランザクションサーバ - メソッドに失敗した場合は、setAbort を使用します。 if theContext not = null if transactionPassed invoke theContext "setComplete" else invoke theContext "setAbort" end-if invoke theContext "finalize" returning theContext end-if exit method . A-Initialise. *> トランザクションサーバ - 実行中のコンテキストを取得します。 invoke objectcontext "GetObjectContext" returning theContext *> この構成要素が MTS トランザクションに含まれるかどうか確認します。 if theContext = null set TxnNotControlledByMTS to true else invoke theContext "IsInTransaction" returning ReturnValue if IsNotInTransaction set TxnNotControlledByMTS to true else set TxnControlledByMTS to true end-if end-if *> プログラム変数を初期化します。 set transactionPassed to true INITIALIZE DFHEIBLK . B-ConnectToDB. *> データソースに接続します。 EXEC SQL CONNECT TO 'SQLServer 2000' USER 'SA' END-EXEC if sqlcode zero move z"connection failed " to ESQLAction perform Z-ReportSQLErrorAndExit end-if . C-SetAutoCommitOff. EXEC SQL SET AUTOCOMMIT OFF END-EXEC if sqlcode zero move z"Set Autocommit Off failed " to ESQLAction perform Z-ReportSQLErrorAndExit end-if perform X-Commit . D-ResetDefaultIsolationLevel. *> SQLServer のデフォルトの分離レベルは「Serialized」であるため、 *> ここでは、このデフォルト値をより適切な値にリセットします。 EXEC SQL SET TRANSACTION ISOLATION READ COMMITTED END-EXEC if sqlcode zero move z"set transaction isoation failed " to ESQLAction perform Z-ReportSQLErrorAndExit end-if . E-ResetDefaultCursorType. *> OpenESQL のデフォルトのカーソルタイプは、dynamic + lock です。 *> 最も効率のよいのは「client」または「firehose」カーソルです。 *> これは、forward + read only として宣言されたカーソルです - ここで *> これを実行する場合は、この時点からこの値がデフォルトとして設定されます。 *> Forward で問題が発生した場合は、並行性を fast *> forward に変更します (ただし、これはクライアントカーソルでは *> なくなります)。 EXEC SQL SET CONCURRENCY READ ONLY END-EXEC if sqlcode zero move z"Set Concurrency Read Only" to ESQLAction perform Z-ReportSQLErrorAndExit end-if EXEC SQL SET SCROLLOPTION FORWARD END-EXEC if sqlcode zero move z"Set Concurrancy Read Only" to ESQLAction perform Z-ReportSQLErrorAndExit end-if . F-CallTransaction. *> プログラムを呼び出してトランザクションを処理します。 move 0 to transaction-Info-RC call tranactionPgm using dfheiblk transaction-Info *> 処理が適切かどうか確認します。 if transaction-Info-RC = 0 set transactionPassed to true else set transactionFailed to true end-if . X-Commit. EXEC SQL COMMIT END-EXEC if sqlcode zero move z"Commit failed " to ESQLAction perform Z-ReportSQLErrorAndExit end-if . X-Rollback. EXEC SQL ROLLBACK END-EXEC if sqlcode zero move z"Rollback failed " to ESQLAction perform Z-ReportSQLErrorAndExit end-if . Y-Disconnect. EXEC SQL DISCONNECT CURRENT END-EXEC if sqlcode zero move z"Disconnect failed " to ESQLAction perform Z-ReportSQLErrorAndExit end-if . Z-ReportSQLErrorAndExit. move spaces to transaction-Info-Returned string ESQLAction delimited by x"00" "SQLSTATE = " SQLSTATE " " mfsqlmessagetext into transaction-Info-Returned end-string exit method . exit method. end method "RetrieveString". *>----------------------------------------------------------- end object. end class cblsqlwrapper.
MTS/COM+ または WebSphere トランザクションの設定方法の詳細は、『分散コンピューティング』のマニュアルを参照してください。
XML ODBC ドライバがある場合は、ODBC データソースと同様に XML ファイルにアクセスするためにそのドライバを設定できます。そして、XML データソースで OpenESQL アシスタントを使用して SQL 文をビルドできます。
XML への情報の変換をするために、OpenESQL に PERSIST 文が追加されました。PERSIST 文を使用する場合は、カーソルの SELECT 文で定義された情報を XML ファイルとして保存できます。構文は次のとおりです。
PERSIST cursor_name TO xml_destination
xml_destination には識別子、ホスト変数、または定数を単一引用符または二重引用符で囲んで指定できます。カーソルでは SCROLLOPTION を static に設定する必要もあります。次に、例を示します。
01 hv pic x(50). procedure-division. *> SQL エラーを処理するために whenever 句を設定します。 exec sql whenever sqlerror goto sql-error end-exec exec sql whenever sqlwarning perform sql-warning end-exec *> データソースに接続します。 exec sql connect to "data source" end-exec *> xml ファイルに保存するカラム情報を使用して静的カーソルを宣言します。 exec sql declare c static cursor for select * from emp end-exec *> カーソルをオープンします。 exec sql open c end-exec *> 二重引用符で囲まれた定数を使用してデータを xml ファイルに保存します。 exec sql persist c to "c:¥XML Files¥xmltest1.xml" end-exec *> 単一引用符で囲まれた定数を使用してデータを xml ファイルに保存します。 exec sql persist c to 'c:¥XML Files¥xmltest2.xml' end-exec *> ホスト変数を使用してデータを xml ファイルに保存します。 move "c:¥XML Files¥xmltest3.xml" to hv exec sql persist c to :hv end-exec *> カーソルをクローズします。 exec sql close c end-exec *> データソースとの接続を解除します。 exec sql disconnect current end-exec goback.
注:Data Direct Connect ODBC ドライバを使用している場合は、バージョン 3.70 以降を使用する必要があります。
一部のアプリケーションでは、Unicode データを ANSI に変換しないで Microsoft SQL Server データソースに取り込んだり保存したりすることがあります。以前のバージョンの OpenESQL では、データを自動変換しないとデータにアクセスできませんでした。現在のバージョンの OpenESQL と Net Express では新しいタイプのホスト変数を使用することで、Unicode データを ANSI に変換しなくても直接操作できるようになりました。Microsoft SQL Server では、次の 3 つの Unicode カラム型がサポートされます。
注:アプリケーションが静的 SQL を使用している場合は、標準データ型を返します。ただし、アプリケーションが動的 SQL を使用している場合は、上記の新しいデータ型を返します。
データを自動的変換しないで、これらのカラムにアクセスするには、次の定義を使用してホスト変数を定義します。
PIC N(xx) USAGE NATIONAL
xx には、カラムのサイズを指定します。この形式は、現在固定長データと可変長データの両方についてサポートされています。可変長データを NULL で終了して、データの挿入や更新時にカラムのデータの末尾を示すことができます。データソースからデータが取り込まれると、ホスト変数の末尾に空白文字が付加されます。
たとえば、次のプログラムでは Microsoft SQL Server 2000 製品に付属している Northwind サンプルデータベースから従業員情報を取り込みます。
$SET UNICODE(NATIVE) $SET SQL WORKING-STORAGE SECTION. EXEC SQL INCLUDE SQLCA END-EXEC * SQL エラーが発生する場合は、ここに詳細なメッセージテキストが示されます。 01 MFSQLMESSAGETEXT PIC X(250). 01 IDX PIC X(04) COMP-5. EXEC SQL BEGIN DECLARE SECTION END-EXEC * 他の COBOL コンパイラに移植する必要がある場合は、 * ここにホスト変数を記述します。 EXEC SQL INCLUDE Employees END-EXEC EXEC SQL END DECLARE SECTION END-EXEC PROCEDURE DIVISION. EXEC SQL WHENEVER SQLERROR perform OpenESQL-Error END-EXEC EXEC SQL CONNECT TO 'LocalServer' END-EXEC * プログラムロジックと SQL 文をここに記述します。 EXEC SQL DECLARE CSR135 CURSOR FOR SELECT A.FirstName ,A.LastName ,A.EmployeeID ,A.HireDate FROM Employees A END-EXEC EXEC SQL OPEN CSR135 END-EXEC PERFORM UNTIL SQLSTATE >= "02000" EXEC SQL FETCH CSR135 INTO :Employees-FirstName ,:Employees-LastName ,:Employees-EmployeeID ,:Employees-HireDate:Employees-HireDate-NULL END-EXEC *> FETCH 処理のデータを処理します。 IF SQLSTATE < "02000" * 配列の取り込みの場合は、フィールド sqlerrd(3) に返される行数が * 影響を受ける行の数。 * PERFORM VARYING IDX FROM 1 BY 1 * UNTIL IDX > SQLERRD(3) * ここに、配列を処理するコードを追加する必要があります。 * END-PERFORM END-IF END-PERFORM EXEC SQL CLOSE CSR135 END-EXEC EXEC SQL DISCONNECT CURRENT END-EXEC EXIT PROGRAM. STOP RUN. * デフォルトの SQL エラールーチン。 * 必要に応じて修正してプログラムを停止します。 OpenESQL-Error Section. display "SQL エラー = " sqlstate " " sqlcode display MFSQLMESSAGETEXT * stop run exit.
次の例は、ANSI でデータを取り込んだ場合と同じコードですが、次のように INCLUDE Employees コピーブックの定義が異なります。
* ----------------------------------------------------------- * Employee テーブルに対する COBOL 宣言 * ----------------------------------------------------------- 01 DCLEmployees. 03 Employees-EmployeeID PIC S9(09) COMP-5. 03 Employees-LastName PIC N(20) USAGE NATIONAL. 03 Employees-FirstName PIC N(10) USAGE NATIONAL. 03 Employees-Title PIC N(30) USAGE NATIONAL. 03 Employees-TitleOfCourtesy PIC N(25) USAGE NATIONAL. 03 Employees-BirthDate PIC X(23). 03 Employees-HireDate PIC X(23). 03 Employees-Address PIC N(60) USAGE NATIONAL. 03 Employees-City PIC N(15) USAGE NATIONAL. 03 Employees-Region PIC N(15) USAGE NATIONAL. 03 Employees-PostalCode PIC N(10) USAGE NATIONAL. 03 Employees-Country PIC N(15) USAGE NATIONAL. 03 Employees-HomePhone PIC N(24) USAGE NATIONAL. 03 Employees-Extension PIC N(4) USAGE NATIONAL. 03 Employees-Photo PIC X(64000). 03 Employees-Notes PIC N(32000) USAGE NATIONAL. 03 Employees-ReportsTo PIC S9(09) COMP-5. 03 Employees-PhotoPath PIC N(255) USAGE NATIONAL.
OpenESQL アシスタントも Unicode データをサポートするように拡張されています。詳細は、『OpenESQL アシスタント』の章を参照してください。