OpenESQL

OpenESQL プリプロセッサを使用すると、COBOL プログラム内に記述された埋め込み SQL 文から ODBC ドライバを通じてリレーショナルデータベースにアクセスできます。

個別のプリプロセッサとは異なり、OpenESQL は、アプリケーションのコンパイル時に SQL 指令を指定して制御します。

ODBC ドライバとデータソース名

ODBC を使用するには、次の操作を行う必要があります。

  1. ODBC ドライバのインストール
  2. ODBC データソース名 (data source name; DSN) の設定

データソース名の設定

Net Express の ODBC サポートを使用するには、ODBC マネージャでデータソース名 (DSN) を設定する必要があります。ODBC マネージャは、Windows デスクトップの [コントロール パネル] の [管理ツール] を使用して開くことができます。適切な [32ビット ODBC] アイコンをクリックします。[システム DSN] タブをクリックします。

「ODBC データソースアドミニストレータ」ダイアログボックスが開きます。

DSN の割り当て方法の詳細は、「ODBC データソースアドミニストレータ」ダイアログボックスの [ヘルプ] ボタンをクリックしてください。

注:64 ビットバージョンの Windows 上で実行している場合に、32 ビットアプリケーション用の DSN を作成する場合は、32 ビットバージョンの ODBC データ ソース アドミニストレータ ユーティリティを実行する必要があります。このユーティリティを実行するコマンドは odbcad32 です。odbcad32.exe ファイルは、windowsdir¥syswow64 フォルダ内にあります。

COBOL プログラムの移行方法

メインフレームから移行する場合には、有効な移行ツールとして OpenESQL を使用できます。OpenESQL は、わかりやすい移行機能を提供し、しかも効率的です。OpenESQL の機能を次に示します。

詳細は、『SQL コンパイラ指令』の節にある BEHAVIORTRACELEVEL、『デモンストレーションアプリケーション』の節にあるデモアプリケーション behavior.app を参照してください。

SQL コンパイラ指令

埋め込み SQL 文を含むプログラムをコンパイルする場合には、SQL コンパイラ指令と適切なオプションを指定する必要があります。プログラムから呼び出す ODBC ドライバは、アクセスする特定のデータソースによって決定されます。

他のコンパイラ指令が指定できるところであればどこにでも SQL 指令を指定できます。指定できる箇所の例を次に示します。

IDE から SQL 指令を設定する方法の詳細は、ヘルプトピックの『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 通りの方法でデータベースに接続できます。

アプリケーションによるデータベース操作が完了するときには、アプリケーションはデータベースとの接続を解除する必要があります。この処理には、DISCONNECT 文を使用します。

暗黙的接続を使用している場合には、プログラムの終了時に OpenESQL によってデータソースとの接続が自動的に解除されます。

プログラムの異常終了時に、OpenESQL に接続の解除とロールバックを暗黙的に実行させるには、SQL コンパイラ指令の INIT=PROT オプションを指定します。

キーワード

OpenESQL では数多くのキーワードが予約されています。これらのキーワードはプログラム内で他の用途に使用することはできません。予約されているキーワードの完全なリストの詳細は、ヘルプトピックの『キーワード』を参照してください。

アプリケーションのビルド

OpenESQL アプリケーションをビルドするには、次の操作を行う必要があります。

  1. SQL 文を EXEC SQL と END-EXEC のキーワードで囲んで、アプリケーションを記述します。Micro Focus Visual COBOL も使用している場合は、PC で OpenESQL アシスタントを使用してアプリケーションを開発し、UNIX システムへパブリッシュする方法が簡単です。Net Express OpenESQL アシスタントでは、SQL 文の開発にグラフィカルなドラッグアンドドロップの方法を提供しています。
  2. SQL コンパイラ指令を使用してアプリケーションをコンパイルします。
  3. [コントロール パネル] の [ODBC データソース] でデータソースを設定します (『データソース名の設定』の節を参照)。アプリケーションを使用して、ODBC データソースを設定します。

Net Express の基本インストールディレクトリのディレクトリ source には、sqlca.cpysqlda.cpy のコピーファイルが提供されており、通常の方法でプログラムにインクルードできます。

Net Express を使用して .exe を作成する場合は、SQL(GEN-CC2) 指令でプログラムをコンパイルしていない限り、必要なオブジェクトファイルがすべて自動的にリンクされます。

注:作成したアプリケーションを他のシステムに移動する場合には、移動先のシステムに適切なファイルが存在することを確認してください。

環境ファイル
32 ビットodbcrw32.dll
64 ビット odbcrw64.dll

デモンストレーションアプリケーション

システムの基本インストールディレクトリにある openesql ディレクトリには、さまざまなデモンストレーションアプリケーションが提供されています。

デモンストレーションアプリケーションを使用するには、1 つ以上の ODBC ドライバと、デモンストレーションに使用するために作成した DNS をインストールする必要があります。

デモンストレーションアプリケーションの中には、接続しているデータベースに EMP というテーブルが存在することを要求するものもあります。

すべての OpenESQL デモンストレーションアプリケーションではコンソールログが作成され、処理の進行状況を表示し、クエリー結果を表示する場合もあります。処理中にエラーが発生する場合は、エラーメッセージを表示して終了します。

次のアプリケーションが用意されています。

トランザクションの管理

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 の使用方法

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 ストアドプロシージャ

OpenESQL では、次の 2 つの文をストアドプロシージャとともに使用できます。

ストアドプロシージャでは、次の処理を実行できます。

注:ストアドプロシージャの機能はデータベースベンダごとに大きく異なり、各ベンダは上記の機能を部分的に提供しています。このため、データベース間でのストアドプロシージャの呼び出しは、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

動的 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.

Web サーバおよびアプリケーションサーバでの OpenESQL の使用方法

ここでは、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 サポート

XML ODBC ドライバがある場合は、ODBC データソースと同様に XML ファイルにアクセスするためにそのドライバを設定できます。そして、XML データソースで OpenESQL アシスタントを使用して SQL 文をビルドできます。

PERSIST 文

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 以降を使用する必要があります。

OpenESQL の Unicode サポート

一部のアプリケーションでは、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 の Unicode サポート』の章を参照してください。