前へ動的 SQL DB2次へ

第 7 章 OpenESQL

OpenESQL は、COBOL アプリケーションで埋め込み SQL を使用し、ODBC 対応のデータソースにアクセスするための統合型プリプロセッサです。

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

7.1 ODBC ドライバとデータベースクライアントソフトウェア

OpenESQL を使用するプログラムは、実行時に ODBC ドライバを使用して、リレーショナルデータベースにアクセスします。 ODBCドライバ製品は Server Express とは別に購入してください。


7.1.1 Oracle OCI サポート

Oracle データベースを使用しており、SQL (TARGETDB=ORACLEOCI) 指令でコンパイルする場合は、アプリケーションが実行時に ODBC 呼び出しではなく、OCI 呼び出しを行います。これは、配備されたアプリケーションが、潜在的なコストとパフォーマンスの利点を有する ODBC ドライバを必要としないことを意味します。

Oracle OCI を使用する場合は、次に示す OpenESQL 機能がサポートされていないことを知っておく必要があります。

Oracle OCI を使用する場合は、ODBC データソース名が適用されないため、CONNECT 文は実際の ORACLE データベースを参照します。

7.2 SQL コンパイラ指令

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

他のコンパイラ指令を指定できる個所ならどこでも、SQL 指令を指定することができます。つまり、次の場所に指定できます。


備考:上記の 3 つの方法を併用することはできません。いずれかの方法のみを使用してください。


SQL コンパイラ指令オプションについて、以下に説明します。

オプション 機能
ALLOWNULLCHARSQL TYPE BINARY ホスト変数を使用するようにソースを変更しなくても、プログラムが、PIC X(n) ホスト変数を使用できる、あるいはCHAR 列で 16進数文字を選択/挿入/更新できるようにします。
[NO]ANSI92ENTRY OpenESQL の動作を SQL ANSI 92 のエントリ レベル規格に準拠させます。
[NO]AUTOCOMMIT 各 SQL 文を個別のトランザクションとして処理し、実行後ただちにコミットします。このオプションを指定せずにトランザクションに対応した ODBC ドライバを使用する場合には、ステートメントをトランザクションの一部として明示的にコミット(またはロールバック)する必要があります。
[NO]AUTOFETCHMicrosoft SQL Server のデータソースで実行される SELECT 文に AUTOFETCH 属性を設定します。この指令でコンパイルを行うと、アプリケーションのパフォーマンスが向上します。この指令は、プログラムが SQL(TARGETDB=MSSQLSERVER) 指令でコンパイルされている場合のみ機能します。
[NO]CHECK 各 SQL 文をコンパイル時にデータベースに送信します。コンパイル時の構文チェックを指定する場合は、DBPASS の指定も必要です。
CHECKSINGLETON OpenESQL で単一行を取り出す SELECT文が複数行の結果を取得した場合にエラーを報告します。 この場合、OpenESQL は SQLCODE に -811 を設定します。
CONCAT=ASCII文字コード 文字列の連結演算子 (|) に使用する文字のASCIIコードを指定します。変更したい場合にだけ指定してください。 省略値は 33 です。
CHECKDUPCURSORこのオプションが設定されると、OpenESQL は、カーソルが既にオープンされていて、プログラムが NOANSI92ENTRY 指令でコンパイルされている場合、 SQLCODE -19516 を返します。プログラムが、NOANSI92ENTRY でコンパイルされた場合のディフォルトの振る舞いでは、カーソルを自動的にクローズし、再オープンします。
CONNECTIONPOOL=[DRIVER | ENVIRONMENT | NONE] ODBC 3.0 の接続プールを有効化します。接続プールを有効化すると、アプリケーションで閉じた接続がドライバ マネージャでは一定時間にわたって維持されるため、アプリケーションで同じ接続を再使用するときに接続を再確立する手間が省けます。接続プールは、特定の ODBC 環境を対象として設定するか、または各ドライバ単位で設定することができます。詳細については、ODBC のドキュメントをご覧ください。このオプションのデフォルト値は NONE で、省略すると接続プールは無効になります。接続プールは、接続を開閉する回数が多いアプリケーションのみに効果を発揮します。なお、Microsoft Transaction Server(MTS)など、接続プール機能を独自に実装した環境もあります。このオプションは、MTS を使用しない環境で ISAPI アプリケーションのパフォーマンスを向上させる場合などに効果的です。
[NO]CTRACE 実行時デバッグ情報を sqltrace.txt ファイルに書き出します。省略値は NOCTRACE です。
[NO]CURSORCASE ESQLVERSION の値が 2.0 であれば CURSORCASE、その他の場合には NOCURSORCASE がデフォルト値です。CURSORCASE を指定するとカーソル名の大文字と小文字が区別され、NOCURSORCASE では区別されません。旧バージョンの OpenESQL では、カーソル名の大文字と小文字は区別されています。
[NO]DB 接続するデータソースの名前。このオプションは、INIT オプションや CHECK オプションとともに使用します。
DBMAN=preprocessor 使用するプリプロセッサを指定します。つねに odbc が設定されるため、dbman=odbc となります。
生成された .int ファイルは、ファイルに埋め込まれた TARGETDB 番号以外は同じ内容になります。
[NO]DECDEL 十進データを格納する変数に対する GetLocaleInfo ルーチンを呼び出す OpenESQL を不要にします。このルーチンは、使用されている区切り文字を返すために変数がアクセスされると常に呼び出されます。通常、区切り文字はピリオドまたはコンマです。この指令には次のオプションがあります。
DECDEL=PERIOD常にピリオドが区切り文字となります。
DECDEL=COMMA常にコンマが区切り文字となります。
DECDEL=LOCAL毎回 GetLocaleInfo を呼び出して区切り文字を取得します。

