![]() | 動的 SQL | DB2 | ![]() |
OpenESQL は、COBOL アプリケーションで埋め込み SQL を使用し、ODBC 対応のデータソースにアクセスするための統合型プリプロセッサです。
個別のプリプロセッサとは異なり、OpenEQL は、アプリケーションのコンパイル時に、SQL 指令を指定することによって制御します。
OpenESQL を使用するプログラムは、実行時に ODBC ドライバを使用して、リレーショナルデータベースにアクセスします。Server Express では、主要なリレーショナルデータベースシステムへのアクセスを提供する高パフォーマンスの ODBC ドライバ群を、提供しています。Server Express をインストールするときに、ODBC ドライバコンポーネントを、必要に応じてインストールすることができます。これらのドライバがインストールされていることを確認するには、メインディレクトリ COBDIR の下にあるサブディレクトリ、odbc を調べます。
ODBC ドライバの設定に関する全文書は、付録の『DataDirect ODBC ドライバ』に記載されています。この付録では、各 ODBC ドライバの要件に関する情報を提供しています。ODBC ドライバの中には、データベースのクライアントソフトウェアのインストールが必要なものもあります。
esqlconf ユーティリティは、環境情報をセットアップし、データベースへの接続のテストに役立ちます。esqlconf の詳細につては、この章の『デモンストレーションアプリケーション』の節を参照してください。
注:
Oracle データベースを使用しており、SQL (TARGETDB=ORACLEOCI) 指令でコンパイルする場合は、アプリケーションが実行時に ODBC 呼び出しではなく、OCI 呼び出しを行います。これは、配備されたアプリケーションが、潜在的なコストとパフォーマンスの利点を有する ODBC ドライバを必要としないことを意味します。
Oracle OCI を使用する場合は、次に示す OpenESQL 機能がサポートされていないことを知っておく必要があります。
Oracle OCI を使用する場合は、ODBC データソース名が適用されないため、CONNECT 文は実際の ORACLE データベースを参照します。
埋め込み SQL 文を含むプログラムをコンパイルする場合は、コンパイラ指令 SQL と適切なオプションを指定する必要があります。プログラムから呼び出す ODBC ドライバは、アクセスするデータソースによって決定されます。
他のコンパイラ指令を指定できる個所ならどこでも、SQL 指令を指定することができます。つまり、次の場所に指定できます。
$set sql(dbman=odbc, autocommit)
cob -V testconn.cbl -C"anim SQL(DBMAN=ODBC)"
備考:上記の 2 つの方法を併用することはできません。いずれかの方法のみを使用してください。
SQL コンパイラ指令オプションについて、以下に説明します。
| オプション | 機能 |
| [NO]ANSI92ENTRY | OpenESQL の動作を SQL ANSI 92 のエントリ レベル規格に準拠させます。 |
| [NO]AUTOCOMMIT | 各 SQL 文を個別のトランザクションとして処理し、実行後ただちにコミットします。このオプションを指定せずにトランザクションに対応した ODBC ドライバを使用する場合には、ステートメントをトランザクションの一部として明示的にコミット(またはロールバック)する必要があります。 |
| [NO]CHECK | 各 SQL 文をコンパイル時にデータベースに送信します。コンパイル時の構文チェックを指定する場合は、DB と PASS の指定も必要です。 |
| CONNECTIONPOOL=[DRIVER | ENVIRONMENT | NONE] | ODBC 3.0 の接続プールを有効化します。接続プールを有効化すると、アプリケーションで閉じた接続がドライバ マネージャでは一定時間にわたって維持されるため、アプリケーションで同じ接続を再使用するときに接続を再確立する手間が省けます。接続プールは、特定の ODBC 環境を対象として設定するか、または各ドライバ単位で設定することができます。詳細については、ODBC のドキュメントをご覧ください。このオプションのデフォルト値は NONE で、省略すると接続プールは無効になります。接続プールは、接続を開閉する回数が多いアプリケーションのみに効果を発揮します。なお、Microsoft Transaction Server(MTS)など、接続プール機能を独自に実装した環境もあります。このオプションは、MTS を使用しない環境で ISAPI アプリケーションのパフォーマンスを向上させる場合などに効果的です。 |
| [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]INIT | プリプロセッサにデータベース接続用のコードを自動生成させます。INIT を指定する場合には、DB オプションと PASS オプションも指定する必要があります。 |
| [NO]NIST | OpenESQL の動作を NIST による SQL ANSI 92 エントリ レベル規格に準拠させます。 |
| 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]RESULTARRAY | すべての出力パラメータに ODBC 配列バインドを使用します(ドライバがこの機能をサポートしている場合のみ)。デフォルト値は RESULTARRAY。 |
| [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 です。 |
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
プログラムからデータベース内のデータにアクセスするには、その前に対象データベースへの接続を確立する必要があります。
プログラムは、次の 2 通りの方法でデータベースに接続できます。
次のいずれかにあてはまる場合は、一般的に CONNET 文が使用されます。
通常、コンパイル時に指定したデータベースのみにアクセスするプログラムに使用します。SQL コンパイラ 指令の INIT オプションを指定すると、SQL コンパイラの DB オプションで指定されたデータソースに PASS オプションで指定されたログイン情報を使用して自動接続するコードが、コンパイラによってプログラムの開始部分に挿入されます。
アプリケーションによるデータベース操作が完了すると、データベースとの接続を解除する必要があります。この処理には DISCONNECT 文を使用します。
自動接続を使用している場合には、プログラムの終了時に OpenESQL によってデータソースとの接続が自動的に解除されます。
プログラムの異常終了時に、OpenESQL に接続の解除とロールバックを自動実行させるには、SQL コンパイラ 指令の INIT=PROT オプションを指定します。
OpenESQL では数多くのキーワードが予約されています。該当する単語は、プログラム内で他の用途に使用すべきではありません。予約済みキーワードのリストは、付録 『予約済みキーワード』に記載されています。
OpenESQL アプリケーションの作成に必要な手順は、次のとおりです。
コピーファイル、sqlca.cpy と sqlda.cpy は、$COBDIR/cpylib ディレクトリに提供されます。このディレクトリが COBCPY 環境変数に確実に設定されるようにする必要があります。
OpenESQL ランタイムモジュールは、非スレッドアプリケーションでは odbcrunx.so 、マルチスレッドアプリケーションでは odbcrunx_t.so となります。このモジュールは、アプリケーション配布時に、アプリケーションに確実に取り込まれるようにする必要があります。
Server Express をインストールすると、openesql ディレクトリにさまざまなデモンストレーション アプリケーションがコピーされます。openesql ディレクトリは、Server Express のインストール ディレクトリの demo サブディレクトリ内に生成されています。
デモンストレーション アプリケーションを使用するには、1 つ以上の ODBC ドライバをインストールしておく必要があります。多くの ODBC ドライバが Server Express とともに自動的にインストールされます。
デモンストレーションアプリケーションの中には、接続しているデータベースに EMP という表を要求するものもあります。スクリプトが提供されているため、$COBDIR 下の odbc/demo ディレクトリのさまざまなデータベースエンジンにこの表を作成することができます。Server Express により提供された odbc.ini ファイルを使用する場合は、サンプルの Dbase データベースがすでにセットアップされています。プログラム実行時に、このデータベースを使用するには、次の手順を行います。
OpenESQL を使用するデモンストレーション アプリケーションを次に示します。これらのアプリケーションは、いずれかも処理の進行状況をコンソールに表示し、照会結果を表示する場合もあります。処理中にエラーが発生すると、エラー メッセージを表示して終了します。
次のプログラムが提供されます。
testconn.cbl ファイルは、CONNECT 文と DISCONNECT 文のさまざまなフォーマットの使用方法を示す OpenESQL のデモンストレーションプログラムです。
catalog.cbl ファイルは、COBOL からの ODBC カタログ機能の使いかたを示す OpenESQL のデモンストレーションプログラムです。
static.cbl ファイルは、COBOL からの 基本的な SQL 機能の使いかたを示す OpenESQL のデモンストレーションプログラムです。INSERT、UPDATE、DELETE、SELECT INTO および カーソルを使用したSELECT の使いかたの例を解説しています。また、COMMIT および ROLLBACK の使いかたも示しています。
dynquery.cbl は 、COBOL からの 動的 SQL 機能の使いかたを示す OpenESQL のデモンストレーションプログラムです。 ユーザが何らかの SQL 文を入力し、プログラムがそれらを実行する機能を提供しています。SQL 文を用意する方法を示し、プログラムのコンパイル時に列のタイプがわからない場合に、SQLDA 構造体を使用して、列からデータを取り出す方法を示します。
上記で説明した EMP 表にアクセスしている場合、サンプルのクエリーは次のようなものになります。
select FIRST_NAME, LAST_NAME, HIRE_DATE, SALARY from EMP
このプログラムは、odbc.ini ファイルのセットアップを支援する設定プログラムです。odbc.ini ファイルには、OpenESQL を使用するとき、プログラムが使用するデータソースについての情報があります。
このプログラムはソースの形式で提供されているため、保有する ODBC ドライバの情報をさらに追加したり、データベースクライアントの検出をさらに行うことができます。アプリケーションで OpenESQL を使用する場合は、アプリケーションのインストールルーチンに esqlconf のコードの一部を使用して、ユーザのために環境を正しくセットアップする場合もあります。
Esqlconf は odbc.ini ファイルを検索しますが、まず ODBCINI 環境変数を検索し、次に HOME ディレクトリを、最後にローカルディレクトリを検索します。ファイルが見つかると、それを編集するオプションか、新しいファイルを作成するオプションが提供されます。ファイルが見つからない場合は、新しいファイルを作成するかどうかを尋ねてきます。新しいファイルは、つねにカレントディレクトリに作成されます。
Esqlconf は、次に示すオプションを提供します。
これによってデータソースの詳細を変更することができます。
これは、環境が正しく設定されていることを確認し、ODBC ドライバのロードを確実にします。 Oracle、Sybase または Informix データベースを使用している場合は、データベースクライアントソフトウェアがインストールされていることを確認します。最後に、データソースへの接続を試します。
OpenESQL では、COMMIT 文と ROLLBACK 文によって ODBC のトランザクション管理機能を制御できます。ODBC では、各ステートメントの実行後にトランザクションが標準で自動コミットされますが、OpenESQL では他の SQL システムとの互換性を考慮して、この機能は無効化されています。自動コミットを有効化するには、SQL コンパイラ 指令の AUTOCOMMIT オプションを指定してください。
注: すべての ODBC ドライバがトランザクション処理を実装しているとはかぎりません。 トランザクション処理を実装していないドライバは、データベースへの即時的で永続的な更新を行います。
以下の表は、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(26) | yyyy-mm-dd hh:mm:ss.ffffff |
ODBC では、日付が yyyy-mm-dd、時刻が hh:mm:ss の形式で表記されます。これらの形式は、データソース側の日付や時刻の表記形式と一致しない可能性があります。入力文字ホスト変数には、データソース側の形式を使用できます。ほとんどのデータソースでは PIC X(26) を使用してください。次に例を示します。
01 mydate PIC x(26). ... 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(26).
01 date-field2 pic x(26).
01 date-field3 pic x(26).
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.
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 は、いずれもホスト変数として宣言する必要はありません。
OpenESQL では、2 つの文(CALL および EXECSP)をストアド プロシージャと組み合わせて使用できます。
CALL は、ODBC ストアド プロシージャの呼び出しに使用します。
Microsoft SQL Server 対応 Micro Focus Embedded SQL Toolkit との後方互換を提供します。
ストアド プロシージャでは次の処理を実行できます。
備考:ストアド プロシージャの機能はデータベース製品ごとに大きく異なり、各製品は上記の機能を部分的に実装しているに過ぎません。したがって、異なるデータベース製品間でのストアド プロシージャ呼び出しの移植性は、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 | ![]() |