前へ動的 SQL DB2次へ

第 7 章 OpenESQL

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

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

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

OpenESQL を使用するプログラムは、実行時に ODBC ドライバを使用して、リレーショナルデータベースにアクセスします。Server Express では、主要なリレーショナルデータベースシステムへのアクセスを提供する高パフォーマンスの ODBC ドライバ群を、提供しています。Server Express をインストールするときに、ODBC ドライバコンポーネントを、必要に応じてインストールすることができます。これらのドライバがインストールされていることを確認するには、メインディレクトリ COBDIR の下にあるサブディレクトリ、odbc を調べます。
この版の Server Expressにバンドルされている ODBCドライバは、OEM提供元の Data Direct Technologies による日本語環境下での動作検証が完了していません。評価目的でのみお使いいただくか、Data Direct Technologies から正しいバージョンのODBCドライバ製品を購入してください。

ODBC ドライバの設定に関する全文書は、ODBCドライバの readmeファイルに記載されています。各 ODBC ドライバの要件に関する情報もそこで提供しています。ODBC ドライバの中には、データベースのクライアントソフトウェアのインストールが必要なものもあります。

esqlconf ユーティリティは、環境情報をセットアップし、データベースへの接続のテストに役立ちます。esqlconf の詳細につては、この章の『デモンストレーションアプリケーション』の節を参照してください。


注:


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 指令を指定することができます。つまり、次の場所に指定できます。


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


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

オプション 機能
[NO]ANSI92ENTRY OpenESQL の動作を SQL ANSI 92 のエントリ レベル規格に準拠させます。
[NO]AUTOCOMMIT 各 SQL 文を個別のトランザクションとして処理し、実行後ただちにコミットします。このオプションを指定せずにトランザクションに対応した ODBC ドライバを使用する場合には、ステートメントをトランザクションの一部として明示的にコミット(またはロールバック)する必要があります。
[NO]CHECK 各 SQL 文をコンパイル時にデータベースに送信します。コンパイル時の構文チェックを指定する場合は、DBPASS の指定も必要です。
CHECKSINGLETON OpenESQL で単一行を取り出す SELECT文が複数行の結果を取得した場合にエラーを報告します。 この場合、OpenESQL は SQLCODE に -811 を設定します。
CONCAT=ASCII文字コード 文字列の連結演算子 (|) に使用する文字のASCIIコードを指定します。変更したい場合にだけ指定してください。 省略値は 33 です。
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]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 を使用します。
[NO]PARAMARRAY すべての入力パラメータに ODBC 配列バインドを使用します(ドライバが同機能をサポートしている場合のみ)。デフォルト値は PARAMARRAY。
[NO]PASS データソースへの接続時に使用するログイン名。このオプションは INIT オプションや CHECK オプションとともに使用します。
[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 データソース

ODBC ドライバをインストールすると、odbc.ini ファイルにはいくつかのデータソースがセットアップされます。dBase データソースは次のようになります。

[dBase]
Driver=INSTALLDIR/lib/C5dbf14.sl
Description=dBase
Database=INSTALLDIR/demo

2 箇所の INSTALLDIR を ODBC をインストールしたディレクトリパスに変更する必要があります。たとえば、ODBC ディレクトリが /home/fritz/odbc の場合は、次のようになります。

[dBase]
Driver=/home/fritz/odbc/lib/C5dbf14.sl
Description=dBase
Database=/home/fritz/odbc/demo

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 データソースを設定します。

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

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

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

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

デモンストレーションアプリケーションの中には、接続しているデータベースに EMP という表を要求するものもあります。スクリプトが提供されているため、$COBDIR 下の odbc/demo ディレクトリのさまざまなデータベースエンジンにこの表を作成することができます。Server Express により提供された odbc.ini ファイルを使用する場合は、サンプルの Dbase データベースがすでにセットアップされています。プログラム実行時に、このデータベースを使用するには、次の手順を行います。

  1. データソース名の入力を求められたら、Dbase と入力します。

  2. ユーザ名とパスワードを空白のままにします。

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 は渡すべき要素の数を含む整数型のホスト変数です。


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

前へ動的 SQL DB2次へ