デフォルトは NODECDEL で、十進変数が参照されるたびに OpenESQL は GetLocaleInfo を呼び出します。

[NO]DETECTDATE デフォルト値は NODETECTDATE。DETECTDATE を指定すると、OpenESQL は ODBC エスケープ シーケンスで文字ホスト変数をチェックし、次の時間データを取り出します。含む文字ホスト変数の値をチェックします。
{d<データ>} - 日付
{t<データ>} - 時刻
{ts<データ>} - タイムスタンプ
検出された値はバインドされます。文字カラムとしては使用されません。この処理は、サーバが日付表記文字列をサポートしていない場合(Microsoft Access など)に必要になります。また、汎用的なアプリケーションにも有効です。ただし、"{d" や "{t"、または "{ts" で開始するデータを含む文字カラムが存在する場合には問題が発生する可能性があります。
[NO]ESQLVERSION OpenESQL の構文レベルを設定します。
[NO]FIPSFLAG SQL文の FIPS規格準拠性をフラグします。 (NIST準拠のためにのみ用意されています)。省略値は NOFIPSFLAG です。
[NO]IGNORE-NESTED=program-id 入れ子のCOBOLプログラムで 指定されたプログラムIDの個所からデータベースインタフェースコードを生成します。 単に、IGNORE-NESTED を指定すると、ソースファイル名と同じプログラムIDが指定されたものとみなします。 省略値は NOIGNORE-NESTED です。
[NO]INIT プリプロセッサにデータベース接続用のコードを自動生成させます。INIT を指定する場合には、DB オプションと PASS オプションも指定する必要があります。
[NO]NIST OpenESQL の動作を NIST による SQL ANSI 92 エントリ レベル規格に準拠させます。
NOT=ASCII文字コード NOT記号 (¬) のためのASCIIコードを指定します。 変更したい場合にのみ指定してください。省略値は 170 です。
ODBCTRACE= [ALWAYS | NEVER | USER] USER (デフォルト値)は、ODBC トレース処理をコントロール パネルで制御する設定です。ODBC コントロール パネルからトレース対象のファイルを指定できます。ALWAYS は ODBC トレース処理を指令で制御する設定であり、IDE でのアプリケーション開発に適しています。ODBC コントロール パネルの設定にかかわらず、この設定ではつねにトレース ファイル(MFSQLTRACE.LOG)が生成されます。通常の開発では、カレント プロジェクトの Debug ディレクトリ(プロジェクトのビルド設定によっては Release ディレクトリ)がトレース ファイルの格納先になります。NEVER を設定すると、アプリケーションのトレースは実行されず、コントロール パネルの設定も無視されます。ODBC トレース ファイルには重要な情報が含まれる場合があるため、情報の安全性を重視する場合には NEVER を使用します。
ODBCV3 この指令は、アプリケーションを ODBC Version 3 のアプリケーションとして登録します。指定しないと、アプリケーションは自身を ODBC Version 2 アプリケーションとして登録します。ODBC Version 3 アプリケーションとして登録すると、パフォーマンスが多少向上します。ただし、SQLCODE および SQLSTATE に対して別の値が返えされ、エラーおよび警告状態となります。この指令を使用する場合は、十分に注意してください。
[NO]PARAMARRAY すべての入力パラメータに ODBC 配列バインドを使用します(ドライバが同機能をサポートしている場合のみ)。デフォルト値は PARAMARRAY。
[NO]PASS データソースへの接続時に使用するログイン名。このオプションは INIT オプションや CHECK オプションとともに使用します。
PREFETCH=n アプリケーションはこの値を使用して、OpenESQL がカーソルのブロックフェッチ(block fetches)を使用するように要求できます。これにより、プログラムロジックを変更しなくても、配列フェッチ(array fetching)と同様にパフォーマンスが向上します。パフォーマンスがどれだけ向上するかは、n の値、および使用中の ODBC ドライバにプリフェッチ(prefetching)が構成されているかどうかで異なります。n の値が 1000 未満であると、フェッチされる行数はバッチごとに制御され、すべてのカーソルで同じ行数がフェッチされます。n が 1000 以上であると、カーソルごとにプリフェッチバッファのサイズを設定します。すべてのカーソルのバッファサイズは同じとなりますが、プリフェッチされる行数は、各カーソルに対するクエリーによって返される行全体のサイズにより異なります。PREFETCH=n が Microsoft SQL Server で使用されていると、AUTOFETCH も読み取り専用カーソルとなります。読み取り専用でないカーソルは強制的にキー設定(keyset) カーソルとなり、位置付け更新に使用されます。PREFETCH=n は、DB2、Oracle および SQL Server でのみサポートされています。
[NO]QUALFIX プリプロセッサがホスト変数を ODBCに宣言するときに 3文字の修飾語を付加します。 省略値は QUALFIX です。
[NO]RESULTARRAY すべての出力パラメータに ODBC 配列バインドを使用します(ドライバがこの機能をサポートしている場合のみ)。デフォルト値は RESULTARRAY。
STMTCACHE OpenESQLが使用する動的SQL文に対する キャッシュサイズを指定します。省略時のサイズは 20 です。 この値の設定と、アプリケーションとデータソースによっては、 性能の向上が得られる場合もありますし、メモリ不足エラーを生じる場合もあります。
[NO]TARGETDB 使用するデータベースエンジンを 1 つだけ指定します。OpenESQL は、特定のデータベース用に最適化を行います。現在は 2 つのオプションがサポートされています。Oracle V7.x を使用している場合は、TARGETDB=ORACLE7 を指定し、ODBC ドライバの代わりに Oracle OCI を使用する場合は、TARGETDB=ORACLEOCI を指定します。
THREAD=[SHARE | ISOLATE] ISOLATE を指定すると、接続やカーソルがスレッドごとに生成されます。この設定は、マルチスレッドのアプリケーション サーバ環境(IIS/ISAPI など)に使用します。一方、SHARE を指定した場合には、接続やカーソルはすべてのスレッドを対象として生成されます。あるスレッドでコード内に記述した CONNECT ステートメントを実行した後、別のスレッドで同じステートメントを実行すると、最初のスレッドですでに接続が開かれているためエラーになります。ISOLATE を指定した場合には、各スレッドで個別に接続を開くことができます。このオプションのデフォルト値は SHARE です。
[NO]USECURLIB[NO | YES | IFNEEDED] ODBCのカーソルライブラリの使用を制御します。 カーソルライブラリは、下位で使用されているデータベースドライバが スクロールカーソルの機能をサポートしない場合に、代わってこれを提供します。 また、位置付け更新をシミュレートします。 USECURLIB=YES を設定すると、常にカーソルライブラリが使用されます。 USERCURLIB=NO を設定すると、カーソルライブラリは使用されません。 USERCURLIB=IFNEEDED を設定すると、アプリケーションがドライバが サポートしないと思われる機能を使用しようとしたときにだけ、カーソルライブラリ が使用されます。 スクロールカーソルをカーソルライブラリで使用するには、STATICカーソル を使用する必要があります。 位置付け更新をカーソルライブラリで使用するには、OPTCCVALコンカレンシ を指定する必要があります。 位置付け更新は、一時に複数の行に対して実行される可能性があることに注意してください。 この理由により、位置付け更新よりも主キーによる WHERE条件のUPDATEを推奨しています。

