![]() | 動的 SQL | DB2 | ![]() |
OpenESQL は、COBOL アプリケーションで埋め込み SQL を使用し、ODBC 対応のデータソースにアクセスするための統合型プリプロセッサです。
個別のプリプロセッサとは異なり、OpenEQL は、アプリケーションのコンパイル時に、SQL 指令を指定することによって制御します。
OpenESQL を使用するプログラムは、実行時に ODBC ドライバを使用して、リレーショナルデータベースにアクセスします。 ODBCドライバ製品は Server Express とは別に購入してください。
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)"
備考:上記の 3 つの方法を併用することはできません。いずれかの方法のみを使用してください。
SQL コンパイラ指令オプションについて、以下に説明します。
| オプション | 機能 | ||||||
| ALLOWNULLCHAR | SQL TYPE BINARY ホスト変数を使用するようにソースを変更しなくても、プログラムが、PIC X(n) ホスト変数を使用できる、あるいはCHAR 列で 16進数文字を選択/挿入/更新できるようにします。 | ||||||
| [NO]ANSI92ENTRY | OpenESQL の動作を SQL ANSI 92 のエントリ レベル規格に準拠させます。 | ||||||
| [NO]AUTOCOMMIT | 各 SQL 文を個別のトランザクションとして処理し、実行後ただちにコミットします。このオプションを指定せずにトランザクションに対応した ODBC ドライバを使用する場合には、ステートメントをトランザクションの一部として明示的にコミット(またはロールバック)する必要があります。 | ||||||
| [NO]AUTOFETCH | Microsoft SQL Server のデータソースで実行される SELECT 文に AUTOFETCH 属性を設定します。この指令でコンパイルを行うと、アプリケーションのパフォーマンスが向上します。この指令は、プログラムが SQL(TARGETDB=MSSQLSERVER) 指令でコンパイルされている場合のみ機能します。 | ||||||
| [NO]CHECK | 各 SQL 文をコンパイル時にデータベースに送信します。コンパイル時の構文チェックを指定する場合は、DB と PASS の指定も必要です。 | ||||||
| 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 を不要にします。このルーチンは、使用されている区切り文字を返すために変数がアクセスされると常に呼び出されます。通常、区切り文字はピリオドまたはコンマです。この指令には次のオプションがあります。
デフォルトは 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を推奨しています。 |
プログラムのコンパイル時に、技術的なサポートを要するエラーが発生した場合、サポート担当者から、問題の原因特定のためにデバッグファイルの提供を依頼されることがあります。こうしたデバッグファイルは、専用の 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 システムのソフトウェアのバグにかかわるエラーの場合に非常に有用です。 |
| ECMLIST | program-name.lst | このファイルは標準の COBOL のリストファイルで、内容は、 EXEC SQL 文を置き換えるために生成されたコードを示す擬似 COBOL コードです。また、プログラムをCHKECM(CTRACE) 指令および LIST 指令でコンパイルする必要があります。 |
プログラムからデータベース内のデータにアクセスするには、その前に対象データベースへの接続を確立する必要があります。
プログラムは、次の 2 通りの方法でデータベースに接続できます。
次のいずれかにあてはまる場合は、一般的に CONNET 文が使用されます。
通常、コンパイル時に指定したデータベースのみにアクセスするプログラムに使用します。SQL コンパイラ 指令の INIT オプションを指定すると、SQL コンパイラの DB オプションで指定されたデータソースに PASS オプションで指定されたログイン情報を使用して自動接続するコードが、コンパイラによってプログラムの開始部分に挿入されます。
アプリケーションによるデータベース操作が完了すると、データベースとの接続を解除する必要があります。この処理には DISCONNECT 文を使用します。
自動接続を使用している場合には、プログラムの終了時に OpenESQL によってデータソースとの接続が自動的に解除されます。
プログラムの異常終了時に、OpenESQL に接続の解除とロールバックを自動実行させるには、SQL コンパイラ 指令の INIT=PROT オプションを指定します。
OpenESQL では数多くのキーワードが予約されています。該当する単語は、プログラム内で他の用途に使用すべきではありません。予約済みキーワードのリストは、付録 『予約済みキーワード』に記載されています。
OpenESQL アプリケーションの作成に必要な手順は、次のとおりです。
コピーファイル、sqlca.cpy と sqlda.cpy は、$COBDIR/cpylib ディレクトリに提供されます。このディレクトリが COBCPY 環境変数に確実に設定されるようにする必要があります。
Server Express をインストールすると、openesql ディレクトリにさまざまなデモンストレーション アプリケーションがコピーされます。openesql ディレクトリは、Server Express のインストール ディレクトリの demo サブディレクトリ内に生成されています。
デモンストレーション アプリケーションを使用するには、1 つ以上の ODBC ドライバをインストールしておく必要があります。
デモンストレーションアプリケーションの中には、接続しているデータベースに EMP という表を要求するものもあります。
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
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(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
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 は渡すべき要素の数を含む整数型のホスト変数です。
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.
アプリケーションの中には、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 | ![]() |