7.3 デバッグファイルの生成

プログラムのコンパイル時に、技術的なサポートを要するエラーが発生した場合、サポート担当者から、問題の原因特定のためにデバッグファイルの提供を依頼されることがあります。こうしたデバッグファイルは、専用の SQL コンパイラ指令を指定して取得します。独自にデバッグ作業を行う場合にもこれらの指令が役立ちます。次の指令があります。

指令
生成ファイル
ファイル内の情報
CHKECM(CTRACE) ecmtrace.txt このファイルの内容は、EXEC SQL 文を置き換えるために生成されたコードを示す擬似 COBOL コードです。このコードは、IBM DB2 COBOL precompiler からの出力と同等です。
CHKECM(TRACE) ecmtrace.txt このファイルの内容は、DB2 ECM とその Compiler との間でどんな情報が渡されるかの詳細です。エラーが発生して無効な構文が生成された場合、このファイルは問題が発生した場所を分離しやすくするのに必要になります。
SQL(CTRACE) sqltrace.txt このファイルの内容は、OpenESQL Precompiler Services に渡された情報の詳細な一覧と結果です。このファイルは、OpenESQL ECM、および OpenESQL システムのソフトウェアのバグにかかわるエラーの場合に非常に有用です。
ECMLISTprogram-name.lstこのファイルは標準の COBOL のリストファイルで、内容は、 EXEC SQL 文を置き換えるために生成されたコードを示す擬似 COBOL コードです。また、プログラムをCHKECM(CTRACE) 指令および LIST 指令でコンパイルする必要があります。

7.4 データベース接続

プログラムからデータベース内のデータにアクセスするには、その前に対象データベースへの接続を確立する必要があります。

プログラムは、次の 2 通りの方法でデータベースに接続できます。

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

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

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

7.5 キーワード

OpenESQL では数多くのキーワードが予約されています。該当する単語は、プログラム内で他の用途に使用すべきではありません。予約済みキーワードのリストは、付録 『予約済みキーワード』に記載されています。

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

OpenESQL アプリケーションの作成に必要な手順は、次のとおりです。

  1. アプリケーションをコーディングします。Micro Focus Net Express も使用している場合は、パーソナルコンピュータで OpenESQL Assistant を使用してアプリケーションを開発し、それを UNIX システムで公開するほうが簡単であることがわかります。Net Express OpenESQL Assistant では、SQL 文の開発にグラフィカルなドラッグアンドドロップの方法を提供しています。

  2. SQL 指令と適切なオプションの指定を確実に行い、アプリケーションをコンパイルします。少なくとも SQL を指定します。

  3. ODBC データソースを設定します。方法についてはお使いの ODBCドライバのドキュメントを参照してください。

コピーファイル、sqlca.cpysqlda.cpy は、$COBDIR/cpylib ディレクトリに提供されます。このディレクトリが COBCPY 環境変数に確実に設定されるようにする必要があります。

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

Server Express をインストールすると、openesql ディレクトリにさまざまなデモンストレーション アプリケーションがコピーされます。openesql ディレクトリは、Server Express のインストール ディレクトリの demo サブディレクトリ内に生成されています。

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

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

OpenESQL を使用するデモンストレーション アプリケーションを次に示します。これらのアプリケーションは、いずれかも処理の進行状況をコンソールに表示し、照会結果を表示する場合もあります。処理中にエラーが発生すると、エラー メッセージを表示して終了します。

次のプログラムが提供されます。

7.8 トランザクション管理

OpenESQL では、COMMIT 文と ROLLBACK 文によって ODBC のトランザクション管理機能を制御できます。ODBC では、各ステートメントの実行後にトランザクションが標準で自動コミットされますが、OpenESQL では他の SQL システムとの互換性を考慮して、この機能は無効化されています。自動コミットを有効化するには、SQL コンパイラ 指令の AUTOCOMMIT オプションを指定してください。


注: すべての ODBC ドライバがトランザクション処理を実装しているとはかぎりません。 トランザクション処理を実装していないドライバは、データベースへの即時的で永続的な更新を行います。


7.9 データ型

以下の表は、SQL と COBOL 間でデータ型を変換するときに、OpenESQL が用いるマッピングを示したものです。

SQL のデータ型
COBOL の Picture
注記
SQL_CHAR(n)
PIC X(n)

SQL_VARCHAR(n)
PIC X(n)

SQL_LONGVARCHAR
PIC X(max) max = 32K
SQL_DECIMAL(p,s) PIC 9(p-s)V9(S) COMP-3 p = 精度 (全桁数)
s = スケール (小数点以下の桁数)
SQL_NUMERIC(p,s) PIC 9(p-s)V9(S) COMP-3
SQL_SMALLINT PIC S9(4) COMP-5
SQL_INTEGER PIC S9(9) COMP-5
SQL_REAL COMP-2
SQL_FLOAT COMP-2
SQL_DOUBLE COMP-2
SQL_BIT PIC S9(4) COMP-5
SQL_TINYINT PIC S9(4) COMP-5
SQL_BIGINT PIC S9(18) COMP-3
SQL_BINARY(n) PIC X(n)
SQL_VARBINARY(n) PIC X(n)
SQL_LONVARBINAR PIC X(max)
SQL_DATE PIC X(10) yyyy-mm-dd
SQL_TIME PIC X(8) hh:mm:ss
SQL_TIMESTAMP PIC X(29) yyyy-mm-dd hh:mm:ss.ffffff

ODBC では、日付が yyyy-mm-dd、時刻が hh:mm:ss の形式で表記されます。これらの形式は、データソース側の日付や時刻の表記形式と一致しない可能性があります。入力文字ホスト変数には、データソース側の形式を使用できます。ほとんどのデータソースでは 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'} - for date.
{t 'hh:mm:ss'} - for time.
{ts yyyy-mm-dd hh:mm:ss[.f...] - for timestamp.

以下のサンプルプログラムでは、使用される日付、時間およびタイムスタンプのエスケープシーケンスを示しています。

 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.
* データソースへの接続。これは、Server Express に
* 提供されるサンプルのデータソースの 1 つです。
     EXEC SQL
         CONNECT TO 'Server Express Sample1' USER 'admin'
     END-EXEC
* テーブルが存在する場合は、それを削除します。
     EXEC SQL
         DROP TABLE DT
     END-EXEC

* DATE、TIME、DATE および TIME の列を持つテーブルを作成します。 
* 
* 注:   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'},  *> Set just the date part
               {t '12:21:54'  },  *> Set just the time part
               {ts '1966-01-24 08:21:56' } *> Set both parts
                   )
     END-EXEC

* 挿入した値を取り出します。
   
     EXEC SQL
         SELECT myDate
               ,myTime
               ,myTimestamp
           INTO
                :date-field1
               ,:date-field2
               ,:date-field3
           FROM DT
           where id = 1
     END-EXEC

* 結果を表示します。

     display 'where the date part has been set :' 
             date-field1
     display 'where the time part has been set :' 
             date-field2
     display 'NOTE, most data sources will set a default'
             ' for the date part '
     display 'where both parts has been set :' 
             date-field3

* テーブルを削除します。
   
     EXEC SQL
         DROP TABLE DT
     END-EXEC

* データソースから切断します。

     EXEC SQL
         DISCONNECT CURRENT
     END-EXEC

     stop run.

あるいは、日付・時刻用のホスト変数を SQL TYPE を使って for 宣言することもできます、以下のホスト変数を宣言します :

01  my-id          pic s9(09) 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ホスト変数を使ったINSERT文
     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 vlaue (
           :my-id
          ,:my-date
          ,:my-time
          ,:my-timestamp  )
     END-EXEC

7.10 SQLCA の使用

SQLCA データ構造体は、Server Express インストール ディレクトリの cpylib サブディレクトリ内の sqlca.cpy ファイルで定義されています。SQLCA をプログラムで使用するには、Data Division に次の文を記述します。

EXEC SQL INCLUDE SQLCA END-EXEC

この文を記述しない場合でも、COBOL コンパイラによって自動的に領域が割り当てられますが、プログラムはその領域にはアクセスできません。ただし、sqlcode (または sqlstate)データ項目を別に宣言すれば、各 SQL EXEC 文の実行後に SQLCA 内の対応フィールドをユーザ定義フィールドにコピーするコードが COBOL コンパイラによって生成されます。

MFSQLMESSAGETEXT データ項目を宣言した場合には、sqlcode にゼロ以外の値が検出されるたびに、例外条件の説明によって同データ項目が更新されます。MFSQLMESSAGETEXT は文字データ項目 PIC X(n) として宣言します(n は任意の有効値)。ODBC エラー メッセージは、SQLCA メッセージ フィールドのサイズ(70 バイト)を超過することが少なくありません。そのため、MFSQLMESSAGETEXT データ項目はとくに有効です。


備考:SQLCA や SQLCODE、SQLSTATE、および MFSQLMESSAGETEXT は、いずれもホスト変数として宣言する必要はありません。


7.11 ストアド プロシージャ

OpenESQL では、2 つの文(CALL および EXECSP)をストアド プロシージャと組み合わせて使用できます。

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


備考:ストアド プロシージャの機能はデータベース製品ごとに大きく異なり、各製品は上記の機能を部分的に実装しているに過ぎません。したがって、異なるデータベース製品間でのストアド プロシージャ呼び出しの移植性は、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 は渡すべき要素の数を含む整数型のホスト変数です。

7.12 位置付け更新

ODBC は、カーソルを使用して直近にフェッチされた行を更新する、位置付け更新をサポートしています。ですが、すべてのドライバが位置付け更新をサポートしているとは限りません。


注: ホスト変数と位置付け更新を併用することはできません。


ODBC ドライバの中には、カーソルに使用される選択文の中に位置付け更新を可能にする FOR UPDATE 句が必要なドライバもあります。ほとんどのデータソースは、SET 文によって、あるいは DECLARE CURSOR 文の中に、CROLLOPTION と CONCURRENCY の組み合わせを指定する必要があります。これが正しく指定されていないと、ODBC Cursor Library は、SQL(USECURLIB=YES) 指令でコンパイルし、SCROLLOPTION STATIC および CONCURRENCY OPTCCVAL (または OPTIMISTIC) を使用して、位置付け更新の実装を制限します。ODBC Cursor Library を使用している場合に、複数の行が更新されるのを防ぐには、更新されるテーブルの主キー列(preimary key column)をカーソルクエリーにインクルードしてください。

$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 Error = " sqlstate " " sqlcode
      display MFSQLMESSAGETEXT
  *> 実行を停止します。
      exit.

7.13 OpenESQLでのUnicodeサポート

アプリケーションの中には、Microsoft SQL Server のデータソースを ANSI に変換せずに取り出したり、格納したりするものがあります。OpenESQL の以前のバージョンでは、データが自動的に変換されていないと、データにアクセスする手段はありませんでした。しかし、現在のバージョンでは、OpenESQL と Server Express は、ANSI に変換されていなくても、新しいタイプのホスト変数を使用することで、ユニコードのデータに直接アクセスできます。Microsoft SQL Server は、次の 3 つのタイプのUnicode列をサポートしています。

自動的にデータを変換せずにこうした列にアクセスするには、次のようにホスト変数を定義します。

PIC N(xx) USAGE NATIONAL

ここで、xx は、列のサイズです。現在のバージョンでは、この形式は、固定長データと可変長データの両方をサポートしています。可変長データは、データの挿入あるいは更新の際に、列に対するデータの最後であることを示すヌルで終了します。データがソースデータから取り出されると、ホスト変数の最後までスペースが充填されます。

例えば、次のプログラムは、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 Error = " sqlstate " " sqlcode
           display MFSQLMESSAGETEXT
       *> 実行を停止します。
           exit.

これは、INCLUDE copybook Employees の定義以外、ANSI のデータを取り出すのと同じコードです。INCLUDE copybook Employees は次のよう定義します。

      *>  --------------------------------------------------------------
      *> 従業員テーブルに対する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.


Copyright © 2004 Micro Focus International Limited. All rights reserved.
本書ならびに使用されている固有の商標と商品名は国際法で保護されています。

前へ動的 SQL DB2次へ