Pro*COBOL®

プログラマーズ・ガイド

12c リリース1 (12.1)

E48238-02(原本部品番号:E53282-01)

2014年5月

Pro*COBOLプログラマーズ・ガイド, 12c リリース1 (12.1)

E48238-02

Copyright © 1996, 2014, Oracle and/or its affiliates.All rights reserved.

原本著者: Simon Watt

原本協力著者: Syed Mujeed Ahmed、Jack Melnick、Neelam Singh、Subhranshu Banerjee、Beethoven Cheng、Michael Chiocca、Nancy Ikeda、Alex Keh、Thomas Kurian、Shiao-Yen Lin、Diana Lorentz、Ajay Popat、Chris Racicot、Pamela Rothman、Simon Slack、Gael Stevens

原本協力者: Valarie Moore

原本協力者:  Oracle Database 12cのドキュメントを、本リリースに携わった全員にとって創造の源となったMark Townsendに捧げます。

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs.No other rights are granted to the U.S. Government.

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

目次

タイトルおよび著作権情報

はじめに

- 対象読者

- ドキュメントのアクセシビリティについて

- 関連ドキュメント

- 表記規則

このリリースの『Pro*COBOLプログラマーズ・ガイド』での変更点

- Pro*COBOL 12c リリース1 (12.1)での変更点

第I部 概要および概念

1 概要

- Pro*COBOLの概要

- Pro*COBOLプリコンパイラ

- 代替言語

- Pro*COBOLプリコンパイラを使用する利点

- SQL言語

- PL/SQL言語

- Pro*COBOLの機能および利点

- ディレクトリ構造

- ヘッダー・ファイル

- ライブラリ・ファイル

- 既知の問題、制限事項および対処方法

- 互換性、アップグレードおよび移行

2 プリコンパイラの概念

- 埋込みSQLプログラミングの基本概念

- 埋込みSQLアプリケーションの開発ステップ

- 埋込みSQL文

- 実行文および宣言部

- 埋込みSQLの構文

- 静的SQL文と動的SQL文

- 埋込みPL/SQLブロック

- ホスト変数および標識変数

- Oracleデータ型

- 表

- エラーおよび警告

- SQLCODE/SQLSTATE状態変数

- SQLCA状態変数

- WHENEVER文

- ORACA

- プリコンパイラ・オプションおよびエラー処理

- SQL99構文のサポート

- プログラミング・ガイドライン

- 略称

- 大/小文字の区別なし

- COBOLのバージョンのサポート

- コーディング領域

- カンマ

- コメント

- 行の継続

- Copy文

- DECIMAL-POINT IS COMMA句

- デリミタ

- オプションの分割ヘッダー

- 埋込みSQLの構文

- 表意定数

- ファイルの長さ

- FILLERの使用

- ホスト変数名

- ハイフン付きの名前

- レベル番号

- MAXLITERALのデフォルト

- マルチバイト・データ型

- SQLのNULL

- 段落およびセクションの名前

- REDEFINES句

- 関係演算子

- 文終了記号

- 宣言部

- 宣言部の内容

- 例

- プリコンパイラ・オプションDECLARE_SECTION

- INCLUDE文の使用

- ファイルの拡張子

- 検索パス

- ネストされたプログラム

- ネストされたプログラムのサポート

- SQLCAの宣言

- ネストされたプログラムの例

- 条件付きプリコンパイル

- 例

- シンボルの定義

- 分割プリコンパイル

- ガイドライン

- カーソルの参照

- MAXOPENCURSORSの指定

- 単一のSQLCAの使用

- 単一のDATE_FORMATの使用

- 制限

- コンパイルおよびリンク

- DEPT表およびEMP表のサンプル

- DEPTデータおよびEMPデータのサンプル

- サンプルEMPプログラム: SAMPLE1.PCO

3 データベースの概念

- Oracleへの接続

- デフォルトのデータベースおよび接続

- 同時ログイン

- ユーザー名/パスワードの使用方法

- 名前指定データベース接続

- 自動ログイン

- AUTO_CONNECTプリコンパイラ・オプション

- 実行時のパスワード変更

- ALTER AUTHORIZATIONを使用しない接続

- 標準のCONNECT

- SYSDBA権限またはSYSOPER権限

- リンクの使用方法

- 基本用語

- トランザクションによるデータベースの保護

- トランザクションの開始および終了

- COMMIT文の使用

- DECLARE CURSOR文でのWITH HOLD句の使用

- CLOSE_ON_COMMITプリコンパイラ・オプション

- ROLLBACK文の使用

- 文レベルのロールバック

- SAVEPOINT文の使用

- RELEASEオプションの使用方法

- SET TRANSACTION文の使用

- デフォルトのロックのオーバーライド

- FOR UPDATE OF句の使用

- 制限

- コミット時のフェッチ

- LOCK TABLE文の使用方法

- 分散トランザクションの処理

- トランザクション処理のガイドライン

- アプリケーションの設計

- ロックの取得

- PL/SQLの使用方法

- X/Openアプリケーション

4 データ型とホスト変数

- Oracle Databaseのデータ型

- 内部データ型

- 外部データ型

- CHAR

- CHARF

- CHARZ

- DATE

- DECIMAL

- DISPLAY

- FLOAT

- INTEGER

- LONG

- LONG RAW

- LONG VARCHAR

- LONG VARRAW

- NUMBER

- OVER-PUNCH

- RAW

- ROWID

- STRING

- UNSIGNED

- VARCHAR

- VARCHAR2

- VARNUM

- VARRAW

- SQL疑似列および関数

- 日時および時間隔のデータ型記述子

- ホスト変数

- ホスト変数の宣言

- 宣言の例

- 初期化

- 制限

- ホスト変数の参照

- ホスト変数としてのグループ項目

- 制限

- 標識変数

- 標識変数の使用方法

- 入力時

- 出力時

- 標識変数の宣言

- 標識変数の参照

- WHERE句での使用

- エラー・メッセージの回避

- ANSIの要件

- マルチバイトNCHAR変数の標識変数

- ホスト・グループ項目の標識変数

- VARCHAR変数

- VARCHAR変数の宣言

- 暗黙的なVARCHARグループ項目

- VARCHAR変数の参照

- 文字データの処理

- PIC Xのデフォルト

- PICXオプションの効果

- 固定長文字変数

- 入力時

- 出力時

- 可変長変数

- 入力時

- 出力時

- ユニバーサルROWID

- サブプログラムSQLROWIDGET

- グローバリゼーション・サポート

- Pro*COBOLのUnicodeサポート

- NLS_LOCAL=YESの制限事項

- 埋込みSQL内の文字列

- 埋込みDDL

- 空白埋込み

- 標識変数

- PIC X/PIC N変数とNCHAR/CHAR列の様々な組合せ

- PIC XとNCHAR列

- PIC NとCHAR列

- 新しいオプションの使用方法

- データ型変換

- DATE文字列フォーマットの明示的な制御

- データ型の同値化

- 同値化の有用性

- ホスト変数の同値化

- VAR文のCONVBUFSZ句

- 例

- CHARFデータ型指定子の使用方法

- ガイドライン

- RAWおよびLONG RAWの値

- プラットフォームのエンディアン形式のサポート

- サンプル・プログラム4: データ型の同値化

5 埋込みSQL

- ホスト変数の使用方法

- 出力ホスト変数および入力ホスト変数

- 標識変数の使用方法

- 入力変数

- 出力変数

- NULLの挿入

- 戻されたNULLの処理

- NULLのフェッチ

- NULLのテスト

- 切り捨てられた値のフェッチ

- 基本的なSQL文

- 行の選択

- 使用可能な句

- 行の挿入

- DML RETURNING句

- 副問合せの使用方法

- 行の更新

- 行の削除

- WHERE句の使用

- カーソル

- カーソルの宣言

- カーソルのオープン

- カーソルからのフェッチ

- カーソルのクローズ

- CURRENT OF句の使用方法

- 制限

- 一般的な文の順序

- 位置付け更新

- PREFETCHプリコンパイラ・オプション

- スクロール可能カーソル

- スクロール可能カーソルの使用方法

- DECLARE SCROLL CURSOR

- OPEN

- FETCH

- CLOSE

- CLOSE_ON_COMMITプリコンパイラ・オプション

- PREFETCHプリコンパイラ・オプション

- B領域の長さの柔軟性

- 固定実行計画

- SQLファイル

- 例

- LOGファイル

- サンプル・プログラム2: カーソル操作

6 埋込みPL/SQL

- PL/SQLの埋込み

- ホスト変数

- VARCHAR変数

- 標識変数

- NULLの処理

- 切り捨てられた値の処理

- SQLCHECK

- PL/SQLの利点

- パフォーマンスの向上

- Oracleとの統合

- カーソルFORループ

- サブプログラム

- パラメータ・モード

- パッケージ

- PL/SQL表

- ユーザー定義レコード

- PL/SQLブロックの埋込み

- ホスト変数およびPL/SQL

- PL/SQLの例

- PL/SQLの複雑な例

- VARCHAR疑似型

- 標識変数およびPL/SQL

- NULLの処理

- 切り捨てられた値の処理

- ホスト表およびPL/SQL

- ARRAYLEN文

- ARRAYLEN文のEXECUTEオプション・キーワード

- 埋込みPL/SQLでのカーソルの使用

- ストアドPL/SQLおよびJavaサブプログラム

- ストアド・サブプログラムの作成

- ストアドPL/SQLまたはJavaサブプログラムのコール

- 無名PL/SQLブロック

- CALL文

- CALLの例

- 動的PL/SQLの使用

- サブプログラムの制限事項

- サンプル・プログラム9: ストアド・プロシージャのコール

- リモート・アクセス

- カーソル変数

- カーソル変数の宣言

- カーソル変数の割当て

- カーソル変数のオープン

- PL/SQLストアド・プロシージャによる間接的なオープン

- Pro*COBOLアプリケーションからの直接的なオープン

- カーソル変数からのフェッチ

- カーソル変数のクローズ

- カーソル変数の解放

- カーソル変数の制限

- サンプル・プログラム11: カーソル変数

- SAMPLE11.SQL

- SAMPLE11.PCO

7 ホスト表

- ホスト表

- ホスト表の利点

- DML文の表

- ホスト表の宣言

- 制限

- ホスト表の参照

- インジケータ表の使用方法

- 表を含んでいるホスト・グループ項目

- Oracleでの制限

- ANSIでの制限および要件

- 表に対する選択

- バッチ・フェッチ

- SQLERRD(3)の使用方法

- フェッチされる行数

- ホスト表の使用制限

- NULLのフェッチ

- 切り捨てられた値のフェッチ

- サンプル・プログラム3: バッチでのフェッチ

- 表に対する挿入

- ホスト表の使用制限

- 表に対する更新

- UPDATEでの制限

- 表に対する削除

- DELETEでの制限

- インジケータ表の使用方法

- FOR句

- 制限

- SELECT文での使用

- CURRENT OF句との併用

- WHERE句

- CURRENT OF句の疑似実行

- ホスト変数としてのグループ項目の表

- サンプル・プログラム14: グループ項目の表

- 配列INSERTおよび配列SELECT構文の追加

- 暗黙的なバッファ済INSERTの使用

8 エラー処理および診断

- エラー処理が必要な理由

- エラー処理の代替手段

- SQLCA

- ORACA

- ANSI SQLSTATE変数

- SQLSTATEの宣言

- SQLSTATE値

- SQLコミュニケーション領域の使用

- SQLCAの内容

- SQLCAの宣言

- エラー・レポートの基本コンポーネント

- ステータス・コード

- 警告フラグ

- 処理済行数

- 解析エラー・オフセット

- エラー・メッセージ・テキスト

- SQLCAの構造

- SQLCAID

- SQLCABC

- SQLCODE

- SQLERRM

- SQLERRD

- SQLWARN

- SQLEXT

- PL/SQLに関する考慮事項

- エラー・メッセージのテキスト全体の取得

- DSNTIAR

- WHENEVERディレクティブ

- 状態

- SQLWARNING

- SQLERROR

- NOT FOUNDまたはNOTFOUND

- アクション

- CONTINUE

- DO CALL

- DO PERFORM

- GOTOまたはGO TO

- STOP

- WHENEVER文のコーディング

- DO PERFORM

- DO CALL

- スコープ

- 不注意な使用: 例

- SQL文のテキストの取得

- Oracle通信領域の使用

- ORACAの内容

- ORACAの宣言

- ORACAを使用可能に設定

- ランタイム・オプションの選択

- ORACAの構造

- ORACAID

- ORACABC

- ORACCHF

- ORADBGF

- ORAHCHF

- ORASTXTF

- 診断情報

- ORASTXT

- ORASFNM

- ORASLNR

- カーソル・キャッシュ統計情報

- ORAHOC

- ORAMOC

- ORACOC

- ORANOR

- ORANPR

- ORANEX

- ORACAのサンプル・プログラム

- エラーとSQLSTATEコードの対応関係

- 状態変数の組合せ

9 Oracle動的SQL

- 動的SQL

- 動的SQLの長所および短所

- 動的SQLを使用する場合

- 動的SQL文の要件

- 動的SQL文の処理

- 動的SQLの使用方法

- 方法1

- 方法2

- 方法3

- 方法4

- ガイドライン

- 一般的なエラーの回避

- 方法1の使用方法

- EXECUTE IMMEDIATE文

- 例

- サンプル・プログラム6: 動的SQL方法1

- 方法2の使用方法

- USING句

- サンプル・プログラム7: 動的SQL方法2

- 方法3の使用方法

- PREPARE

- DECLARE

- OPEN

- FETCH

- CLOSE

- サンプル・プログラム8: 動的SQL方法3

- 方法4の使用方法

- SQLDAの必要性

- DESCRIBE文

- SQLDAの内容

- 方法4の実行

- DECLARE STATEMENT文の使用方法

- ホスト表の使用方法

- PL/SQLの使用方法

- 方法1の場合

- 方法2の場合

- 方法3の場合

- 方法4の場合

- 注意

- 動的SQL文のキャッシング

第II部 アプリケーション

10 ANSI動的SQL

- ANSI動的SQLの基礎

- プリコンパイラのオプション

- ANSI SQL文の概要

- サンプル・コード

- Oracle拡張機能

- 参照セマンティクス

- バルク操作での表の使用方法

- ANSI動的SQLのプリコンパイラ・オプション

- 動的SQL文の構文

- ALLOCATE DESCRIPTOR

- 変数

- 例

- DEALLOCATE DESCRIPTOR

- GET DESCRIPTOR

- SET DESCRIPTOR

- 例

- PREPAREの使用

- DESCRIBE INPUT

- DESCRIBE OUTPUT

- EXECUTE

- EXECUTE IMMEDIATEの使用

- DYNAMIC DECLARE CURSORの使用

- カーソルのOPEN

- FETCH

- 動的カーソルのCLOSE

- Oracle動的方法4との違い

- 制限

- サンプル・プログラム: SAMPLE12.PCO

11 Oracle動的SQL: 方法4

- 方法4の特殊要件

- 方法4の利点

- データベースに必要な情報

- 情報の格納位置

- 情報の取得方法

- SQL記述子領域(SQLDA)の理解

- SQLDAの目的

- 複数のSQLDA

- SQLDAの宣言

- SQLDA変数

- 前提知識

- SQLADRの使用

- データの変換

- データ型の強制変換

- NULLまたはNOT NULLデータ型の処理

- 基本手順

- 各手順の詳細

- ホスト文字列の宣言

- SQLDAの宣言

- DESCRIBEへの最大数の設定

- 記述子の初期化

- ホスト文字列への問合せテキストの格納

- ホスト文字列からの問合せのPREPARE

- カーソルの宣言

- バインド変数のDESCRIBE

- プレースホルダの数の再設定

- バインド変数の値の取得

- カーソルのOPEN

- 選択リストのDESCRIBE

- 選択リスト項目の最大数の再設定

- 各選択リスト項目の長さおよびデータ型の再設定

- アクティブ・セットからの行のFETCH

- 選択リストの値の取得および処理

- カーソルのCLOSE

- 方法4でのホスト表の使用

- サンプル・プログラム10: 動的SQL方法4

12 マルチスレッド・アプリケーション

- スレッドの概要

- Pro*COBOLのランタイム・コンテキスト

- ランタイム・コンテキストの使用モデル

- 複数のスレッドで1つのランタイム・コンテキストを共有

- 複数のスレッドで複数のランタイム・コンテキストを共有

- マルチスレッド・アプリケーションのユーザー・インタフェース機能

- THREADSオプション

- ランタイム・コンテキストの埋込みSQL文およびディレクティブ

- SQL-CONTEXTのホスト表の使用禁止

- EXEC SQL ENABLE THREADS

- EXEC SQL CONTEXT ALLOCATE

- EXEC SQL CONTEXT USE

- EXEC SQL CONTEXT FREE

- Pro*C/C++プログラムとの対話

- マルチスレッド・プログラミングに関する注意事項

- マルチスレッドの制限

- 複数のコンテキストの例

- 例1

- 例2

- 例3

- 例4

- 例5

- マルチスレッドの例

13 ラージ・オブジェクト(LOB)

- LOBの使用

- 内部LOB

- 外部LOB

- BFILEのセキュリティ

- LOBとLONGおよびLONG RAWの比較

- LOBロケータ

- 一時LOB

- LOBバッファリング・サブシステム

- LOBの使用方法

- アプリケーションでのLOBロケータ

- LOBの初期化

- 内部LOB

- 外部LOB

- 一時LOB

- LOBの解放

- LOB文のルール

- すべてのLOB文に適用されるルール

- LOBバッファリング・サブシステムに適用されるルール

- ホスト変数に適用されるルール

- LOB文

- APPEND

- ASSIGN

- CLOSE

- COPY

- CREATE TEMPORARY

- DISABLE BUFFERING

- ENABLE BUFFERING

- ERASE

- FILE CLOSE ALL

- FILE SET

- FLUSH BUFFER

- FREE TEMPORARY

- LOAD FROM FILE

- OPEN

- READ

- TRIM

- WRITE

- DESCRIBE

- ポーリング・メソッドを使用したREADおよびWRITE

- LOBサンプル・プログラム: LOBDEMO1.PCO

14 プリコンパイラのオプション

- procobコマンド

- 大/小文字区別

- プリコンパイル時のアクション

- オプションについて

- オプション値の優先順位

- マクロ・オプションおよびマイクロ・オプション

- カレント値の決定

- プリコンパイラ・オプションの入力

- コマンドライン

- インライン

- 長所

- EXEC ORACLEのスコープ

- 構成ファイル

- 列プロパティのサポート

- プリコンパイラ・オプションのスコープ

- クイック・リファレンス

- Pro*COBOLプリコンパイラ・オプションの使用

- ASACC

- ASSUME_SQLCODE

- AUTO_CONNECT

- CHARSET_PICX

- CHARSET_PICN

- CLOSE_ON_COMMIT

- COMMON_PARSER

- CONFIG

- DATE_FORMAT

- DB2_ARRAY

- DBMS

- DECLARE_SECTION

- DEFINE

- DYNAMIC

- END_OF_FETCH

- ERRORS

- File_ID

- FIPS

- FORMAT

- HOLD_CURSOR

- HOST

- IMPLICIT_SVPT

- INAME

- INCLUDE

- IRECLEN

- LITDELIM

- LNAME

- LRECLEN

- LTYPE

- MAX_ROW_INSERT

- MAXLITERAL

- MAXOPENCURSORS

- MODE

- NESTED

- NLS_LOCAL

- ONAME

- ORACA

- ORECLEN

- OUTLINE

- OUTLNPREFIX

- PAGELEN

- PICN_ENDIAN

- PICX

- PLAN_BASELINE

- PLAN_PREFIX

- PLAN_RUN

- PLAN_FIXED

- PLAN_ENABLED

- MEMFORPREFETCH

- PREFETCH

- RELEASE_CURSOR

- RUNOUTLINE

- SELECT_ERROR

- SQLCHECK

- STMT_CACHE

- TYPE_CODE

- UNSAFE_NULL

- USERID

- VARCHAR

- XREF

A オペレーティング・システムの依存性

- このマニュアルにあるシステム固有の参照情報

- COBOLのバージョン

- ホスト変数

- 宣言

- ネーミング

- INCLUDE文

- MAXLITERALのデフォルト

- マルチバイト・グローバリゼーション・サポート文字に対するPIC N句またはPIC G句

- 予測できないRETURN-CODE特殊レジスタ。

- バイナリ・データのバイト順序

B 予約語、キーワードおよびネームスペース

- 予約語およびキーワード

- 予約済ネームスペース

C パフォーマンス・チューニング

- パフォーマンスを低下させる原因

- パフォーマンスの向上

- ホスト表の使用方法

- PL/SQLおよびJavaの使用

- SQL文の最適化

- オプティマイザ・ヒント

- ヒントの渡し方

- SQL文のキャッシング

- 索引の使用

- 行レベル・ロックの利用

- 不要な解析の排除

- 明示カーソルの操作

- カーソルの制御

- カーソル管理オプションの使用

- プライベートSQL領域およびカーソル・キャッシュ

- リソースの使用

- 実行回数の少ない場合

- 実行回数の多い場合

- 共有SQL領域への影響

- 埋込みPL/SQLに関する考慮事項

- パラメータの相互作用

- 不要な再解析の回避

D 構文および意味検査

- 構文および意味検査の基礎

- 検査の種類および範囲の制御

- SQLCHECK=SEMANTICSの指定

- 意味検査の使用許可

- Oracleへの接続

- DECLARE TABLEの使用

E 埋込みSQL文およびプリコンパイラ・ディレクティブ

- プリコンパイラ・ディレクティブおよび埋込みSQL文の概要

- 文記述子

- 構文図の読み方

- 文の終了記号

- 必須のキーワードおよびパラメータ

- オプションのキーワードおよびパラメータ

- 構文ループ

- 複数パーツの図

- Oracleオブジェクト名

- ALLOCATE (実行可能埋込みSQL拡張機能)

- ALLOCATE DESCRIPTOR (実行可能埋込みSQL)

- CALL (実行可能埋込みSQL)

- CLOSE (実行可能埋込みSQL)

- COMMIT (実行可能埋込みSQL)

- CONNECT (実行可能埋込みSQL拡張機能)

- CONTEXT ALLOCATE (実行可能埋込みSQL拡張機能)

- CONTEXT FREE (実行可能埋込みSQL拡張機能)

- CONTEXT USE (Oracle埋込みSQLディレクティブ)

- DEALLOCATE DESCRIPTOR (埋込みSQL文)

- DECLARE CURSOR (埋込みSQLディレクティブ)

- DECLARE DATABASE (Oracle埋込みSQLディレクティブ)

- DECLARE STATEMENT (埋込みSQLディレクティブ)

- DECLARE TABLE (Oracle埋込みSQLディレクティブ)

- DELETE (実行可能埋込みSQL)

- DESCRIBE (実行可能埋込みSQL)

- DESCRIBE DESCRIPTOR (実行可能埋込みSQL)

- ENABLE THREADS (実行可能埋込みSQL拡張機能)

- EXECUTE ...END-EXEC (実行可能埋込みSQL拡張機能)

- EXECUTE (実行可能埋込みSQL)

- EXECUTE DESCRIPTOR (実行可能埋込みSQL)

- EXECUTE IMMEDIATE (実行可能埋込みSQL)

- FETCH (実行可能埋込みSQL)

- FETCH DESCRIPTOR (実行可能埋込みSQL)

- FREE (実行可能埋込みSQL拡張機能)

- GET DESCRIPTOR (実行可能埋込みSQL)

- INSERT (実行可能埋込みSQL)

- LOB APPEND (実行可能埋込みSQL拡張機能)

- LOB ASSIGN (実行可能埋込みSQL拡張機能)

- LOB CLOSE (実行可能埋込みSQL拡張機能)

- LOB COPY (実行可能埋込みSQL拡張機能)

- LOB CREATE TEMPORARY (実行可能埋込みSQL拡張機能)

- LOB DESCRIBE (実行可能埋込みSQL拡張機能)

- LOB DISABLE BUFFERING (実行可能埋込みSQL拡張機能)

- LOB ENABLE BUFFERING (実行可能埋込みSQL拡張機能)

- LOB ERASE (実行可能埋込みSQL拡張機能)

- LOB FILE CLOSE ALL (実行可能埋込みSQL拡張機能)

- LOB FILE SET (実行可能埋込みSQL拡張機能)

- LOB FLUSH BUFFER (実行可能埋込みSQL拡張機能)

- LOB FREE TEMPORARY (実行可能埋込みSQL拡張機能)

- LOB LOAD (実行可能埋込みSQL拡張機能)

- LOB OPEN (実行可能埋込みSQL拡張機能)

- LOB READ (実行可能埋込みSQL拡張機能)

- LOB TRIM (実行可能埋込みSQL拡張機能)

- LOB WRITE (実行可能埋込みSQL拡張機能)

- OPEN (実行可能埋込みSQL)

- OPEN DESCRIPTOR (実行可能埋込みSQL)

- PREPARE (実行可能埋込みSQL)

- ROLLBACK (実行可能埋込みSQL)

- SAVEPOINT (実行可能埋込みSQL)

- SELECT (実行可能埋込みSQL)

- SET DESCRIPTOR (実行可能埋込みSQL)

- UPDATE (実行可能埋込みSQL)

- VAR (Oracle埋込みSQLディレクティブ)

- WHENEVER (埋込みSQLディレクティブ)

F Pro*COBOL for Windows

- Pro*COBOLアプリケーションのコンパイルおよびリンク

- IDEの使用方法

- Animatorの使用方法

- COBOLおよびCBLLINKコマンド

- COBSQLコマンド

- サンプル・プログラム

- デモ表の作成

- サンプル・プログラムのビルド

- サンプル・ファイル

索引

はじめに

このマニュアルは、Oracle Pro*COBOLプリコンパイラの総合的なユーザーズ・ガイドおよびリファレンスです。このマニュアルでは、データベース言語SQLおよびPL/SQLを使用してOracleデータへのアクセスと操作を行うCOBOLプログラムの開発方法を説明します。SQLおよびPL/SQLの詳細は、『Oracle Database SQL言語リファレンス』および『Oracle Database PL/SQL言語リファレンス』を参照してください。

内容は次のとおりです。

- 対象読者

- ドキュメントのアクセシビリティについて

- 関連ドキュメント

- 表記規則

対象読者

『Pro*COBOLプログラマーズ・ガイド』は、Oracle環境で動作する新規のCOBOLアプリケーションを開発したり、既存のアプリケーションをOracle環境用に変換するユーザーを対象としています。また、このマニュアルは特にプログラマを対象として記述されていますが、Pro*COBOLについて総合的に解説していますので、システム・アナリストやプロジェクト・マネージャ、埋込みSQLアプリケーションに関心のあるその他のユーザーにも役立つ内容となっています。

このマニュアルを有効に利用するには、次の知識が必要です。

- COBOLでのアプリケーションのプログラミング

- SQLデータベース言語

- Oracleの概念および用語

ドキュメントのアクセシビリティについて

Oracleのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイト(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc)を参照してください。

Oracle Supportへのアクセス

Oracleサポート・サービスでは、My Oracle Supportを通して電子支援サービスを提供しています。詳細情報は(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info)か、聴覚に障害のあるお客様は(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs)を参照してください。

関連ドキュメント

詳細は、次のOracleドキュメントを参照してください。

- 『Oracle Database SQL言語リファレンス』

- 『Oracle C++ Call Interfaceプログラマーズ・ガイド』

- 『Oracle Call Interfaceプログラマーズ・ガイド』

このマニュアル内の多くの例では、Oracleのインストール時にデフォルトでインストールされるシード・データベースのサンプル・スキーマを使用しています。これらのスキーマの作成方法およびその使用方法の詳細は、『Oracle Databaseサンプル・スキーマ』を参照してください。

表記規則

このマニュアルでは次の表記規則を使用します。

規則

意味

太字

太字は、操作に関連するGraphical User Interface要素、または本文中で定義されている用語および用語集に記載されている用語を示します。

イタリック体

イタリックは、ユーザーが特定の値を指定するプレースホルダ変数を示します。

固定幅フォント

固定幅フォントは、段落内のコマンド、URL、サンプル内のコード、画面に表示されるテキスト、または入力するテキストを示します。

このリリースの『Pro*COBOLプログラマーズ・ガイド』での変更点

ここでは、『Pro*COBOLプログラマーズ・ガイド』での変更点を示します。

Pro*COBOL 12c リリース1 (12.1)での変更点

Oracle Database 12c リリース1 (12.1)用のPro*COBOLでの変更点は、次のとおりです。

新機能

このリリースでの新機能は次のとおりです。

- 自動増分列のサポート
Pro*COBOLでは、自動増分列がサポートされるようになりました。これによって、チケット発行、HRおよびトラッキング・アプリケーションの開発が単純になり、データベースをOracle Databaseに移行しやすくなります。

- 32Kの列のサポート
Pro*COBOLでは、VARCHAR2、NVARCHAR2およびRAWデータを含む32Kの列がサポートされるようになりました。この機能も、データベースをOracle Databaseに移行する際に役立ちます。

- メモリーによるプリフェッチのサポート
新しいインラインおよびコマンドライン・オプションによって、行のプリフェッチに使用するメモリーを指定できるようになりました。この新しいMEMFORPREFETCHオプションによって、データベースをOracle Databaseに移行しやすくなります。既存のPREFETCHオプションはそのまま残されています。

「MEMFORPREFETCH」を参照してください。

- SQL計画管理(SPM)のサポート
新しいコマンドライン・オプションによって計画ベースラインのSQL文が生成され、生成されるSQLおよびLOGファイルの名前および形式も制御されます。これらの新しいオプションによって、既存のプリコンパイラのSQL計画管理の機能が拡張されます。パフォーマンス管理の手段が提供され、コンパイラ・アプリケーションのアップグレードが容易になります。

「PLAN_BASELINE」を参照してください。

「PLAN_PREFIX」を参照してください。

「PLAN_RUN」を参照してください。

「PLAN_FIXED」を参照してください。

「PLAN_ENABLED」を参照してください。

第I部

概要および概念

第I部は、次の章で構成されています。

- 概要

- プリコンパイラの概念

- データベースの概念

- データ型とホスト変数

- 埋込みSQL

- 埋込みPL/SQL

- ホスト表

- エラー処理および診断

- Oracle動的SQL

1 概要

この章では、Pro*COBOLプリコンパイラについて説明します。Oracleデータを操作するアプリケーション・プログラムを開発するうえでのその役割と、このプリコンパイラによりアプリケーションで実行できる処理について説明します。次の項目について説明します。

- Pro*COBOLの概要

- Pro*COBOLプリコンパイラ

- Pro*COBOLプリコンパイラを使用する利点

- SQL言語

- PL/SQL言語

- Pro*COBOLの機能および利点

- ディレクトリ構造

Pro*COBOLの概要

Oracle Databaseにアクセスするには、Structured Query Language (SQL)という高水準の問合せ言語を使用します。通常はSQL*Plusなどの対話型インタフェースを介してSQLを使用します。

Pro*COBOLは、SQL文をCOBOLプログラムに埋め込むことができるプログラミング・ツールです。Pro*COBOLプリコンパイラは、COBOLプログラム内のSQL文を標準のOracleランタイム・ライブラリ・コールに変換します。生成された出力ファイルは、通常の方法でコンパイル、リンクおよび実行できます。

迅速な開発と他のシステムとの互換性を優先する場合は、Pro*COBOLプリコンパイラを使用します。

Pro*COBOLプリコンパイラ

Pro*COBOLプリコンパイラは、SQL文をCOBOLプログラムに埋め込むことができるプログラミング・ツールです。図1-1のように、プリコンパイラはホスト・プログラムを入力として受け入れ、埋込みSQL文を標準Oracleランタイム・ライブラリ・コールに変換して、通常の方法でコンパイル、リンクおよび実行できるソース・プログラムを生成します。

図1-1 埋込みSQLプログラムの開発

注意:
Pro*COBOLは、Windows 2000の32-bit版対応のMicro Focus Net Express 5.0をサポートしています。

注意:
Pro*COBOLでは、オブジェクト指向COBOL(OOCOBOL)仕様をサポートしていません。

代替言語

Oracleプリコンパイラは次の言語で使用できます(ただし、すべてのシステムで使用できるとはかぎりません)。

- C/C++

- COBOL

- FORTRAN

Pro*COBOLプリコンパイラを使用する利点

Pro*COBOLプリコンパイラを使用すると、アプリケーション・プログラムに強力で柔軟なSQLを組み込めます。SQL文をCOBOLに埋め込むことができます。便利なインタフェースによって、アプリケーションから直接Oracleにアクセスできます。

他の多くのアプリケーション開発ツールとは異なり、Pro*COBOLではアプリケーションを高度にカスタマイズできます。たとえば、最新のウィンドウ機能およびマウス技術を取り込んだユーザー・インタフェースを作成できます。また、ユーザーとの対話なしに、バックグラウンドで実行するアプリケーションも作成できます。

さらに、Pro*COBOLを使用してアプリケーションを微調整できます。リソース使用率、SQL文の実行および様々なランタイム・インジケータの状況を詳細に監視できます。得られた情報に基づいて、最大のパフォーマンスが実現できるようにプログラムのパラメータを調整できます。

SQL言語

Oracleデータにアクセスして操作するには、SQLが必要です。SQLを対話形式で使用するか、アプリケーション・プログラムに埋め込んで使用するかは、作業の内容によって異なります。COBOLのプロシージャ処理能力を必要とする作業や定期的に実行する作業の場合は、埋込みSQLを使用します。

SQLは、その柔軟で強力な特性、および習得が容易であることから、最もすぐれたデータベース言語となりました。SQLは非プロシージャ言語であるため、目的とする処理を指定するときにその方法を指定する必要がありません。英文に似た少数の文で、Oracleデータを一度に1行または複数行ずつ簡単に操作できます。

任意の(SQL*Plus以外の) SQL文をアプリケーション・プログラムから実行できます。たとえば、次の操作が可能です。

- データベース表の動的なCREATE (作成)、ALTER (変更)およびDROP (削除)。

- データ行のSELECT (選択)、INSERT (挿入)、UPDATE (更新)およびDELETE (削除)。

- トランザクションのCOMMIT (コミット)やROLLBACK (ロールバック)。

アプリケーション・プログラムにSQL文を埋め込む前に、SQL*Plusを使用して対話式にSQL文をテストできます。通常、対話型SQLから埋込みSQLへの切替えはわずかな変更で行えます。

PL/SQL言語

SQLを拡張したPL/SQLは、プロシージャ構造、変数宣言および強力なエラー処理をサポートするトランザクション処理言語です。同一PL/SQLブロック内では、SQLおよびPL/SQLの拡張機能をすべて使用できます。

埋込みPL/SQLの主な利点はパフォーマンスの向上です。SQLと異なり、PL/SQLでは、SQL文を論理的にグループ化し、1文単位ではなくブロック単位でOracleに送信できます。この結果、ネットワークの通信量および処理のオーバーヘッドが減少します。

アプリケーション・プログラムにPL/SQLを埋め込む方法などPL/SQLの詳細は、第6章「埋込みPL/SQL」を参照してください。

Pro*COBOLの機能および利点

図1-2に示すように、Pro*COBOLには、効率がよく信頼性の高いアプリケーション開発を支援する機能および利点が数多くあります。

図1-2 Pro*COBOLの機能および利点

たとえば、Pro*COBOLプリコンパイラを使用して次のことができます。

- COBOLを使用したアプリケーション開発。

- ANSI/ISO埋込みSQL規格への準拠。

- 実行時に、COBOLプログラム内で有効な任意のSQL文の受入れおよび作成を可能にする、ANSI動的SQL方法4の利用。

- 高度にカスタマイズされたアプリケーションの設計および開発。

- Oracleの内部データ型とCOBOLデータ型の間の自動変換。

- COBOLアプリケーション・プログラムにPL/SQLトランザクション処理ブロックを埋め込むことによる、パフォーマンスの向上。

- 有用なプリコンパイラ・オプションの指定およびプリコンパイル中の値変更。

- データ型の同値化機能を使用した、Oracleによる入力データの解析および出力データの形式設定の制御。

- 複数のプログラム・モジュールを個別にプリコンパイルし、後でリンクして1つの実行可能プログラムを作成する機能。

- 埋込みSQLデータを操作する文およびPL/SQLブロックの構文と意味のチェック。

- Oracle Net Servicesを使用した、複数ノード上のOracle Databaseへの同時アクセス。

- 入力および出力プログラム変数での配列の使用。

- 異なった環境下でのホスト・プログラムの実行を可能にする、コード・セクションの条件付きプリコンパイル。

- 高級言語で記述されているユーザー・イグジットを使用した、Oracle FormsおよびOracle Reportsなどのツールとのインタフェース。

- ANSI準拠の状態変数SQLSTATEとSQLCODE、またはSQLコミュニケーション領域(SQLCA)とWHENEVER文を使用した、エラーおよび警告の処理。または、SQLSTATEとSQLCODE、およびSQLコミュニケーション領域(SQLCA)とWHENEVER文を使用。

- Oracle通信領域(ORACA)に備えられている診断プログラム拡張セットの使用。

- ラージ・オブジェクト(LOB)データベース型へのアクセス。

ディレクトリ構造

Pro*COBOLをインストールする際に、Oracle Universal Installerによって\precompというディレクトリがORACLE_BASE\ORACLE_HOMEディレクトリに作成されます。

注意:
\precompディレクトリには、Pro*C/C++など他の製品のファイルが格納されている場合があります。

\precompディレクトリは、表1-1に示すディレクトリで構成されています。

表1-1 ディレクトリ

ディレクトリ名

内容

\admin

構成ファイル

\demo\procob2

Pro*COBOLのサンプル・プログラム

\demo\sql

サンプル・プログラムのSQLスクリプト

\doc\procob2

Pro*COBOLのREADMEファイル

\lib

ライブラリ・ファイル

\mesg

メッセージ・ファイル

\public

ヘッダー・ファイル

ヘッダー・ファイル

ORACLE_BASE\ORACLE_HOME\precomp\publicディレクトリには、表1-2に示すPro*COBOLのヘッダー・ファイルが格納されています。

表1-2 ヘッダー・ファイル

ヘッダー・ファイル

説明

oraca.cob

ランタイム・エラーの診断、およびプログラムによる様々なOracleリソースの使用状況の監視に役立つOracle通信領域(ORACA)が含まれています。

oraca5.cob

ORACA5は、ORACAのCOMP-5バージョンです。

sqlca.cob

ランタイム・エラーの診断に役立つSQLコミュニケーション領域(SQLCA)が含まれています。SQLCAは、実行可能なSQL文が実行されるたびに更新されます。

sqlca5.cob

SQLCA5は、SQLCAのCOMP-5バージョンです。

sqlda.cob

動的SQL方法4を使用するプログラムに必要なデータ構造であるSQL記述子領域(SQLDA)が含まれています。

sqlda5.cob

これは、SQLDAのCOMP-5バージョンです。

ライブラリ・ファイル

ORACLE_BASE\ORACLE_HOME \precomp\libディレクトリには、Pro*COBOLアプリケーションをリンクするときに使用するライブラリ・ファイルが格納されています。ライブラリ・ファイル名は、orasql12.libです。

既知の問題、制限事項および対処方法

1. Windowsのすべてのオペレーティング・システムでは、ファイル名やディレクトリ名にスペースを含めることができますが、Oracle Pro*COBOLプリコンパイラでは、ファイル名やディレクトリ名にスペースを含むファイルはプリコンパイルされません。たとえば、次のような書式は使用しないでください。

- proc iname=test one.pc

- proc iname=d:\dir1\second dir\sample1.pc

2. SPARC Solaris 64ビット・コンピュータでは、COMP5プリコンパイラ・オプションを使用できません。かわりにCOMPオプションを使用します。

互換性、アップグレードおよび移行

追加の「配列INSERT」および「配列SELECT」構文は、DB2プリコンパイラ・アプリケーションをPro*Cobolアプリケーションに移行する場合に役立ちます。これは、DB2の配列INSERTおよび配列SELECT構文をOracle Pro*Cobol用に変更する必要がないためです。

Pro*Cobolでサポートされている「暗黙的なバッファ済INSERT」機能は、パフォーマンスを向上させるために、Pro*Cobolの配列構文を使用せず、DB2プリコンパイラ・アプリケーションをPro*Cobolアプリケーションに移行する場合に役立ちます。

2 プリコンパイラの概念

この章では埋込みSQLプログラムの動作を説明します。重要な用語の定義、基本概念の説明および主なルールを示します。

内容は次のとおりです。

- 埋込みSQLプログラミングの基本概念

- プログラミング・ガイドライン

- 宣言部

- ネストされたプログラム

- 条件付きプリコンパイル

- 分割プリコンパイル

- コンパイルおよびリンク

- DEPT表およびEMP表のサンプル

- サンプルEMPプログラム: SAMPLE1.PCO

埋込みSQLプログラミングの基本概念

この項では、後の各章で説明する内容の基本概念について説明します。

埋込みSQLアプリケーションの開発ステップ

プリコンパイルを実行すると、通常どおりにコンパイルできるソース・ファイルが生成されます。プリコンパイルを行うと従来の開発過程より1ステップ処理が増えますが、これによって柔軟性に富んだアプリケーションを開発できるという大きな利点があります。

図2-1は、埋込みSQLアプリケーションの開発過程を示しています。

図2-1 アプリケーションの開発過程

埋込みSQL文

埋込みSQLとは、アプリケーション・プログラムに記述されているSQL文のことです。SQL文を含むアプリケーション・プログラムはホスト・プログラムと呼ばれ、その記述言語はホスト言語と呼ばれます。たとえば、Pro*COBOLでは、SQL文をCOBOLホスト・プログラムに埋め込むことができます。

Oracleデータの操作および問合せには、INSERT文、UPDATE文、DELETE文およびSELECT文を使用します。INSERTはデータベース表へのデータ行の追加、UPDATEは行の変更、DELETEは不要な行の削除、SELECTは検索条件を満たす行の検索を行います。

アプリケーション・プログラムではSQL文のみ有効であり、SQL*Plus文は無効です。(SQL*Plusにはレポートの書式化、SQL文の編集、環境パラメータの設定のための文が追加されています。)

実行文および宣言部

埋込みSQL文には、すべての対話型SQL文に加えて、Oracleとホスト・プログラムの間でデータを転送できるその他の文があります。埋込みSQL文には、実行文およびディレクティブという2つのタイプがあります。

実行SQL文は、データベースのコールを生成します。実行SQL文には、ほとんどすべての問合せ、データ操作言語(DML)文、データ定義言語(DDL)文、データ制御言語(DCL)文が含まれます。

一方、ディレクティブではSQLLIBのコールは発生せず、Oracleデータの操作も行われません。

ディレクティブはOracleオブジェクト、コミュニケーション領域およびSQL変数を宣言するために使用します。ディレクティブは、COBOLの宣言を記述できる位置であればどこでも記述できます。

付録E「埋込みSQL文およびプリコンパイラ・ディレクティブ」は、重要な文およびディレクティブを説明しています。表2-1に、いくつかの埋込みSQL文の一例を分類して示します。

表2-1 埋込みSQL文

ディレクティブ

文

用途

ARRAYLEN*

PL/SQLでのホスト表の使用

BEGIN DECLARE SECTION*

END DECLARE SECTION*

ホスト変数の宣言

DECLARE*

Oracleオブジェクトの命名

INCLUDE*

ファイルへのコピー

VAR*

変数の同値化

WHENEVER*

ランタイム・エラーの処理

実行SQL文

文

用途

ALLOCATE*

ALTER

CONNECT*

CREATE

DROP

GRANT

NOAUDIT

RENAME

REVOKE

TRUNCATE

Oracleデータの定義および制御

CLOSE*

DELETE

EXPLAIN PLAN

FETCH*

INSERT

LOCK TABLE

OPEN*

SELECT

UPDATE

Oracleデータの問合せおよび操作

COMMIT

ROLLBACK

SAVEPOINT

SET TRANSACTION

トランザクションの処理

DESCRIBE*

EXECUTE*

PREPARE*

動的SQLの使用

ALTER SESSION

SET ROLE

セッションの制御

*対話形式はありません。

埋込みSQLの構文

アプリケーション・プログラムでは、SQL文とホスト言語の文を自由に混在させることができ、SQL文でホスト言語の変数が使用できます。ホスト・プログラムにSQL文を記述するために特に必要なことは、SQL文をワードEXEC SQLで開始し、トークンEND-EXECで終了することのみです。Pro*COBOLが、実行EXEC SQL文をすべてランタイム・ライブラリSQLLIBのコールに変換します。

大部分の埋込みSQL文がそれに対応する対話型文と異なる点は、新しい句が追加されているか、プログラム変数が使用されていることのみです。次の対話型ROLLBACK文と埋込みROLLBACK文を比較してください。

ROLLBACK WORK;           -- interactive

* embedded
EXEC SQL
ROLLBACK WORK
END-EXEC.

SQL文の後には、ピリオドやその他の終了記号を置くことができます。次は、どちらも正しいSQL文です。

EXEC SQL ... END-EXEC,
EXEC SQL ... END-EXEC.

静的SQL文と動的SQL文

大部分のアプリケーション・プログラムは、静的SQL文および固定的なトランザクションを処理するように設計されています。この場合、処理を実行する前に各SQL文およびトランザクションの構成がわかります。つまり、発行されるSQLコマンド、変更されるデータベースの表、更新される列などが事前にわかります。第5章「埋込みSQL」を参照してください。

しかし、実行時に有効なSQL文を受け入れて処理する必要のあるアプリケーションもあります。この場合、関係するSQLコマンド、データベースの表および列は実行時までわからない場合もあります。

動的SQLは、プログラムの実行時にSQL文を受け取るかまたは作成し、データ型変換を明示的に管理する高度なプログラミング技術です。第9章「Oracle動的SQL」、第10章「ANSI動的SQL」および第11章「Oracle動的SQL: 方法4」を参照してください。

埋込みPL/SQLブロック

Pro*COBOLはPL/SQLブロックを1つの埋込みSQL文のように扱うため、SQL文の埋込みが可能なアプリケーション・プログラム内の任意の場所にPL/SQLブロックを埋め込むことができます。PL/SQLをホスト・プログラム内に埋め込むには、PL/SQLと共有する変数を宣言し、キーワードEXEC SQL EXECUTEおよびEND-EXECを使用してPL/SQLブロックを囲みます。

PL/SQLはすべてのSQLデータ操作コマンドおよびトランザクション処理コマンドをサポートしているため、埋込みPL/SQLブロックからOracleデータを柔軟かつ安全に操作できます。PL/SQLの詳細は、第6章「埋込みPL/SQL」を参照してください。

ホスト変数および標識変数

ホスト変数とは、COBOL言語で宣言され、Oracleとの間で共有される(つまり、ユーザー・プログラムおよびOracleの両方がその値を参照できる)スカラー変数または表変数、あるいはグループ項目です。ホスト変数はOracleとプログラムの間の通信を仲介します。

データベースにデータを渡すには入力ホスト変数を使用します。データベースからプログラムにデータおよびステータス情報を渡すには、出力ホスト変数を使用します。

ホスト変数は、式を使用できる位置であればどこに使用してもかまいません。SQL文では、ホスト変数にコロン(:)の接頭辞を付けて、データベース・スキーマ名からホスト変数を切り分ける必要があります。

任意のホスト変数に任意指定の標識変数を関連付けることができます。標識変数とは、ホスト変数の値または条件を示す整変数です。NULLとは、値がないか、未知であるか、または適用不可能な値です。標識変数を使用すると、入力ホスト変数にNULLを割り当てたり、出力変数のNULLまたは出力文字ホスト変数の切り捨てられた値を検出できます。

ホスト変数についての禁止事項は次のとおりです。

- COBOL文で先頭にコロンを付けること

- ALTERやCREATEなどのデータ定義(DDL)文で使用すること

SQL文中に標識変数を記述する場合は、前にコロンを付けて、関連付けられたホスト変数の直後に記述してください(標識変数の前にオプションのキーワードINDICATORを付けることも可能です)。

SQL文で使用するプログラム変数はすべて、COBOL言語の規則に従って宣言する必要があります。この場合、通常のスコープ規則が適用されます。COBOLでは変数名の長さは任意ですが、Pro*COBOLでは最初の30文字のみが有効になります。数字で始まるものも含め、有効なCOBOL識別子であればどれでもホスト変数識別子として使用できます。

ホスト変数の外部データ型およびそのソース・データベースまたはターゲット・データベース列の内部データ型は、同じである必要はありませんが、互換性が必要です。表4-9「内部データ型と外部データ型の間での変換」は、必要に応じてOracleによって自動的に変換される、互換性のあるデータ型を示しています。

Oracleデータ型

一般的に、ホスト・プログラムはデータベースにデータを入力し、データベースはホスト・プログラムにデータを出力します。Oracleは、入力データをデータベースの表に挿入し、出力データを選択して プログラム・ホスト変数に格納します。データ項目を格納するために、Oracleではそのデータ型を認識する必要があり、データ型により値の記憶形式と有効範囲が指定されます。

Oracleでは、内部データ型と外部データ型という2種類のデータ型が認識されます。内部データ型は、Oracleでデータベース列にデータを格納する方法を指定します。また、Oracleでは、データベース疑似列を表す内部データ型も使用されます。データベース疑似列は特定のデータ項目を戻すものの、表には実際の列はありません。

外部データ型は、データがホスト変数にどのように格納されるかを指定します。ホスト・プログラムからOracleにデータが入力されると、Oracleは必要に応じて、入力ホスト変数の外部データ型とデータベース列の内部データ型の変換を行います。また、Oracleからホスト・プログラムにデータを出力するときも、Oracleは必要に応じて、データベース列の内部データ型と出力ホスト変数の外部データ型の変換を行います。

注意:
動的SQL方法4またはデータ型の同値化を使用すると、デフォルトのデータ型変換をオーバーライドできます。データ型の同値化の詳細は、「DATE文字列フォーマットの明示的な制御」を参照してください。

表

Pro*COBOLでは、表ホスト変数(ホスト表と呼ばれます)を定義して、それを単一のSQL文で操作できます。SELECT文、FETCH文、DELETE文、INSERT文およびUPDATE文を使用すると、大量のデータの問合せおよび操作を簡単に行えます。

ホスト表の詳細は、第7章「ホスト表」を参照してください。

エラーおよび警告

埋込みSQL文を実行すると、エラーまたは警告が発生する場合があります。これらの結果を処理する方法が必要です。Pro*COBOLは、次のエラー処理方法を備えています。

- SQLCODE状態変数

- SQLSTATE状態変数

- SQLコミュニケーション領域(SQLCA)

- WHENEVER文

- Oracle通信領域(ORACA)

SQLCODE/SQLSTATE状態変数

SQL文の実行後、OracleサーバーはSQLCODEまたはSQLSTATEという変数にステータス・コードを戻します。ステータス・コードは、そのSQL文の実行に成功したか、エラーまたは警告状態が発生したかを示します。

SQLCA状態変数

SQLCAは、Oracleでプログラムにランタイム・ステータス情報を渡すために使用されるプログラム変数を定義するデータ構造体です。SQLCAを使用すると、直前に試みた処理に関するOracleからのフィードバックに基づいて、異なる処理を実行できます。たとえば、DELETE文が成功したかチェックし、成功した場合は削除された行数をチェックできます。

SQLCAによって、診断チェックおよびイベント処理ができます。実行時には、Oracleからプログラムに渡されるステータス情報をSQLCAで保持します。SQL文の実行後、Oracleにより図2-2に示すようにSQLCA変数が設定されて、結果が示されます。

図2-2 SQLCAの更新

INSERT文、UPDATE文またはDELETE文の実行の成否を確認でき、成功した場合には、何行処理されたかを確認できます。文の実行に失敗した場合は、原因の詳細な情報が得られます。

MODE={ANSI13 | ORACLE}のとき、SQLCAを宣言するには、SQLCAをハードコーディングするか、INCLUDE文を使用してプログラムにコピーする必要があります。SQLCAの宣言および使用方法は、「SQLコミュニケーション領域の使用」を参照してください。

WHENEVER文

WHENEVER文を使用すると、Oracleがエラーまたは警告状態を検出した際に自動的に行われるアクションを指定できます。アクションには、次の文から続行、サブプログラムのコール、ラベル付きの命令への分岐、段落の実行、停止などがあります。

ORACA

ランタイム・エラーについて、SQLCAに格納されている情報よりも詳細な情報が必要なときにORACAを使用します。ORACAは、Oracleの通信を扱うデータ構造です。この中にはカーソル統計情報、現行のSQL文に関する情報、オプションの設定、およびシステムの統計情報が含まれます。

プリコンパイラ・オプションおよびエラー処理

Oracleは、SQL文が成功したか失敗したかについて、状態変数SQLSTATEおよびSQLCODEで戻します。プリコンパイラ・オプションMODE=ORACLEのときは、SQLCAを組み込むことによってSQLCODEを宣言できます。MODE=ANSIの場合はSQLSTATEまたはSQLCODEを宣言する必要がありますが、SQLCAの宣言は不要です。

詳細は、第8章「エラー処理および診断」を参照してください。

SQL99構文のサポート

SQL規格により、規格に準拠するすべてのソフトウェア製品で、SQLアプリケーションを移植できます。Oracle機能は、ANSI/ISO SQL99規格(ANSI準拠の結合を含む)に準拠しています。Pro*Cobolでは、Oracle DatabaseでサポートされているすべてのSQL99機能がサポートされており、SELECT文、INSERT文、DELETE文およびUPDATE文と、DECLARE CURSOR文でのカーソル本体のSQL99構文がサポートされています。

プログラミング・ガイドライン

この項では、埋込みSQLの構文、コーディング規則、Pro*COBOL固有の機能および制限事項を説明します。簡単に参照できるように、項目をアルファベット順に記載してします。

略称

COBOLの標準略称を使用できます。たとえば、PICTURE ISをPIC、USAGE IS COMPUTATIONALをCOMPと記述できます。

大/小文字の区別なし

Pro*COBOLプリコンパイラのオプションと値、EXEC SQL文、インライン・コマンドおよびCOBOL文には大文字と小文字の区別がありません。Pro*COBOLプリコンパイラは大文字のトークンも小文字のトークンも受け入れます。

COBOLのバージョンのサポート

Pro*COBOLでは、使用しているオペレーティング・システムに標準のCOBOL (通常はCOBOL-85またはCOBOL-74)がサポートされます。両方のCOBOLをサポートするプラットフォームもあります。詳細は、使用しているシステム固有のOracleマニュアルを参照してください。

コーディング領域

プリコンパイラ・オプションFORMATは、ソース・コードの書式を指定します。FORMAT=ANSI (デフォルト)と指定すると、ANSI規格にできるかぎり準拠したコードを作成できます。ANSI規格では、1から6桁目にオプションの順序番号を、7桁目(インジケータ領域)にはコメント行または継続行を記述できます。

分割ヘッダー、セクション・ヘッダー、段落の名前、FDおよび01文は、8から11桁目(A領域)から始まります。EXEC SQL文、EXEC ORACLE文など、その他の文は、領域B (12から72桁)に記述する必要があります。ソース・コード書式のガイドラインは、コンパイラの規則によって変更できます。

FORMAT=TERMINALを指定すると、COBOL文を1桁目(一番左の桁)から始めるか、または1桁目をインジケータ領域にできます。この書式も、コンパイラの規則によって変更されます。

FORMAT=VARIABLEを指定すると、B領域の長さの柔軟性が許可されます。

COBOL文の書式が実際に受け付けられるかどうかを判断するには、使用しているプラットフォーム用のCOBOLコンパイラのマニュアルを参照してください。

注意:
このマニュアルのサンプルCOBOLコードでは、FORMAT=TERMINALに設定しています。デモ・ディレクトリのオンライン・サンプル・プログラムではFORMAT=ANSIになっています。

カンマ

SQLでは、次の例に示すように、カンマを使用してリスト項目を区切る必要があります。

EXEC SQL SELECT ENAME, JOB, SAL
INTO :EMP-NAME, :JOB-TITLE, :SALARY
FROM EMP
WHERE EMPNO = :EMP-NUMBER
END-EXEC.

COBOLでは、カンマまたは空白を使用してリスト項目を区切ることができます。たとえば、次の2つの文は等価です。

ADD AMT1, AMT2, AMT3 TO TOTAL-AMT.
ADD AMT1 AMT2 AMT3 TO TOTAL-AMT.

コメント

SQL文の中にCOBOLのコメント行を入れることができます。COBOLのコメント行は、インジケータ領域内で先頭にアスタリスク(*)を付けて始めます。

SQL文の中には、「- -」で始まるANSI SQLスタイルのコメントを行の最後に記述できます(ただし、SQL文の最終行の後には記述できません)。

行の残りの部分には、「*>」の2文字で始まるCOBOLコメントを記述できます。

SQL文には、C言語スタイル(/* ... */)のコメント文が記述できます。

次の例には、前述の4つのスタイルのコメントがすべて含まれています。

MOVE 12 TO DEPT-NUMBER. *> This is the software development group.
EXEC SQL SELECT ENAME, SAL
*    assign column values to output host variables
INTO :EMP-NAME, :SALARY    -- output host variables
/*  column values assigned to output host variables */
FROM EMP
WHERE DEPTNO = :DEPT-NUMBER
END-EXEC.    -- illegal Comment

コメントをネストしたり、SQL文の最終行の終了記号END-EXECの後にコメントを入れることはできません。

行の継続

次の例に示すように、COBOLの規則に従ってSQL文を次の行へ続けることができます。

EXEC SQL SELECT ENAME, SAL INTO :EMP-NAME, :SALARY FROM EMP
WHERE DEPTNO = :DEPT-NUMBER
END-EXEC.

継続インジケータは必要ありません。

ある行から次の行に文字列リテラルを継続するには、72桁までリテラルを記述します。次の行の7桁目にハイフン(-)、12桁以降に二重引用符を記述して、残りのリテラルを記述します。次に、例を示します。

WORKING STORAGE SECTION.
...
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01  UPDATE-STATEMENT  PIC X(80) VALUE "UPDATE EMP SET BON
-               "US = 500 WHERE DEPTNO = 20".
EXEC SQL END DECLARE SECTION END-EXEC.

Copy文

Copy文はPro*COBOLでは解析されません。そのため、COPY命令に含まれるファイルには、ホスト変数の定義を含めることも、埋込みSQL文を含めることもできません。かわりに、「INCLUDE文の使用」で説明しているINCLUDEプリコンパイラ文を使用します。INCLUDEを使用し、さらにDECLARE_SECTION=YESも使用する際には注意してください。グループ項目は、すべて宣言部の内部に配置するか、あるいはすべて外部に配置する必要があります。

DECIMAL-POINT IS COMMA句

Pro*COBOLでは、ENVIRONMENT DIVISIONでのDECIMAL-POINT IS COMMA句がサポートされます。ソース・ファイルにDECIMAL-POINT IS COMMA句が指定されていると、VALUE句内で数値リテラルの小数部分の開始記号としてカンマを使用できます。

たとえば、次の句は有効です。

IDENTIFICATION DIVISION.
PROGRAM-ID.  FOO
ENVIRONMENT DIVISION.
CONFIGURATION   SECTION.
SPECIAL-NAMES.
DECIMAL-POINT IS COMMA.                *>  <-- **
DATA DIVISION.
WORKING-STORAGE SECTION.
...
01  WDATA1          PIC      S9V999 VALUE  +,567. *>  <--- **
01  WDATA2          PIC      S9V999 VALUE  -,234. *>  <--- **
...

デリミタ

COBOLの文字列定数およびリテラルのデリミタの指定には、LITDELIMオプションを使用します。LITDELIM=APOSTと指定すると、Pro*COBOLではCOBOLコードを生成する際に引用符を使用します。LITDELIM=QUOTE (デフォルト)と指定すると、次に示すように二重引用符を使用します。

CALL "SQLROL" USING SQL-TMP0.

SQL文では、次の例に示すように、特殊文字または小文字を含む識別子は二重引用符で区切る必要があります。

EXEC SQL CREATE TABLE "Emp2" END-EXEC.

また、文字列定数を区切る場合は、次の例のように引用符を使用します。

EXEC SQL SELECT ENAME FROM EMP WHERE JOB = 'CLERK' END-EXEC.

Pro*COBOLは、Pro*COBOLソース・ファイルで使用されているデリミタに関係なく、LITDELIMの値で指定されたデリミタを生成します。

オプションの分割ヘッダー

次の分割ヘッダーはオプションです。

- IDENTIFICATION DIVISION

- ENVIRONMENT DIVISION

- DATA DIVISION

PROCEDURE DIVISIONヘッダーはオプションではありません。プリコンパイルできるソースは次のとおりです。

*IDENTIFICATION DIVISION header is optional
PROGRAM-ID.     HELLO.
*ENVIRONMENT DIVISION header is optional
CONFIGURATION SECTION.
*DATA DIVISION header is optional
WORKING-STORAGE SECTION.
PROCEDURE       DIVISION.
DISPLAY "Hello World!".
STOP RUN.

埋込みSQLの構文

Pro*COBOLプログラムでSQL文を使用する場合は、SQL文の前にEXEC SQLを指定し、SQL文の最後にEND-EXECキーワードを指定します。埋込みSQL構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

表意定数

HIGH-VALUE、ZEROおよびSPACEなどの表意定数は、SQL文では使用できません。たとえば、次のSQL文は無効です。

EXEC SQL DELETE FROM EMP WHERE COMM = ZERO END-EXEC.

このかわりに、次のように指定します。

EXEC SQL DELETE FROM EMP WHERE COMM = 0 END-EXEC.

ファイルの長さ

Pro*COBOLが処理できるソース・ファイルの長さには制限があります。内部で使用する変数によって、生成されるファイルのサイズが制限される場合があります。許容される行数の絶対的な制限はありませんが、次に示すようなソース・ファイルの状態によって、ファイル・サイズに制約が生じます。

- 埋込みSQL文の複雑さ(たとえば、バインド変数および定義変数の数)

- データベース名の使用の有無(たとえば、AT句を使用してデータベース名に接続する場合)

- 埋込みSQL文の数

この制限に関連した問題を防ぐには、複数のプログラム単位を使用してソース・ファイルのサイズを小さくします。

FILLERの使用

ホスト変数の宣言でワードFILLERを使用できます。ワードFILLERは、明示的に参照できないグループの基本項目を指定するときに使用します。次の宣言は有効です。

01  STOCK.
05  DIVIDEND     PIC X(5).
05  FILLER       PIC X.
05  PRICE        PIC X(6).

ホスト変数名

ホスト変数には、有効な標準COBOL識別子であればどれでも使用できます。変数名の長さに制限はありませんが、最初の30文字のみ有効になります。COBOLコンパイラが認識する有効文字の最大数は30です。

移植性を考慮する場合は、ホスト変数名を18文字以下(SQL標準での長さの要件)に制限することもできます。

アプリケーションで使用制限があるワードの一覧は、付録B「予約語、キーワードおよびネームスペース」を参照してください。

ハイフン付きの名前

静的SQL文ではハイフン付きのホスト変数名を使用できますが、動的SQLでは使用できません。たとえば、次の指定は無効です。

MOVE "DELETE FROM EMP WHERE EMPNO = :EMP-NUMBER" TO SQLSTMT.
EXEC SQL PREPARE STMT1 FROM SQLSTMT END-EXEC.

レベル番号

ホスト変数を宣言する際、レベル番号01から49および77を使用できます。Pro*COBOLでは、VARYING句を含む変数またはレベル49または77として宣言する擬似型の変数(先頭に「SQL-」が付くデータ型の変数)は使用できません。

MAXLITERALのデフォルト

MAXLITERALオプションを使用して、Pro*COBOLで生成される文字列リテラルの最大長を指定して、コンパイラ制限を超えないようにします。Pro*COBOLの場合はデフォルト値は256ですが、これより小さい値の指定が必要な場合もあります。IBM独自のS370オペレーティング・システムでは120です。

マルチバイト・データ型

マルチバイト・キャラクタ・データを扱うために、ANSI規格の各国語キャラクタ・セットのデータ型がサポートされています。使用しているコンパイラでPIC N句またはPIC G句がサポートされている場合は、これらの句によって固定長のNCHAR文字列を格納する変数が定義されます。可変長のマルチバイト各国語キャラクタ・セット文字列を格納するには、長さフィールドおよび文字列フィールドから構成されるCOBOLグループ項目を使用します。「VARCHAR変数」を参照してください。

クライアント側のグローバリゼーション・サポート各国語キャラクタ・セットを指定するために環境変数NLS_NCHARを使用できます。

SQLのNULL

SQLにおいて、NULLは欠落した、不明な、または不適切な列の値を表します。ゼロや空白に相当するものではありません。NVL関数を使用してNULLを非NULL値へ変換し、IS [NOT] NULL比較演算子を使用してNULLを検索し、標識変数を使用してNULLの挿入およびテストを行います。

段落およびセクションの名前

次の例に示すように、COBOLの標準的な段落の名前およびセクションの名前をSQL文と関連付けできます。

LOAD-DATA.
EXEC SQL
INSERT INTO EMP (EMPNO, ENAME, DEPTNO)
VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER)
END-EXEC.

また、次の例のようにWHENEVER ... DOまたはWHENEVER ... GOTOで段落の名前を参照することもできます。

PROCEDURE DIVISION.
MAIN.
EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC.
...
SQL-ERROR SECTION.
...

段落の名前は、すべて領域Aから始めます。

REDEFINES句

COBOLのREDEFINES句を使用して、グループ項目または基本項目を再定義できます。たとえば、次の宣言は有効です。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  REC-ID   PIC X(4).
01  REC-NUM  REDEFINES  REC-ID  PIC S9(4) COMP.
EXEC SQL END DECLARE SECTION END-EXEC.

および

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  STOCK.
05  DIVIDEND     PIC X(5).
05  PRICE        PIC X(6).
01  BOND  REDEFINES  STOCK.
05  COUPON-RATE  PIC X(4).
05  PRICE        PIC X(7).
EXEC SQL END DECLARE SECTION END-EXEC.

1つのINTO句で、グループ項目ホスト変数およびその再定義の両方の項目が使用されていても、Pro*COBOLは警告もエラーも発行しません。

関係演算子

表2-2のように、COBOLの関係演算子はそれに対応するSQLの関係演算子と異なります。また、COBOLでは記号のかわりにワードを使用できますが、SQLでは使用できません。

表2-2 関係演算子

SQL演算子

COBOL演算子

=

=、EQUAL TO

< >, !=, ^=

NOT=、NOT EQUAL TO

>

>、GREATER THAN

<

<、LESS THAN

>=

>=、GREATER THAN OR EQUAL TO

<=

<=、LESS THAN OR EQUAL TO

文終了記号

COBOLの文はCOBOL文またはSQL文、あるいはその両方を1つ以上含み、ピリオドで終わります。次の例に示すように、条件文では最後の文のみピリオドで終わる必要があります。

IF EMP-NUMBER = ZERO
MOVE FALSE TO VALID-DATA
PERFORM GET-EMP-NUM UNTIL VALID-DATA = TRUE
ELSE
EXEC SQL DELETE FROM EMP
WHERE EMPNO = :EMP-NUMBER
END-EXEC
ADD 1 TO DELETE-TOTAL.
END-IF.

SQL文は、カンマ、ピリオドまたはその他のCOBOL文で終了できます。

宣言部

データベース・サーバーとアプリケーション・プログラムの間のデータの受渡しには、ホスト変数とエラー処理が必要です。この項では、これらの必要条件を満たす方法を説明します。

宣言部の内容

宣言部は、次の文で開始します。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.

次の文で終了します。

EXEC SQL END DECLARE SECTION END-EXEC.

この2つの文の間に指定できるのは、次の要素のみです。

- ホスト変数および標識変数の宣言

- ホスト変数以外のCOBOL変数

- EXEC SQL DECLARE文

- EXEC SQL INCLUDE文

- EXEC SQL VAR文

- EXEC ORACLE文

- COBOLコメント

例

プログラムで使用する4つのホスト変数を宣言した例を次に示します。

WORKING-STORAGE SECTION.
...
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01  EMP-NUMBER     PIC 9(4)  COMP VALUE ZERO.
01  EMP-NAME       PIC X(10) VARYING.
01  SALARY         PIC S9(5)V99 COMP-3 VALUE ZERO.
01  COMMISSION     PIC S9(5)V99 COMP-3 VALUE ZERO.
EXEC SQL END DECLARE SECTION END-EXEC.

プリコンパイラ・オプションDECLARE_SECTION

宣言部はオプションです。Pro*COBOLには、リリース8.0以前のリリースとの下位互換性を保つために、宣言部内の宣言のみホスト変数として使用するかどうかを明示的に制御できるコマンドライン・プリコンパイラ・オプションが用意されています。このオプションは次のとおりです。

DECLARE_SECTION={YES | NO}(デフォルトはNO)

DECLARE_SECTIONオプションは、コマンドラインまたは構成ファイル内で指定する必要があります。

MODE=ORACLEおよびDECLARE_SECTION=YESと設定した場合は、宣言部の中で宣言した変数のみホスト変数として使用できます。MODE=ANSIと設定すると、DECLARE_SECTIONは暗黙的にYESに設定されます。マクロ・オプションおよびマイクロ・オプションの詳細は、「マクロ・オプションおよびマイクロ・オプション」を参照してください。

DECLARE_SECTIONをYESに設定した場合は、SQL文中で使用するすべてのプログラム変数を宣言部内で宣言する必要があります。DECLARE_SECTIONをNOに設定した場合は、宣言部を使用するかどうかを選択できます。この場合、ホスト変数および標識変数は宣言部の中でも宣言部の外でも宣言できます。このようなオプションとしての使用は、リリース8.0以下のリリースと異なる点です。オプションの詳細は、「DECLARE_SECTION」を参照してください。

1つのプリコンパイル・ユニットで複数の宣言部を使用できます。さらに、複数の独立したプリコンパイル・ユニットを1つのホスト・プログラムに含めることもできます。

INCLUDE文の使用

INCLUDE文を使用して、ホスト・プログラムにファイルをコピーできます。次に例を示します。

*    Copy in the SQL Communications Area (SQLCA)
EXEC SQL INCLUDE SQLCA END-EXEC.
*    Copy in the Oracle Communications Area (ORACA)
EXEC SQL INCLUDE ORACA END-EXEC.

INCLUDEは、どのファイルに対しても実行できます。Pro*COBOLプログラムをプリコンパイルすると、EXEC SQL INCLUDE文はそれぞれ、その文で指定されたファイルのコピーに置き換えられます。

ファイルの拡張子

システムでファイル拡張子が使用される場合にファイル拡張子の指定を省略すると、Pro*COBOLではソース・ファイルのデフォルトの拡張子(通常はCOB)が使用されます。詳細は、使用しているシステム固有のOracleマニュアルを参照してください。

検索パス

システムでディレクトリが使用される場合は、次のようにINCLUDEオプションを使用して、INCLUDEするファイルの検索パスを設定できます。

INCLUDE=path

このとき、pathのデフォルト値はカレント・ディレクトリです。

Pro*COBOLは、最初にカレント・ディレクトリを検索し、次にINCLUDEオプションで指定されたディレクトリを検索して、最後に標準INCLUDEファイル用のディレクトリを検索します。このため、SQLCAやORACAなどの標準ファイルのパスを指定する必要はありません。標準以外のファイルについては、カレント・ディレクトリに格納されている場合を除いてパスが必要です。

また次のように、コマンドラインで複数のパスを指定することもできます。

... INCLUDE=<path1> INCLUDE=<path2> ...

複数のパスを指定すると、Pro*COBOLにより、カレント・ディレクトリ、path1ディレクトリ、path2ディレクトリの順に検索されます。標準INCLUDEファイルを含むディレクトリは最後に検索されます。パスの構文はシステムによって異なります。詳細は、使用しているシステム固有のOracleマニュアルを参照してください。

検索パスを指定しても、Pro*COBOLでは最初に現在のディレクトリでファイルを検索します。INCLUDEするファイルが別のディレクトリにある場合、現在のディレクトリ、または検索パス上の先行する他のディレクトリに、同じ名前のファイルがないことを確認してください。大文字と小文字が区別されるオペレーティング・システムを使用している場合は、ファイルを格納したときと同じファイル名を大文字と小文字を区別して指定してください。.

ネストされたプログラム

COBOLにおけるプログラムのネストは、あるプログラムを別のプログラムの内側に配置することを意味します。包含されたプログラムは、自身を包含しているプログラムのリソースの一部を参照できます。名前はプログラム内でのみ認識されるため、上位プログラムとネストされたプログラムの内部で使用されている名前が同一であり、かつ競合せずに異なるデータ項目を表す場合もあります。ただし、上位プログラムの構成セクションに記述された名前は、ネストされたプログラムで参照されることがあります。

GLOBAL句をサポートしないコンパイラもあります。Pro*COBOLはGLOBAL句を含むコードを生成することにより、ネストされたプログラムをサポートします。GLOBAL句が無条件に生成されるのを防ぐには、プリコンパイラ・オプションでNESTED=NOと指定します。NESTED(=YESまたはNO)のデフォルトはYESで、構成ファイルまたはコマンドラインで指定できますが、インラインで(EXEC ORACLE文)指定することはできません。

関連項目: 「NESTED」を参照してください。

プログラムでは、ネストされたプログラムを複数記述できます。同様に、ネストされたプログラムについても、その中にさらにネストされたプログラムを記述できます。ネストされたプログラムは、それを含むプログラムのEND PROGRAMヘッダーの直前に記述する必要があります。

ネストされたプログラムをコールできるのは、そのプログラムを直接的または間接的に含むプログラムのみです。ネストされたプログラムを別のプログラム(ネストのツリー構造の別の分岐にあるプログラムも含む)からコールする場合は、ネストされたプログラムのPROGRAM-ID段落にCOMMON句を記述します。COMMONは、ネストされたプログラムでのみ使用できます。

PROGRAM-ID.  <nested-program-name> COMMON.

ファイル定義にGLOBAL句を使用して、レベル01のデータ項目(自動的にグローバルになる従属項目)を記述できます。このように記述したデータ項目は、それらのデータ項目に直接的または間接的に含まれるすべてのサブプログラムで参照できます。上位プログラムにはGLOBALを使用します。上位プログラムでGLOBALと宣言された名前と同じ名前がネストされたプログラムで定義されていると、COBOLではネストされたプログラムの中の宣言が使用されます。データ項目にREDEFINES句が使用されているときは、GLOBALはREDEFINESの後に記述する必要があります。

FD file-name GLOBAL ...
01 data-name1 GLOBAL ...
01 data-name2 REDEFINES data-name3 GLOBAL ...

ネストされたプログラムのサポート

Pro*COBOLでは、1つのソース・ファイル内に埋込みSQLを持つ複数のネストされたプログラムを格納できます。上位プログラムでグローバルとしてマークされた、上位プログラム・レベルで有効なホスト変数である01レベルの項目はすべて、上位プログラムが直接的または間接的に含むすべてのプログラムで、有効なホスト変数として使用できます。次の例を考えてみます。

IDENTIFICATION DIVISION.
PROGRAM-ID. MAINPROG.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 REC1  GLOBAL.
05    VAR1   PIC X(10).
05    VAR2   PIC X(10).
01 VAR1  PIC X(10) GLOBAL.
EXEC SQL END DECLARE SECTION END-EXEC.

PROCEDURE DIVISION.
...
<main program statements>
...
IDENTIFICATION DIVISION.
PROGRAM-ID. NESTEDPROG.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

01 VAR1   PIC S9(4).

PROCEDURE DIVISION.
...
EXEC SQL SELECT X, Y INTO :REC1 FROM ... END-EXEC.

EXEC SQL SELECT X INTO :VAR1 FROM ... END-EXEC.

EXEC SQL SELECT X INTO :REC1.VAR1 FROM ... END-EXEC.
...
END PROGRAM NESTEDPROG.
END PROGRAM MAINPROG.

メイン・プログラムはホスト変数REC1をグローバル変数として宣言しているため、ネストされたプログラムは最初のSELECT文で宣言なしでREC1を使用することができます。VAR1はグローバル変数としても、ネストされたプログラムのローカル変数としても宣言されています。そのため、2番目のSELECT文はS9(4)として宣言されたVAR1を使用し、グローバル宣言をオーバーライドします。3番目のSELECT文では、PIC X(10)として宣言されたREC1のグローバル変数VAR1が使用されています。

前述の例は、DECLARE_SECTION=NOが使用されている場合の結果を説明しています。DECLARE_SECTION=YESの場合、ホスト変数が宣言部で宣言されていない場合、Pro*COBOLはホスト変数を認識しません。DECLARE_SECTION=YESと指定して前述のプログラムをプリコンパイルすると、2番目のSELECT文の結果、あいまいなホスト変数エラーが発生します。最初のSELECT文および3番目のSELECT文は同様に動作します。

注意: 再帰的なネストされたプログラムは、サポートされていません。

SQLCAの宣言

ネストされたプログラムでは、提供される組込みSQLCA (「SQLCA状態変数」を参照)の定義はグローバルとして宣言されるため、SQLCAの宣言は上位プログラム内でのみ必要になります。SQLCAは、新しいSQL文が実行されるたびに変更できます。提供されるSQLCAはいつでも変更できるため、ネストされたプログラムで追加のSQLCA領域を宣言する場合にはグローバル指定を削除できます。これはSQLDAおよびORACAにも適用されます。

ネストされたプログラムの例

デモ・ディレクトリのSAMPLE13.PCOを参照してください。

条件付きプリコンパイル

条件付きプリコンパイルとは、特定の条件に基づいてコード・セクションをホスト・プログラムに組み込む(または除外する)プリコンパイルの方法です。たとえば、UNIXでプリコンパイルするときにはあるコード・セクションを組み込み、VMSでプリコンパイルするときには別のコード・セクションを組み込むことができます。条件付きプリコンパイルの使用により、様々な環境で実行できるプログラムを作成できます。

環境および処理を定義する文によってコードの条件文が区切られます。コード・セクションには、ホスト言語の文を記述することも、EXEC SQL文を記述することもできます。次の文でプリコンパイルの条件を制御します。

*   -- define a symbol
EXEC ORACLE DEFINE symbol END-EXEC.
*    -- if symbol is defined
EXEC ORACLE IFDEF symbol  END-EXEC.
*   -- if symbol is not defined
EXEC ORACLE IFNDEF symbol END-EXEC.
*            -- otherwise
EXEC ORACLE ELSE END-EXEC.
*           -- end this control block
EXEC ORACLE ENDIF END-EXEC.

条件文はEND-EXECで終了する必要があります。

注意:
使用しているコンパイラの条件付きコンパイル機能が、Pro*COBOLでサポートされない場合があります。

例

次の例では、シンボルSITE2が定義されているときのみSELECT文がプリコンパイルされます。

EXEC ORACLE IFDEF SITE2 END-EXEC.
EXEC SQL SELECT DNAME
INTO :DEPT-NAME
FROM DEPT
WHERE DEPTNO = :DEPT-NUMBER
EXEC ORACLE ENDIF END-EXEC.

次の例に示すように条件ブロックはネストできます。

EXEC ORACLE IFDEF OUTER END-EXEC.
EXEC ORACLE IFDEF INNER END-EXEC.
...
EXEC ORACLE ENDIF END-EXEC.
EXEC ORACLE ENDIF END-EXEC.

ホスト言語または埋込みSQLのコードをIFDEFとENDIFの間に記述し、シンボルを定義しないことによって、そのコードをコメントとして扱えます。

シンボルの定義

シンボルを定義するには2通りの方法があります。1つは、次の文をホスト・プログラムに組み込む方法です。

EXEC ORACLE DEFINE symbol END-EXEC.

もう1つは、次の構文を使用してコマンドラインでシンボルを定義する方法です。

... INAME=filename ... DEFINE=symbol

symbolの部分は大/小文字区別がありません。

Pro*COBOLをシステムにインストールした時点で、ポート固有のいくつかのシンボルが事前定義されています。たとえば、オペレーティング・システムの事前定義済シンボルには、CMS、MVS、UNIXおよびVMSがあります。

注意:
DEFINE SYMBOL名で、先頭に数字を使用した場合、またはダッシュを含めた場合、プリコンパイル時にリカバリ不可能なエラーが発生します。DEFINE SYMBOL名では、アンダースコアを使用すること、および先頭以外で数字を使用することはできます。

分割プリコンパイル

複数のCOBOLプログラム・モジュールを別々にプリコンパイルし、後でリンクして1つの実行可能プログラムを作成できます。これにより、プログラムの機能コンポーネントの作成とデバッグを複数のプログラマが分担して行う場合に必要とされる、モジュラー・プログラミングが可能になります。個々のプログラム・モジュールを同じ言語で作成する必要はありません。

ガイドライン

次のガイドラインに従うと、いくつかの問題を回避できます。

カーソルの参照

カーソル名はSQL識別子であり、その有効範囲はプリコンパイル・ユニットです。このため、カーソルの動作が複数のプリコンパイル・ユニット(ファイル)にまたがることはありません。つまり、1つのファイルの中で宣言したカーソルを、別のファイルでオープンまたはフェッチすることはできません。分割プリコンパイルを実行するときは、指定のカーソルに対する定義と参照がすべて1つのファイルに記述されているか確認してください。

MAXOPENCURSORSの指定

Oracleに接続するプログラム・モジュールをプリコンパイルするときは、MAXOPENCURSORSに、どのプログラム・モジュールについても十分な大きさの値を指定してください。指定したMAXOPENCURSORSの値は、別のプログラム・モジュールに使用すると無視されます。実行時には、その接続に有効な値のみ使用されます。

単一のSQLCAの使用

SQLCAの1つのメモリー領域のみを使用する場合の処理は、使用するPro*COBOLのバージョンによって異なります。

バージョン1.8以下

SQLCAをグローバルに宣言する必要があります。そのためには、次の行を変更してSQLCA.COBファイルを修正します。

01  SQLCA.

これを次のように変更します。

01  SQLCA EXTERNAL.

SQLCA.cobからコピーしたSQLCAのハードコード定義を組み込み、前述の変更を行う方法もあります。その場合も、SQLCAの定義をすべてのプリコンパイル・ユニットに組み込む必要があります。

バージョン2以上

バージョン2以上のPro*COBOLでは、SQLCAがファイル・システムからコピーされません。プリコンパイラによって生成されます。これらのバージョンでSQLCA構造を共有する必要がある場合は、次の文を使用しません。

EXEC SQL INCLUDE SQLCA END-EXEC

かわりに、次のコードを使用します。

EXEC SQL INCLUDE SQLCA.ANX END-EXEC

これにより、プリコンパイラによってSQLCA構造が生成され、EXTERNALキーワードが自動的に追加されます。

単一のDATE_FORMATの使用

各プログラム・モジュールでは、DATEに同じ書式の文字列を使用する必要があります。

制限

明示カーソルの参照は、すべて同じプログラム・ファイル内で行います。別のモジュールで宣言されたカーソルの操作はできません。カーソルの詳細は、第4章を参照してください。

また、SQL文が記述されているプログラム・ファイルはすべて、ローカルSQL文のスコープ内にあるSQLCAを必要とします。

コンパイルおよびリンク

実行可能プログラムを作成するには、Pro*COBOLによって生成されたソース・ファイルをコンパイルし、その結果得られたオブジェクト・モジュールを、SQLLIBおよびシステム固有のOracleライブラリ内の必要なモジュールとリンクさせる必要があります。

リンカーはオブジェクト・モジュール内のシンボリック参照を解決します。これらの参照で競合が発生すると、リンクは失敗します。プリコンパイル済のプログラムにサード・パーティのソフトウェアをリンクするときに、このような競合が起こる可能性があります。こうした問題が生じるのは、サード・パーティのソフトウェアの中にはOracleと互換性のないものがあるためです。Oracleサポート・サービスに問い合せて、使用するソフトウェアがサポートされているかどうかを確認してください。

コンパイルおよびリンクの方法はシステムによって異なります。たとえば、システムによっては、ホスト言語プログラムをコンパイルするときにコンパイラの最適化をオフにする必要があります。手順は、使用しているシステム固有のOracleマニュアルを参照してください。

DEPT表およびEMP表のサンプル

このマニュアルで紹介するほとんどのプログラム例では、DEPTおよびEMPという2つのサンプル・データベース表が使用されています。デモ・ディレクトリにこの2つの表が含まれていない場合は、サンプル・プログラムを実行する前に表を作成してください。次に示すのはそれぞれの表の定義です。

CREATE TABLE DEPT (DEPTNO NUMBER(2), DNAME VARCHAR2(14), LOC VARCHAR2(13));

CREATE TABLE EMP (EMPNO NUMBER(4) primary key, ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER(4), HIREDATE DATE, SAL NUMBER(7,2), COMM NUMBER(7,2), DEPTNO NUMBER(2));

DEPTデータおよびEMPデータのサンプル

DEPT表およびEMP表には、それぞれ次のデータ行が設定されています。

DEPTNO  DNAME      LOC
------- ---------- ---------
10      ACCOUNTING NEW YORK
20      RESEARCH   DALLAS
30      SALES      CHICAGO
40      OPERATIONS BOSTON

EMPNO ENAME   JOB          MGR  HIREDATE    SAL   COMM  DEPTNO
----- ------- --------- ------ --------- ------ ------ -------
7369 SMITH   CLERK       7902 17-DEC-80    800             20
7499 ALLEN   SALESMAN    7698 20-FEB-81   1600    300      30
7521 WARD    SALESMAN    7698 22-FEB-81   1250    500      30
7566 JONES   MANAGER     7839 02-APR-81   2975             20
7654 MARTIN  SALESMAN    7698 28-SEP-81   1250   1400      30
7698 BLAKE   MANAGER     7839 01-MAY-81   2850             30
7782 CLARK   MANAGER     7839 09-JUN-81   2450             10
7788 SCOTT   ANALYST     7566 19-APR-87   3000             20
7839 KING    PRESIDENT        17-NOV-81   5000             10
7844 TURNER  SALESMAN    7698 08-SEP-81   1500             30
7876 ADAMS   CLERK       7788 23-MAY-87   1100             20
7900 JAMES   CLERK       7698 03-DEC-81    950             30
7902 FORD    ANALYST     7566 03-DEC-81   3000             20
7934 MILLER  CLERK       7782 23-JAN-82   1300             10

サンプルEMPプログラム: SAMPLE1.PCO

埋込みSQLについては、プログラム例を見るとよくわかります。次のプログラムは、demoディレクトリのSAMPLE1.PCOです。

プログラムでデータベースにログインし、従業員番号を入力すると、従業員名、給与およびコミッションをEMP表に問い合せます。選択の結果はホスト変数EMP-NAME、SALARYおよびCOMMISSIONに格納されます。また、ホスト標識変数COMM-INDを使用して列COMMISSION内のNULL値を検出します。「標識変数」を参照してください。

次に、段落DISPLAY-INFOによって結果が表示されます。

COBOL変数USERNAME、PASSWDおよびEMP-NAMEは、VARYING句によって宣言されます。VARYING句により、VARCHARという可変長文字列のOracle外部データ型を使用できます。このデータ型は、「VARCHAR変数」を参照してください。

エラー処理のためにSQLCAコミュニケーション領域が組み込まれています。エラーが発生すると、段落SQL-ERRORが実行されます。「SQLコミュニケーション領域の使用」を参照してください。

ここで使用されているBEGIN DECLARE SECTION文およびEND DECLARE SECTION文は、プリコンパイラ・オプションDECLARE_SECTIONがYES、またはオプションMODEがANSIに設定されていない場合、省略できます。「MODE」を参照してください。

エラー処理のためにWHENEVER文を使用しています。詳細は、「WHENEVERディレクティブ」を参照してください。

このプログラムは、従業員番号として0 (ゼロ)を入力すると終了します。

注意:
この機能を簡単に示すために、この例では、通常デプロイされたシステムで使用されるパスワード管理技術を実行しません。本番環境では、Oracle Databaseのパスワード管理のガイドラインに従って、すべてのサンプル・アカウントを無効にしてください。パスワード管理のガイドラインおよび他のセキュリティの推奨事項については、『Oracle Databaseセキュリティ・ガイド』を参照してください。

* This program logs on to ORACLE, prompts the user for an employee number,
* queries the database for the employee's name, salary, and commission, then
* displays the result. The program terminates when the user enters a 0.              *
ID DIVISION.

PROGRAM-ID. QUERY.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME          PIC X(10) VARYING.
01  PASSWD            PIC X(10) VARYING.
01  EMP-REC-VARS.
05  EMP-NAME      PIC X(10) VARYING.
05  EMP-NUMBER    PIC S9(4) COMP VALUE ZERO.
05  SALARY        PIC S9(5)V99 COMP-3 VALUE ZERO.
05  COMMISSION    PIC S9(5)V99 COMP-3 VALUE ZERO.
05  COMM-IND      PIC S9(4) COMP VALUE ZERO.
EXEC SQL END DECLARE SECTION END-EXEC.

EXEC SQL INCLUDE SQLCA END-EXEC.

01  DISPLAY-VARIABLES.
05  D-EMP-NAME    PIC X(10).
05  D-SALARY      PIC Z(4)9.99.
05  D-COMMISSION  PIC Z(4)9.99.
05  D-EMP-NUMBER  PIC 9(4).

01 D-TOTAL-QUERIED   PIC 9(4) VALUE ZERO.

PROCEDURE DIVISION.
BEGIN-PGM.
EXEC SQL WHENEVER SQLERROR
DO PERFORM SQL-ERROR END-EXEC.

PERFORM LOGON.

QUERY-LOOP.
DISPLAY " ".
DISPLAY "ENTER EMP NUMBER (0 TO QUIT): "
WITH NO ADVANCING.

ACCEPT D-EMP-NUMBER.

MOVE D-EMP-NUMBER TO EMP-NUMBER.
IF (EMP-NUMBER = 0)
PERFORM SIGN-OFF.
MOVE SPACES TO EMP-NAME-ARR.
EXEC SQL WHENEVER NOT FOUND GOTO NO-EMP END-EXEC.
EXEC SQL SELECT ENAME, SAL, NVL(COMM, 0)
INTO :EMP-NAME, :SALARY, :COMMISSION:COMM-IND
FROM EMP
WHERE EMPNO = :EMP-NUMBER
END-EXEC.
PERFORM DISPLAY-INFO.
ADD 1 TO D-TOTAL-QUERIED.
GO TO QUERY-LOOP.

NO-EMP.
DISPLAY "NOT A VALID EMPLOYEE NUMBER - TRY AGAIN.".
GO TO QUERY-LOOP.

LOGON.
MOVE "SCOTT" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "TIGER" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE AS USER: ", USERNAME-ARR.

DISPLAY-INFO.
DISPLAY " ".
DISPLAY "EMPLOYEE    SALARY    COMMISSION".
DISPLAY "--------    ------    ----------".
MOVE EMP-NAME-ARR TO D-EMP-NAME.
MOVE SALARY TO D-SALARY.
IF COMM-IND = -1
DISPLAY D-EMP-NAME, D-SALARY, "          NULL"
ELSE
MOVE COMMISSION TO D-COMMISSION
DISPLAY D-EMP-NAME, D-SALARY, "      ", D-COMMISSION
END-IF.

SIGN-OFF.
DISPLAY " ".
DISPLAY "TOTAL NUMBER QUERIED WAS ",
D-TOTAL-QUERIED, ".".
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY.".
DISPLAY " ".
EXEC SQL COMMIT WORK RELEASE END-EXEC.
STOP RUN.

SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

3 データベースの概念

この章では、CONNECT文およびそのオプション、Oracle Net Servicesおよびネットワーク接続に関連する文を説明します。トランザクション処理についても解説します。Oracleデータに対する変更の確定または取消しを制御する方法を含めて、データベースの整合性を保つための基本的な技術を学習します。

- Oracleへの接続

- デフォルトのデータベースおよび接続

- 基本用語

- トランザクションによるデータベースの保護

- トランザクションの開始および終了

- COMMIT文の使用

- ROLLBACK文の使用

- SAVEPOINT文の使用

- RELEASEオプションの使用方法

- SET TRANSACTION文の使用

- デフォルトのロックのオーバーライド

- コミット時のフェッチ

- 分散トランザクションの処理

- トランザクション処理のガイドライン

Oracleへの接続

Pro*COBOLプログラムは、データの問合せや操作を行う前に、Oracleにログインする必要があります。ログインするには、次に示すようにCONNECT文を使用します。

EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.

USERNAMEおよびPASSWDはPIC X(n)またはPIC X(n) VARYINGホスト変数です。また、次の文も使用できます。

EXEC SQL
CONNECT :USR-PWD
END-EXEC.

この場合、ホスト変数USR-PWDには、スラッシュ(/)で区切られたユーザー名およびパスワードに続き、オプションのtnsnames.oraエイリアス(@TNSALIAS)が含まれます。

CONNECT文の構文には、オプションのALTER AUTHORIZATION句を使用できます。次がCONNECT文の構文です。

EXEC SQL
CONNECT { :user IDENTIFIED BY :oldpswd | :usr_psw }
[[AT { dbname | :host_variable }] USING :connect_string ]
[ {ALTER AUTHORIZATION :newpswd  | IN {SYSDBA | SYSOPER} MODE} ]
END-EXEC.

ALTER AUTHORIZATION句の詳細は、「実行時のパスワード変更」を参照してください。SYSDBAおよびSYSOPERオプションの詳細は、「SYSDBA権限またはSYSOPER権限」を参照してください。

CONNECT文は、プログラムが実行する最初のSQL文であることが必要です。したがって、別の実行SQL文を、位置的にはCONNECT文の前に記述できますが、論理的にはCONNECT文の前に記述できません。プリコンパイラ・オプションAUTO_CONNECT=YESの場合、CONNECT文は必要ありません。

Oracleユーザー名およびパスワードを別々に指定する場合は、2つのホスト変数を文字列またはVARCHAR変数として定義します。ユーザー名およびパスワードの両方を含んだユーザーIDを指定する場合は、必要なホスト変数は1つのみです。

CONNECTを実行する前に、ユーザー名とパスワードの変数を設定する必要があります。設定しない場合、CONNECTは失敗します。プログラムのプロンプトで値の入力を求めることも、次のように値をハードコードすることもできます。

WORKING STORAGE SECTION.
...
01  USERNAME  PIC X(10).
01  PASSWD    PIC X(10).
...
...
PROCEDURE DIVISION.
LOGON.
EXEC SQL WHENEVER SQLERROR GOTO LOGON-ERROR END-EXEC.
MOVE "SCOTT" TO USERNAME.
MOVE "TIGER" TO PASSWD.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.

ただし、ユーザー名およびパスワードはCONNECT文にハードコードできません。また、二重引用符付きのリテラルも使用できません。たとえば、次の2つの文は無効です。

EXEC SQL
CONNECT SCOTT IDENTIFIED BY TIGER
END-EXEC.

EXEC SQL
CONNECT "SCOTT" IDENTIFIED BY "TIGER"
END-EXEC.

デフォルトのデータベースおよび接続

1つのPro*COBOLプログラムの中で複数のデータベース接続を同時に保持できます。

同時ログイン

Pro*COBOLは、Oracle Net Servicesを介した分散処理に対応しています。アプリケーションは、ローカル・データベースおよびリモート・データベースの任意の組合せに同時にアクセスしたり、同じデータベースへの複数の接続を確立できます。図3-1では、アプリケーション・プログラムは1つのローカルOracle Databaseおよび3つのリモートOracle Databaseと通信しています。ORA2、ORA3およびORA4はCONNECT文中で使用される論理名です。

図3-1 Oracleを介した接続

Oracle Net Servicesは、ネットワーク上の異なるマシン間およびオペレーティング・システム間に存在する境界を排除することによって、Oracleのツール製品に分散処理環境を提供します。この項では、Oracle Net Servicesを介した分散処理がPro*COBOLでどのようにサポートされているかを説明します。さらに、アプリケーションで次の処理を行う方法を学びます。

- 他のデータベースへの直接または間接アクセス

- ローカルおよびリモート・データベースの任意の組合せへの同時アクセス

- 同一のデータベースへの複数接続

通常、EXEC SQL CONNECT :USR-PWD END-EXECで確立した1つの接続で十分です。接続先のデータベースはUSR-PWD句の指定によって決まります。USR-PWD句にデフォルトのデータベースのユーザー名およびパスワードが含まれる場合は、セッションのデフォルトとして定義されたデータベースに接続されます。「ユーザー名/パスワード@REMDB」が含まれる場合は、Oracle Net Services構成で定義されたように、Oracle Net Servicesを介してREMDBデータベースに接続されます。(USING句を使用してOracle Net Services接続文字列を指定する方法もあります。)これがデフォルトの接続です。

同じデータベースまたは別のデータベースへの同時接続の追加には、AT句、つまりEXEC SQL AT DB1 CONNECT :USR-PWD END-EXECを使用します。AT句の後の名前は、非デフォルト接続として一意に識別され、AT句の後にある同じ名前のSQL文がその接続に対して実行されます。SQL文の中にAT句の指定がない場合は、デフォルトの接続に対して実行されます。

データベース名は一意にする必要がありますが、2つ以上のデータベース名で同じ接続を指定できます。したがって、任意のノード上のデータベースに対して複数の接続を確立できます。

ユーザー名/パスワードの使用方法

通常は、次のようにしてOracleへの接続を確立します。

EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWORD END-EXEC.

また、次のような指定もできます。

EXEC SQL CONNECT :USR-PWD END-EXEC.

USR-PWDには有効なOracle接続文字列が含まれます。

「自動ログイン」に示すように、自動的にログインすることもできます。

これらは、単純化したCONNECT文のサブセットです。詳細は、この章の以降の項および「CONNECT (実行可能埋込みSQL拡張機能)」を参照してください。

名前指定データベース接続

次は、名前指定データベースに接続する例です。通常は、名前指定データベース接続を使用するのは同時接続が複数ある場合のみです。次の例では、単一接続の構文を示しています。

* --  Declare necessary host variables
WORKING-STORAGE SECTION.
...
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME  PIC X(10) .
01  PASSWORD  PIC X(10) .
01  DB-STRING PIC X(20) .
...
EXEC SQL END DECLARE SECTION END-EXEC.
...
PROCEDURE DIVISION.
MOVE "scott" TO USERNAME.
MOVE "tiger" TO PASSSWORD.
MOVE "nyremote" TO DB-STRING.
...
* --  Assign a unique name to the database connection.
EXEC SQL DECLARE DBNAME DATABASE END-EXEC.
* --  Connect to the nondefault database
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWORD
AT DBNAME USING :DB-STRING
END-EXEC.

この例の識別子は、次の目的で使用されています。

- ホスト変数USERNAMEおよびPASSWORDは、有効ユーザーを識別します。

- ホスト変数DB-STRINGには、リモート・ノードの非デフォルト・データベースにログインするためのOracle Net Servicesの構文を含めます。

- 宣言されていない識別子DBNAMEにより、非デフォルトの接続に名前を付けます。これはOracleが使用する識別子であり、ホスト変数でもプログラム変数でもありません。

USING句は、DBNAMEに対応付けるネットワーク、マシンおよびデータベースを指定します。その後、(DBNAMEを指定した) AT句を使用したSQL文が、DB-STRINGで指定されたデータベースで実行されます。

もう1つの方法として、次の例に示すように、AT句で文字ホスト変数を使用できます。

* --  Declare necessary host variables
WORKING-STORAGE SECTION.
...
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME  PIC X(10).
01  PASSWORD  PIC X(10).
01  DB-NAME   PIC X(10).
01  DB-STRING PIC X(20).
...
EXEC SQL END DECLARE SECTION END-EXEC.
...
PROCEDURE DIVISION.
MOVE "scott" TO USERNAME.
MOVE "tiger" TO PASSSWORD.
MOVE "oracle1" TO DB-NAME.
MOVE "nyremote" TO DB-STRING.
...
* --  Connect to the nondefault database
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWORD
AT :DB-NAME USING :DB-STRING
END-EXEC.

DB-NAMEがホスト変数の場合は、DECLARE DATABASE文は必要ありません。DBNAMEが宣言されていない識別子の場合にのみ、CONNECT... AT DBNAME文を実行する前にDECLARE DBNAME DATABASE文を実行する必要があります。

SQL操作。権限を付与されている場合は、非デフォルトの接続で任意のSQL DML文を実行できます。たとえば、次のように入力します。

EXEC SQL AT DBNAME SELECT ...
EXEC SQL AT DBNAME INSERT ...
EXEC SQL AT DBNAME UPDATE ...

次の例では、DB-NAMEはホスト変数です。

EXEC SQL AT :DB-NAME DELETE ...

カーソルの制御。OPEN、FETCHおよびCLOSEなどのカーソルの制御文は例外で、AT句は使用しません。カーソルと明示的に識別されたデータベースを対応付ける場合は、次に示すとおり、DECLARE CURSOR文でAT句を使用してください。

EXEC SQL AT :DB-NAME DECLARE emp_cursor CURSOR FOR ...
EXEC SQL OPEN emp_cursor ...
EXEC SQL FETCH emp_cursor ...
EXEC SQL CLOSE emp_cursor END-EXEC.

DB-NAMEがホスト変数の場合、その宣言は、宣言したカーソルを参照するすべてのSQL文のスコープ内にあることが必要です。たとえば、あるサブプログラムでカーソルをオープンし、それを別のサブプログラムでフェッチする場合は、DB-NAMEをグローバルに宣言するか、それぞれのサブプログラムに渡す必要があります。

カーソルからのオープン、クローズまたはフェッチには、AT句は使用しません。SQL文は、DECLARE CURSOR文のAT句で名前を付けられたデータベースか、カーソルの宣言でAT句が使用されていない場合はデフォルトのデータベースにおいて実行されます。

AT :ホスト変数句を使用して、カーソルに対応付けられた接続を変更できます。ただし、カーソルがオープンされているときは対応付けを変更できません。次の例を考えてみます。

EXEC SQL AT :DB-NAME DECLARE emp_cursor CURSOR FOR ...
MOVE "oracle1" TO DB-NAME.
EXEC SQL OPEN emp_cursor END-EXEC.
EXEC SQL FETCH emp_cursor INTO ...
MOVE "oracle2" TO DB-NAME.
* -- illegal, cursor still open
EXEC SQL OPEN emp_cursor END-EXEC.
EXEC SQL FETCH emp_cursor INTO ...

この例は、2番目のOPEN文を実行するときにemp_cursorがまだオープンされているため、無効となります。異なる接続に対して別々のカーソルが維持されることはありません。emp_cursorは1つのみ存在できます。別の接続のために再オープンするには、その前にクローズする必要があります。最後の例をデバッグするには、次のように、単にカーソルをクローズしてから再オープンします。

* -- close cursor first
EXEC SQL CLOSE emp_cursor END-EXEC.
MOVE "oracle2" TO DB-NAME.
EXEC SQL OPEN EMP-CUROR END-EXEC.
EXEC SQL FETCH emp_cursor INTO ...

動的SQL。動的SQL文は、文中ではAT句が使用されないカーソル制御文に類似しています。動的SQL方法1では、非デフォルトの接続で文を実行する場合は、AT句を使用する必要があります。次に、例を示します。

EXEC SQL AT :DB-NAME EXECUTE IMMEDIATE :SQL-STMT END-EXEC.

方法2、3および4で非デフォルトの接続で文を実行する場合は、DECLARE STATEMENT文でのみAT句を使用します。PREPARE、DESCRIBE、OPEN、FETCHおよびCLOSEなど、その他の動的SQL文はAT句を使用しません。次の例に方法2を示します。

EXEC SQL AT :DB-NAME DECLARE SQL-STMT STATEMENT END-EXEC.
EXEC SQL PREPARE SQL-STMT FROM :SQL-STRING END-EXEC.
EXEC SQL EXECUTE SQL-STMT END-EXEC.

次の例は方法3を示します。

EXEC SQL AT :DB-NAME DECLARE SQL-STMT STATEMENT END-EXEC.
EXEC SQL PREPARE SQL-STMT FROM :SQL-STRING END-EXEC.
EXEC SQL DECLARE emp_cursor CURSOR FOR SQL-STMT END-EXEC.
EXEC SQL OPEN emp_cursor ...
EXEC SQL FETCH emp_cursor INTO ...
EXEC SQL CLOSE emp_cursor END-EXEC.

複数の接続を同時にオープンする場合(アクティブな接続の識別にAT句が必要)でなければ、リモート・データベースに接続する際にAT句を使用する必要はありません。リモート・データベースにデフォルト接続を行うには、次の構文を使用します。

EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWORD USING :DB-STRING
END-EXEC.

自動ログイン

次のようなユーザーIDを使用すると、Oracleに自動的にログインできます。

<prefix><username>

prefixにはOracle初期化パラメータOS_AUTHENT_PREFIXの値(デフォルト値はOPS$)を指定し、usernameには使用しているオペレーティング・システムのユーザー名またはタスク名を指定します。たとえば、接頭辞がOPS$でユーザー名がTBARNESの場合、OPS$TBARNESがOracleの有効なユーザーIDであれば、ユーザーOPS$TBARNESとしてOracleにログインします。

自動ログイン機能を利用するには、次のようにPro*COBOLにスラッシュ(/)文字を渡すことが必要です。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 ORACLEID   PIC X.
...
EXEC SQL END DECLARE SECTION END-EXEC.
...
MOVE '/' TO ORACLEID.
EXEC SQL CONNECT :ORACLEID END-EXEC.

これによって、自動的にOPS$usernameというユーザーとして接続します。たとえば、オペレーティング・システムのユーザー名がRHILLで、OPS$RHILLがOracleの有効なユーザー名の場合、スラッシュ(/)を使用して接続すると、ユーザーOPS$RHILLとして自動的にログインします。

Pro*COBOLに文字列を渡すこともできます。ただし、その文字列の後続にブランクを入れないでください。たとえば、次のCONNECT文は失敗します。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 ORACLEID   PIC X(5).
...
EXEC SQL END DECLARE SECTION END-EXEC.
...
MOVE '/    ' TO ORACLEID.
EXEC SQL CONNECT :ORACLEID END-EXEC.

AUTO_CONNECTプリコンパイラ・オプション

Pro*COBOLでは、プログラムはCONNECT文を使用せずにデフォルトのデータベースにログインできます。このためには、コマンドラインにプリコンパイラ・オプションAUTO_CONNECTを指定することが必要です。

OS_AUTHENT_PREFIXのデフォルト値がOPS$、ユーザー名がTBARNESであり、OPS$TBARNESがOracleの有効なユーザーIDであるとします。AUTO_CONNECT=YESの場合、Pro*COBOLが実行SQL文を検出すると、ユーザー・プログラムはOPS$TBARNESのユーザーIDで自動的にOracleにログインします。

AUTO_CONNECT=NO (デフォルト)の場合は、OracleにログインするにはCONNECT文を使用する必要があります。

実行時のパスワード変更

Pro*COBOLでは、オプションのALTER AUTHORIZATION句によって、実行時のユーザー/パスワードをクライアント・アプリケーションで簡単に変更できます。

ALTER AUTHORIZATION句の構文は、次のとおりです。

EXEC SQL CONNECT .. ALTER AUTHORIZATION :NEWPSWD END-EXEC.

この句を使用すると、アカウントのパスワードが、NEWPSWDで指定された値に変更されます。パスワードを変更すると、USER/NEWPSWDとして接続が試行されます。次の結果が予想されます。

- アプリケーションが問題なく接続されます。

- アプリケーションが接続に失敗します。次のどちらかの原因が考えられます。

- なんらかの理由でパスワードを認識できませんでした。パスワードは元のままです。

- アカウントがロックされています。パスワードは変更できません。

ALTER AUTHORIZATIONを使用しない接続

この項では、別の種類のCONNECT文で考えられる結果を説明します。

標準のCONNECT

次の文がアプリケーションから発行されるとします。

EXEC SQL CONNECT ...   /* No ALTER AUTHORIZATION clause */

通常の接続が実行されます。予想される結果は次のとおりです。

- アプリケーションが問題なく接続されます。

- アプリケーションは接続できるが、パスワードに関する警告を受ける。この警告は、パスワードの期限は切れているが、まだログインできる猶予期間であることを示しています。この時点で、ユーザーは、アカウントがロックされる前にパスワードを変更するように求められます。

- アプリケーションが接続に失敗します。次の原因が考えられます。

- パスワードが間違っています。

- アカウントが期限切れになっているか、またはロック状態です。

SYSDBA権限またはSYSOPER権限

Oracle8.1より前のリリースでは、SYSOPERまたはSYSDBAシステム権限を得るために次の句を使用する必要はありませんでしたが、今回のリリースでは使用する必要があります。

SYSDBAまたはSYSOPERのシステム権限でログインするには、CONNECT文で他のすべての句の後に次のオプション文字列を追加します。

IN { SYSDBA | SYSOPER } MODE

次に例を示します。

EXEC SQL CONNECT ... IN SYSDBA MODE END-EXEC.

このオプションには次の制限があります。

- AUTO_CONNECT=YESのプリコンパイラ・オプション設定を使用しているときは、このオプションはサポートされません。

- CONNECT文でALTER AUTHORIZATIONキーワードを使用しているときは、このオプションは使用できません。

リンクの使用方法

データベース・リンクは、Oracle分散データベース・オプションを介してサポートされます。たとえば、分散問合せでは、単一のSELECT文で1つ以上の非デフォルト・データベース上のデータにアクセスできます。

分散問合せ機能はデータベース・リンクに依存しており、リンクにより接続事態ではなく、CONNECT文に名前が割り当てられます。実行時には、指定したデータベースサーバーにより埋込みSELECT文が実行され、非デフォルトのデータベースに暗黙的に接続されて、必要なデータが取得されます。

詳細は、『Oracle Database Net Services管理者ガイド』を参照してください。

基本用語

トランザクションの説明に入る前に、この項で定義されている用語に慣れる必要があります。

データベースが管理するジョブおよびタスクをセッションと呼びます。ユーザー・セッションは、アプリケーション・プログラムまたはOracle FormsなどのOracleのツール製品を実行してデータベースに接続すると開始されます。Oracleでは、複数のユーザー・セッションを同時に動作させ、コンピュータ・リソースを共有できます。このためには、Oracleが同時実行性、つまり多数のユーザーによる同一データへのアクセスを制御する必要があります。同時実行性を適切に制御しないと、データの整合性が損なわれることがあります。つまり、データまたは構造への変更が誤った順序で行われるおそれがあります。

Oracleでは、ロックを使用してデータへの同時アクセスを制御します。ロックにより、データの表や行などのデータベース・リソースのユーザーに一時的な所有権が与えられます。つまり、このユーザーがデータの変更を終了するまで他のユーザーは同じデータを変更できません。表のデータおよび構造はデフォルトのロック機構によって保護されるため、リソースを明示的にロックする必要はありません。ただし、デフォルトのロックをオーバーライドするときは、表または行単位でデータ・ロックを要求できます。行の共有および排他など、ロックのモードを選択できます。

複数のユーザーが同じデータベース・オブジェクトへのアクセスを試みると、デッドロックが発生する可能性があります。たとえば、同じ表を更新するユーザーが2人いる場合、それぞれ相手が現在ロックしている行の更新を試みると待機状態になります。それぞれのユーザーが、相手が使用中のリソースを待つことになるため、サーバーによりデッドロックが解除されるまで、どちらも処理を続行できません。サーバーからは、最小量の作業を完了した関連トランザクションに対してエラー信号が送られ、「リソース待機の間にデッドロックが検出されました」というエラー・コードがSQLCAのSQLCODEに戻されます。

1つの表に対しユーザーが問い合せ、同時に別のユーザーが更新している場合、データベースは問合せについて、その表のデータの読込み一貫性ビューを生成します。つまり、問合せが開始されて処理がそのまま続行しているときは、問合せによって読み込まれるデータは変更されません。更新アクティビティが続行している間、データベースは表のデータのスナップショットをとり、変更内容をロールバック・セグメントに記録します。データベースは、このロールバック・セグメント内の情報に基づいて読込み一貫性のある問合せ結果を作成し、必要に応じて変更を取り消します。

トランザクションによるデータベースの保護

データベースはトランザクション指向です。つまり、トランザクションを使用してデータの整合性を保証します。トランザクションとは、あるタスクを完了するために定義する1つ以上の論理的に関連付けられたSQL文です。データベースでは、一連のSQL文を一単位として扱い、それらの文によって実行されたすべての変更が、同時にコミット(確定)されるか、ロールバック(取消し)されます。トランザクションの途中でアプリケーション・プログラムに障害が発生すると、データベースは自動的にトランザクション前の状態にリストアされます。

次項では、トランザクションの設計および制御方法について説明します。具体的には、次の方法について説明します。

- トランザクションの開始および終了

- COMMIT文を使用したトランザクションの確定

- ROLLBACK TO文とともにSAVEPOINT文を使用したトランザクションの部分的な取消し

- ROLLBACK文を使用したトランザクション全体の取消し

- RELEASEオプションを指定したリソースの解放およびデータベースのログオフ

- SET TRANSACTION文を使用した読取り専用トランザクションの設定

- FOR UPDATE句またはLOCK TABLE文を使用したデフォルトのロックのオーバーライド

この章で説明するSQL文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

トランザクションの開始および終了

プログラムの最初の実行SQL文(CONNECT以外)によりトランザクションを開始します。1つのトランザクションが終了すると、次の実行SQL文により別のトランザクションが自動的に開始します。このように、すべての実行文はトランザクションの一部です。宣言SQL文はロールバックされません。また、コミットする必要もないため、トランザクションの一部とみなされません。

トランザクションは、次のいずれかの方法で終了します。

- COMMITまたはROLLBACK文を記述します。RELEASEオプションは、付けても付けなくてもかまいません。これにより、データベースへの変更を明示的に確定または取り消します。

- 実行の前と後の両方で自動コミットを発行するデータ定義文(ALTER、CREATEまたはGRANTなど)を記述します。これはデータベースへの変更を暗黙的に確定します。

システム障害が発生した場合、ソフトウェア上の問題、ハードウェア上の問題または強制割込みなどが原因で予期しないセッション停止が発生した場合にも、トランザクションは終了します。

トランザクションの途中でプログラムに障害が発生すると、Oracleは発生したエラーを検出し、そのトランザクションをロールバックします。オペレーティング・システムに障害が発生した場合は、データベースは元の状態(トランザクション処理前の状態)にリストアされます。

COMMIT文の使用

COMMIT文を使用すると、データベースへの変更を確定できます。変更がコミットされるまで、他のユーザーは変更されたデータにアクセスできず、表示されるのはトランザクション開始前の状態のデータです。COMMIT文は、ホスト変数の値にも、プログラムの制御フローにも影響しません。具体的には、COMMIT文により次の処理が実行されます。

- カレント・トランザクションのデータベースに対する変更をすべて確定します。

- これらの変更を他のユーザーが参照できるようにします。

- すべてのセーブポイントを消去します(SAVEPOINT文の使用に関する次の項を参照)。

- 解析ロック以外の行および表のロックをすべて解除します。

- FOR UPDATE句を使用して宣言されているカーソルをクローズするか、CURRENT OF句を使用してコード内の別の場所で参照されているカーソルをクローズします。MODE=ANSI | ANSI14またはCLOSE_ON_COMMIT=YESを使用した場合は、明示カーソルがすべてクローズされます。

- トランザクションを終了します。

MODE={ANSI13 | ORACLE}のときは、CURRENT OF句で参照されていない明示カーソルはコミット後もオープン状態となります。これによってパフォーマンスが向上します。「コミット時のフェッチ」の例を参照してください。

これらの処理は通常の処理の一部分であるため、COMMIT文はプログラムのメイン・パスにインラインで設定する必要があります。プログラムを終了する前に、保留中の変更を明示的にコミットしてください。コミットしない場合、保留中の変更はロールバックされます。次の例では、トランザクションをコミットして切断します。

EXEC SQL COMMIT WORK RELEASE END-EXEC.

オプションのキーワードWORKには、ANSI互換性があります。RELEASEオプションを指定すると、プログラムが使用しているリソース(ロックおよびカーソル)がすべて解放され、データベースからログオフされます。

データ定義文は実行の前と後の両方で自動コミットを発行するため、データ定義文の後にCOMMIT文を記述する必要はありません。したがってデータ定義文が正常終了しても異常終了しても、その前のトランザクションがコミットされます。

DECLARE CURSOR文でのWITH HOLD句の使用

CURSORの後にWITH HOLD句を付けて宣言されているカーソルは、COMMIT後もオープン状態となります。この句の使用方法は、次の例のとおりです。

EXEC SQL
DECLARE C1 CURSOR WITH HOLD
FOR SELECT ENAME FROM EMP
WHERE EMPNO BETWEEN 7600 AND 7700
END-EXEC.

UPDATEの場合は、カーソルを宣言しないでください。DB2では、デフォルト(コミット時に全カーソルをクローズする)を変更するためにWITH HOLD句が使用されます。Pro*COBOLでは、DB2からOracleへのアプリケーションの移行を簡単に行えるようにするために、この句が用意されています。MODE=ANSIと指定されているとき、OracleではDB2のデフォルトが使用されますが、ホスト変数はすべて宣言部で宣言する必要があります。宣言部を省略するには、次の項で説明するプリコンパイラ・オプションCLOSE_ON_COMMITを使用します。「DECLARE CURSOR (埋込みSQLディレクティブ)」を参照してください。

CLOSE_ON_COMMITプリコンパイラ・オプション

プリコンパイラ・オプションCLOSE_ON_COMMITを使用すると、MODE=ANSIのデフォルト動作をオーバーライドできます(コマンドラインにMODE=ANSIを指定した場合、WITH HOLD句で宣言されていないカーソルはコミット時にクローズされます)。

CLOSE_ON_COMMIT = {YES | NO}

デフォルトはNOです。このオプションは、コマンドラインまたは構成ファイルで入力する必要があります。

注意:
このオプションは注意して使用してください。カーソルのオープン/クローズを何度も行うと、各OPEN文で再解析を行う必要があるためアプリケーションの処理速度が低下する可能性があります。「CLOSE_ON_COMMIT」を参照してください。

ROLLBACK文の使用

ROLLBACK文を使用すると、保留状態のデータベースへの変更を取り消せます。たとえば表から行を誤って削除したときなどは、ROLLBACK文を使用して元のデータをリストアできます。ROLLBACK文は、ホスト変数の値やプログラム内の制御の流れには影響を与えません。ROLLBACK文は、次の操作を行います。

- カレント・トランザクションで実行されたデータベースの変更を取り消します。

- すべてのセーブポイントを消去します。

- トランザクションを終了します。

- 解析ロック以外の行および表のロックをすべて解除します。

- FOR UPDATE句を使用して宣言されているカーソルをクローズするか、CURRENT OF句を使用してコード内の別の場所で参照されているカーソルをクローズします。MODE={ANSI | ANSI14}が指定されている場合は、すべての明示カーソルがクローズされます。

MODE={ANSI13 | ORACLE}のときは、CURRENT OF句で参照されていない明示カーソルはロールバック後もオープン状態となります。

ROLLBACK文は例外処理の一部になっているため、プログラムのメイン・パスではなくエラー処理ルーチン内に指定する必要があります。次の例では、トランザクションをロールバックして切断します。

EXEC SQL ROLLBACK WORK RELEASE END-EXEC.

オプションのキーワードWORKには、ANSI互換性があります。RELEASEオプションを指定すると、プログラムが使用しているリソースがすべて解放され、データベースからログオフされます。

WHENEVER SQLERROR GOTO文からROLLBACK文が記述されているエラー処理ルーチンに分岐したときに、ロールバックでエラーが発生すると、プログラムが無限にループする可能性があります。このような事態を避けるには、ROLLBACK文の前にWHENEVER SQLERROR CONTINUEを記述します。

次に例を示します。

EXEC SQL
WHENEVER SQLERROR GOTO SQL-ERROR
END-EXEC.
...
DISPLAY 'Employee number? '.
ACCEPT EMP-NUMBER.
DISPLAY 'Employee name? '.
ACCEPT EMP-NAME.
EXEC SQL INSERT INTO EMP (EMPNO, ENAME)
VALUES (:EMP-NUMBER, :EMP-NAME)
END-EXEC.
...
SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
DISPLAY 'PROCESSING ERROR.'.
DISPLAY 'ERROR CODE : ', SQLCODE.
DISPLAY 'MESSAGE :', SQLERRMC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

プログラムが異常終了すると、Oracleはトランザクションをロールバックします。

文レベルのロールバック

Oracleは、SQL文を実行する前に、暗黙的なセーブポイント(ユーザーは操作できません)を設定します。SQL文でエラーが発生すると、Oracleは自動的にその文をロールバックし、該当するエラー・コードをSQLCA内のSQLCODEに戻します。たとえば、INSERT文が一意の索引内に同じ値を挿入しようとしたためエラーが発生すると、この文はロールバックの対象になります。

失敗したSQL文によって開始された作業のみが失われます。現在のトランザクションでその文の前に行われた作業は保持されます。このため、データ定義文が失敗した場合、それに先行する自動コミットは取り消されません。

注意:
SQL文は実行前に必ず解析され、構文規則に従っているか、有効なデータベース・オブジェクトを参照しているかが検証されます。SQL文の実行中にエラーが検出されると、ロールバックが発生しますが、解析中にエラーが検出されても、ロールバックは発生しません。

Oracleは、デッドロックを解除するために単一のSQL文をロールバックすることもあります。デッドロックの原因となっているトランザクションの1つにエラーを通知して、そのトランザクションの現行の文をロールバックします。

SAVEPOINT文の使用

SAVEPOINT埋込みSQL文を使用すると、トランザクションの処理の現時点にマークを設定し名前を指定できます。マークを設定したそれぞれの点をセーブポイントと呼びます。たとえば、次の文によりstart_deleteというセーブポイントを設定します。

EXEC SQL SAVEPOINT start_delete END-EXEC.

セーブポイントによってロング・トランザクションを分割できるため、より複雑なプロシージャを制御できるようになります。たとえば、単一のトランザクションが複数のファンクションを実行しているときに、それぞれのファンクションの前にセーブポイントを設定できます。この結果、あるファンクションでエラーが発生しても、簡単にデータを元の状態にリストアし、リカバリして、そのファンクションを再実行できます。

トランザクションの一部を取り消すには、ROLLBACK文およびそのTO SAVEPOINT句によってセーブポイントを指定します。TO SAVEPOINT句を使用すると、カレント・トランザクションの途中の文までロールバックできます。そのため、変更をすべて取り消す必要はありません。ROLLBACK TO SAVEPOINT文は、次の操作を行います。

- 指定したセーブポイントがマークされた以降のデータベースへの変更を取り消します。

- 指定したセーブポイント以降のセーブポイントをすべて消去します。

- 指定したセーブポイントがマークされた以降に取得された行および表のロックをすべて解除します。

次の例は、MAIL_LIST表にアクセスして、新しいリストの挿入、古いリストの更新、(少数の)使用されていないリストの削除を行います。削除後、SQLCAのSQLERRD(3)をチェックして、削除された行数を調べます。削除された行数が必要以上に大きいときは、セーブポイントのstart_deleteまでロールバックしてこの削除を取り消します。

* -- For each new customer
DISPLAY 'New customer number? '.
ACCEPT CUST-NUMBER.
IF CUST-NUMBER = 0
GO TO REV-STATUS
END-IF.
DISPLAY 'New customer name? '.
ACCEPT  CUST-NAME.
EXEC SQL INSERT INTO MAIL-LIST (CUSTNO, CNAME, STAT)
VALUES (:CUST-NUMBER, :CUST-NAME, 'ACTIVE').
END-EXEC.
...
* -- For each revised status
REV-STATUS.
DISPLAY 'Customer number to revise status? '.
ACCEPT CUST-NUMBER.
IF CUST-NUMBER = 0
GO TO SAVE-POINT
END-IF.
DISPLAY 'New status? '.
ACCEPT NEW-STATUS.
EXEC SQL UPDATE MAIL-LIST
SET STAT = :NEW-STATUS WHERE CUSTNO = :CUST-NUMBER
END-EXEC.
...
* -- mark savepoint
SAVE-POINT.
EXEC SQL SAVEPOINT START-DELETE END-EXEC.
EXEC SQL DELETE FROM MAIL-LIST WHERE STAT = 'INACTIVE'
END-EXEC.
IF SQLERRD(3) < 25
* -- check number of rows deleted
DISPLAY 'Number of rows deleted is ', SQLERRD(3)
ELSE
DISPLAY 'Undoing deletion of ', SQLERRD(3), ' rows'
EXEC SQL
WHENEVER SQLERROR GOTO SQL-ERROR
END-EXEC
EXEC SQL
ROLLBACK TO SAVEPOINT START-DELETE
END-EXEC
END-IF.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL COMMIT WORK RELEASE END-EXEC.
STOP RUN.
* -- exit program.
...
SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
DISPLAY 'Processing error'.
* -- exit program with an error.
STOP RUN.

ROLLBACK TO SAVEPOINT文では、RELEASEオプションを指定できないことに注意してください。

あるセーブポイントまでロールバックすると、そのセーブポイント以降のすべてのセーブポイントが消去されます。ただし、ロールバックしたセーブポイントはそのまま残ります。たとえば、5つのセーブポイントを設定しているときに3番目のセーブポイントまでロールバックすると、4番目と5番目のセーブポイントのみ消去されます。COMMIT文またはROLLBACK文を実行すると、すべてのセーブポイントが消去されます。

RELEASEオプションの使用方法

プログラムが異常終了すると、Oracleは自動的に変更をロールバックします。異常終了は、プログラムが作業を明示的にコミットもロールバックもしないまま、RELEASE埋込みSQL文を使用して接続を切断した場合に発生します。

これに対し、プログラムが所定作業を実行し、オープンしているカーソルをクローズし、明示的に作業をコミットまたはロールバックし、接続を切断して、制御をユーザーに戻した場合には、プログラムは正常に終了します。実行される最後のSQL文が次のいずれかのときにプログラムは正常終了します。

EXEC SQL COMMIT WORK RELEASE END-EXEC.

または

EXEC SQL ROLLBACK WORK RELEASE END-EXEC.

トークンWORKはオプションです。最後のSQL文が上のどちらでもない場合は、そのユーザー・セッションで取得したロックおよびカーソルはプログラムの終了後も解放されず、ユーザー・セッションがアクティブでなくなったことをOracleが認識するまで保持されます。この結果、マルチユーザー環境では、他のユーザーはロックされたリソースへのアクセスを必要以上に長く待たされる場合があります。

SET TRANSACTION文の使用

SET TRANSACTION文を使用すると、読取り専用または読取り/書込み両用のトランザクションを開始したり、カレント・トランザクションを特定のロールバック・セグメントに割り当てることができます。読取り専用トランザクションは、COMMIT文またはROLLBACK文、データ定義文によって終了します。

読取り専用トランザクションでは反復可能読取りが行えるため、他のユーザーが更新中の1つ以上の表に対して、複数の問合せを実行する場合に便利です。読取り専用トランザクション中、複数の表と複数の問合せで構成された読取り一貫性ビューが作成され、すべての問合せがデータベースの同じスナップショットを参照します。他のユーザーは、通常の方法でデータの問合せや更新ができます。次にSET TRANSACTION文の例を示します。

EXEC SQL SET TRANSACTION READ ONLY END-EXEC.

SET TRANSACTION文は、読取り専用トランザクションの最初のSQL文である必要があり、1つのトランザクションで1回しか使用できません。READ ONLYパラメータは必須です。これを使用しても、他のトランザクションには影響がありません。読取り専用トランザクションで使用できるのは、SELECT文(FOR UPDATEなし)、LOCK TABLE文、SET ROLE文、ALTER SESSION文、ALTER SYSTEM文、COMMIT文およびROLLBACK文のみです。

次に示すのは、あるストア・マネージャが、読取り専用トランザクションを使用してその日の販売活動、過去1週間の販売活動および過去1か月間の販売活動を調べて、サマリー・レポートを作成する例です。このレポートは、このトランザクションの実行中にデータベースを更新する他のユーザーによる影響を受けません。

EXEC SQL SET TRANSACTION READ ONLY END-EXEC.
EXEC SQL SELECT SUM(SALEAMT) INTO :DAILY FROM SALES
WHERE SALEDATE = SYSDATE END-EXEC.
EXEC SQL SELECT SUM(SALEAMT) INTO :WEEKLY FROM SALES
WHERE SALEDATE > SYSDATE - 7 END-EXEC.
EXEC SQL SELECT SUM(SALEAMT) INTO :MONTHLY FROM SALES
WHERE SALEDATE > SYSDATE - 30 END-EXEC.
EXEC SQL COMMIT WORK END-EXEC.
* --  simply ends the transaction since there are no changes
* --  to make permanent
* --  format and print report

デフォルトのロックのオーバーライド

デフォルトでは、Oracleによって多数のデータ構造が暗黙的に(自動的に)ロックされます。ただし、デフォルトのロックをオーバーライドして、別のロックを有効にする場合は、行または表を特定して、そこにデータ・ロックを要求できます。明示的なロックを行うと、トランザクション実行中に表へのアクセスを共有または拒絶でき、また、マルチ表および多重問合せの読込み一貫性を確保できます。

SELECT FOR UPDATE OF文を使用すると、表の特定の行を明示的にロックして、更新または削除が実行されるまでその行が変更されないようにできます。ただし、Oracleでは、更新時または削除時には自動的に行レベルのロックが行われます。したがって、UPDATEまたはDELETEの前に行をロックするときにのみFOR UPDATE OF句を使用してください。

LOCK TABLE文を使用すると、表全体を明示的にロックできます。

FOR UPDATE OF句の使用

カーソルをDECLAREするときは、カーソルで定義されるすべての行に排他ロックを取得する効果のあるFOR UPDATE句をオプションで指定できます。これは、たとえば更新をある表内の既存の行に対して行う場合に、更新中に他のユーザーによって行が変更されるのを防止するのに便利です。

CURRENT OF句でカーソルを参照した場合、プリコンパイラは自動的にFOR UPDATE句をカーソル定義に追加するため、OF句は省略可能です。たとえば、次のような文があるとします。

EXEC SQL DECLARE emp_cursor CURSOR FOR
SELECT ENAME, JOB, SAL FROM EMP WHERE DEPTNO = 20
FOR UPDATE OF SAL
END-EXEC.

OFを削除して、次のように簡潔に記述します。

EXEC SQL DECLARE emp_cursor CURSOR FOR
SELECT ENAME, JOB, SAL FROM EMP WHERE DEPTNO = 20
FOR UPDATE
END-EXEC.

「CURRENT OF句の使用」の例を参照してください。

制限

FOR UPDATE句を複数の表に使用することはできません。しかし、ロックしたい表の列を指定するには、FOR UPDATE OF句を使用する必要があります。FOR UPDATE文による行のロックはCOMMITで取り消され、カーソルがクローズされた理由が説明されます。コミット後にFOR UPDATEカーソルからフェッチしようとすると、「フェッチ順序が無効です。」というエラーが発生します。

コミット時のフェッチ

コミットとフェッチを併用する場合は、CURRENT OF句を使用しないでください。そのかわりに各行のROWIDを選択し、更新または削除するときにその値を使用してカレント行を識別してください。次の例を考えてみます。

EXEC SQL DECLARE emp_cursor CURSOR FOR
SELECT ENAME, SAL, ROWID FROM EMP WHERE JOB = 'CLERK'
END-EXEC.
...
EXEC SQL OPEN emp_cursor END-EXEC.
EXEC SQL WHENEVER NOT FOUND GOTO ...
PERFORM
EXEC SQL
FETCH emp_cursor INTO :EMP_NAME, :SALARY, :ROW-ID
END-EXEC
...
EXEC SQL UPDATE EMP SET SAL = :NEW-SALARY
WHERE ROWID = :ROW-ID
END-EXEC
EXEC SQL COMMIT END-EXEC
END-PERFORM.

ただし、フェッチされた行はロックされないので注意してください。つまり、ある行を読み込んでも、その行を更新または削除する前に別のユーザーがその行を変更してしまうと、結果に矛盾が生じる可能性があります。

LOCK TABLE文の使用方法

LOCK TABLE文を使用すると、指定したロック・モードで1つ以上の表をロックできます。たとえば、次の文は行共有モードでEMP表をロックします。行共有ロックでは、表への同時アクセスが可能になります。他のユーザーがその表全体をロックして排他的に使用することはできなくなります。

EXEC SQL
LOCK TABLE EMP IN ROW SHARE MODE NOWAIT
END-EXEC.

ロック・モードによって、その表に設定できる他のロックが決定されます。たとえば、同時に多数のユーザーが1つの表に対して行共有ロックを取得できる一方で、排他ロックを取得できるのは一度に1ユーザーのみです。あるユーザーが表を排他ロックしている間は、他のユーザーはその表内の行の挿入、更新または削除を行えません。ロック・モードの詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

オプションのキーワードNOWAITを指定すると、他のユーザーが表をロックしている場合は、その表の解放を待機しないようにOracleに対して指示できます。制御はただちにプログラムに戻されるため、プログラムではロックの取得を再度試みるまでの間に別の作業ができます。(SQLCA内のSQLCODEをチェックすると、表ロックが失敗したか確認できます。)NOWAITを省略すると、表が利用可能になるまで、Oracleは待機します。待機の時間制限は設定されていません。

表がロックされていても、他のユーザーは表に対して問い合せできますが、問合せを実行しても表のロックを取得できません。したがって、問合せが他の問合せや更新を妨げることはなく、更新が問合せを妨げることもありません。2つの異なるトランザクションで同じ行の更新が試みられる場合にのみ、一方のトランザクションが他方のトランザクションの完了まで待機の状態になります。表のロックは、トランザクションがCOMMITまたはROLLBACKを発行すると解除されます。

分散トランザクションの処理

分散データベースとは、異なるノード上の複数の物理データベースで構成される単一の論理データベースです。分散型の文とは、データベース・リンクによってリモート・ノードにアクセスする任意のSQL文です。分散トランザクションには、分散データベースの複数のノードでデータを更新するための分散型の文が、1つ以上設定されています。その更新が1つのノードのみに影響するときは、そのトランザクションは分散型ではありません。

コミットを発行すると、分散トランザクションによる影響を受ける各データベースの変更が確定されます。かわりにROLLBACKを発行すると、すべての変更が取り消されます。ただし、コミットまたはロールバック中にネットワークやマシンで障害が発生すると、分散トランザクションの状態は不明またはインダウトになることがあります。そのような場合、FORCE TRANSACTIONシステム権限があれば、FORCE句を使用して、ローカル・データベースでトランザクションを手動でコミットまたはロールバックできます。このトランザクションは、データ・ディクショナリ・ビューDBA_2PC_PENDINGにあるトランザクションIDを引用符で囲んだリテラルで指定する必要があります。次に、いくつかの例を示します。

EXEC SQL COMMIT FORCE '22.31.83' END-EXEC.
...
EXEC SQL ROLLBACK FORCE '25.33.86'END-EXEC.

FORCEは指定されたトランザクションのみコミットまたはロールバックするため、カレント・トランザクションには影響しません。インダウトのトランザクションは、手動ではセーブポイントにロールバックできないことに注意してください。

COMMIT文中のCOMMENT句を使用すると、分散トランザクションと対応付けるためのコメントを指定できます。トランザクションがインダウトの場合、サーバーはデータ・ディクショナリ・ビューDBA_2PC_PENDINGのCOMMENTで指定されたテキストをトランザクションIDとともに格納します。テキストは、引用符の付いた50文字 以下のリテラルであることが必要です。次に、例を示します。

EXEC SQL
COMMIT COMMENT 'In-doubt trans; notify Order Entry'
END-EXEC.

分散トランザクションの詳細は、『Oracle Database概要』を参照してください。

トランザクション処理のガイドライン

次のガイドラインに従うと、いくつかの問題を回避できます。

アプリケーションの設計

アプリケーションを設計するときは、論理的に関連する処理を1つのトランザクション内にグループ化してください。正しく設計されたトランザクションには、与えられた作業を完了するために必要なステップが、すべて過不足なく含まれています。

表を参照するデータは一貫している必要があります。したがって、トランザクション内のSQL文は一貫した方法に従ってデータを変更する必要があります。たとえば2種類の銀行預金口座間の資金の送金取引の場合は、一方の口座に対する借方記帳および他方の口座に対する貸方記帳の処理がトランザクションに含まれている必要があります。どちらの処理も、正常終了または失敗が同時であることが必要です。一方の口座への新規預金など、この取引とは無関係な更新取引をトランザクションに取り込まないでください。

ロックの取得

アプリケーション・プログラム内にSQLのロック文がある場合、ロックを要求するユーザーはそのロックを獲得する権限が必要です。データベース管理者(DBA)は、どの表でもロックできます。DBA以外のユーザーは、自分が所有する表または権限を持つ表(ALTER、SELECT、INSERT、UPDATEおよびDELETEなど)のみロックできます。

PL/SQLの使用方法

トランザクションにPL/SQLブロックが記述されている場合、PL/SQLブロック内で指定されたコミットおよびロールバック操作はトランザクション全体を対象に行われます。次の例のROLLBACK操作では、UPDATEおよびINSERTによる変更を取り消します。

EXEC SQL INSERT INTO EMP ...
EXEC SQL EXECUTE
BEGIN        UPDATE emp
...
...
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
ROLLBACK;
END;
END-EXEC.
...

X/Openアプリケーション

X/OpenアプリケーションでのXAインタフェースの使用方法の詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

4 データ型とホスト変数

この章では、Pro*COBOLプログラムを作成する際に必要となる基本的な情報を、次の内容で説明します。

- Oracle Databaseのデータ型

- 日時および時間隔のデータ型記述子

- ホスト変数

- 標識変数

- VARCHAR変数

- 文字データの処理

- ユニバーサルROWID

- グローバリゼーション・サポート

- Pro*COBOLのUnicodeサポート

- データ型変換

- DATE文字列フォーマットの明示的な制御

- データ型の同値化

- プラットフォームのエンディアン形式のサポート

- サンプル・プログラム4: データ型の同値化

Oracle Databaseのデータ型

Oracle Databaseは、内部データ型および外部データ型の2種類のデータ型を認識します。内部データ型はOracle Databaseがデータベース列にどのようにデータを格納するかを指定します。

Oracle内部(「組込み」とも呼ばれる)データ型の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

Oracle Databaseは、データベース疑似列を表す場合にも内部データ型を使用します。外部データ型は、データがホスト変数にどのように格納されるかを指定します。

内部データ型

表4-1は、各Oracle組込みデータ型の説明をまとめたものです。

表4-1 Oracle組込みデータ型の概要

データ型

説明

列の長さおよびデフォルト

CHAR

固定長文字データ。長さsizeは文字数またはバイト数(各国語キャラクタ・セットによる)。

表内の行ごとに固定(後続の空白を含む)。列サイズは、固定幅の各国語キャラクタ・セットの場合は文字数、または1文字を格納するために必要なバイト数で、各行の上限は2000バイトです。デフォルトのサイズは、各国語キャラクタ・セットに応じて、各行につき1文字または1バイトです。サイズを設定する際は、キャラクタ・セット(1バイトまたはマルチバイト)を考慮に入れてください。

VARCHAR2

固定長文字データ。長さサイズは文字数またはバイト数(各国語キャラクタ・セットによる)。最大サイズを指定する必要があります。

行ごとに可変。列サイズは、固定幅の各国語キャラクタ・セットの場合は文字数、可変幅の各国語キャラクタ・セットの場合はバイト数です。最大サイズは、1文字を格納するために必要なバイト数によって決定されます。各行の上限は4000バイトです。デフォルトのサイズは、各国語キャラクタ・セットに応じて1文字または1バイトです。

NCHAR(size)

固定長文字データ。長さサイズは文字数またはバイト数(各国語キャラクタ・セットによる)。

表内の行ごとに固定(後続の空白を含む)。列サイズは、固定幅の各国語キャラクタ・セットの場合は文字数、可変幅の各国語キャラクタ・セットの場合はバイト数です。最大サイズは、1文字を格納するために必要なバイト数によって決定されます。各行の上限は2000バイトです。デフォルトは、キャラクタ・セットに応じて1文字または1バイトです。

NVARCHAR2(size)

可変長データ。長さサイズは文字数またはバイト数(各国語キャラクタ・セットによる)。最大サイズを指定する必要があります。

行ごとに可変。列サイズは、固定幅の各国語キャラクタ・セットの場合は文字数です。最大サイズは、1文字を格納するために必要なバイト数によって決定されます。各行の上限は4000バイトです。デフォルトは、キャラクタ・セットに応じて1文字または1バイトです。

CLOB

シングルバイト文字データ

最大2^32 - 1 バイトまたは4GB。

NCLOB

シングルバイトまたは固定長マルチバイト各国語キャラクタ・セット(NCHAR)データ

最大2^32 - 1 バイトまたは4GB。

LONG

可変長文字データ

表内の行ごとに可変、最大で1行当たり2^31 - 1 バイトまたは2GB。これによって、下位互換性が保たれます。

NUMBER(p、s)

可変長数字データ。最大精度pまたは位取りs(あるいはその両方)は38。

行ごとに可変。1列に必要な最大領域は1行当たり21バイト。

DATE

日付および時刻の固定長データ(紀元前(B.C.E) 4712年1月1日から、西暦4712年12月31日まで)

表内の行ごとに7バイトで固定。デフォルトの書式は、NLS_DATE_FORMATパラメータで指定される文字列(DD-MON-YYなど)。

BLOB

非構造型バイナリ・データ

最大2^32 - 1 バイトまたは4GB。

BFILE

外部ファイルに格納されたバイナリ・データ

最大2^32 - 1 バイトまたは4GB。

RAW

可変長ロー・バイナリ・データ

表の行ごとに可変、1行当たり最大2000バイト。最大サイズを指定する必要があります。これによって、下位互換性が保たれます。

LONG RAW

可変長ロー・バイナリ・データ

表内の行ごとに可変、最大で1行当たり2^31 - 1 バイトまたは2GB。これによって、下位互換性が保たれます。

ROWID

行アドレスを表すバイナリ・データ

表の行ごとに10バイト(拡張ROWID)または6バイト(制限付きROWID)で固定。

外部データ型

外部データ型には内部データ型がすべて含まれ、サポートされる他のホスト言語で使用するいくつかのデータ型も含まれています。データ型の同値化ではデータ型名を、動的SQL方法4ではデータ型コードを使用します。次の表に、外部データ型を示します。

表4-2 外部データ型

名前

コード

説明

CHAR

1

96

<= 65535バイト、可変長文字列()

<= 65535バイト、固定長文字列()

CHARF

96

<= 65535バイト、固定長文字列

CHARZ

97

<= 65535バイト、固定長、NULL終了文字列()

DATE

12

7バイト、固定長日付/時刻値

DECIMAL

7

COBOLパック10進数

DISPLAY

91

先行符号付きCOBOL数値文字列

DISPLAY TRAILING

152

COBOL後続符号付き数値

FLOAT

4

4バイトまたは8バイトの浮動小数点数

INTEGER

3

2バイト、4バイトまたは8バイトの符号付き整数。

LONG

8

<= 2147483647バイト、固定長文字列

LONG RAW

24

<= 217483647バイト、固定長バイナリ・データ

LONG VARCHAR

94

<= 217483643バイト、可変長文字列

LONG VARRAW

95

<= 217483643バイト、可変長バイナリ・データ

NUMBER

2

2進化10進数形式で表したOracle内部形式番号。

OVERPUNCH LEADING

172

埋込み先行符号付きCOBOL数値文字列

OVERPUNCH TRAILING

154

埋込み後続符号付きCOBOL数値文字列(PIC S9(n)V9(m) DISPLAY形式での宣言と同じ)

RAW

23

<= 65535バイト、固定長バイナリ・データ()

ROWID

11

固定長バイナリ値(システム固有)

STRING

5

<= 65535バイト、NULL終了文字列()

UNSIGNED

68

2バイトまたは4バイトの符号なし整数

UNSIGNED DISPLAY

153

COBOL符号なし数値

VARCHAR

9

<= 65533バイト、可変長文字列

VARCHAR2

1

<= 65535バイト、可変長文字列()

VARNUM

6

可変長2進数

VARRAW

15

<= 65533バイト、可変長バイナリ・データ

注意:

CHARのデータ型コードは、PICX=VARCHAR2のときには1、PICX=CHARFのときには96になります。

一部のプラットフォームでは、最大サイズが32767 (32K)です。

CHAR

CHARの動作は、オプションPICXの設定によって異なります。詳細は、「PICX」を参照してください。

CHARF

デフォルトでは、CHARFデータ型はすべての非可変長文字ホスト変数を表します。CHARFデータ型は、固定長文字列の格納に使用します。ほとんどのプラットフォームでは、CHARF値の最大長は65535 (64K)バイトです。詳細は、「PICX」を参照してください。

入力時: Oracleでは、入力ホスト変数に指定されたバイト数を読み取り、後続の空白を切り捨てずに、ターゲット・データベース列に入力値を格納します。

入力値がデータベース列の定義より長い場合は、エラーが発生します。入力値がすべて空白の場合は、空白文字列が格納されます。

出力時: Oracleからは出力ホスト変数に指定したバイト数が戻され、必要に応じて空白が埋め込まれて、出力値がターゲット・ホスト変数に割り当てられます。NULLが戻された場合、変数の元の値は上書きされません。

出力値がホスト変数の宣言長より長い場合、Oracleはホスト変数に割り当てる前に出力値を切り捨てます。標識変数が使用可能な場合、標識変数は出力値の元の長さに設定されます。

CHARZ

CHARZデータ型は、固定長のNULL終了文字列を表します。ほとんどのプラットフォームでは、CHARZ値の最大長は65535バイトです。通常Pro*COBOLでは、この外部型は必要ありません。

DATE

DATEデータ型は、日付および時刻を7バイトの固定長フィールドで表します。表4-3に示すように、世紀、年、月、日、時(24時間制)、分および秒は、左から右にこの順序で格納されます。

表4-3 日付書式

バイト

1

2

3

4

5

6

7

意味

世紀

年

月

日

時

分

秒

例

1994年10月17日午後1時23分12秒

119

194

10

17

14

24

13

世紀と年を表すバイトは、100を加算した表記です。時間、分および秒は、1を加算した表記です。B.C.E.(西暦紀元前)の日付は99以下です。エポックは、紀元前4712年1月1日です。この日付の場合、世紀のバイトは53で、年のバイトは88です。時間のバイト範囲は1から24です。分と秒の範囲は、1から60です。時刻のデフォルトは、午前零時(1, 1, 1)です。Pro*COBOLは「日時および時間隔のデータ型記述子」に記載されているとおり、追加でさらに5つの日時データ型をサポートします。

DECIMAL

DECIMALデータ型は、計算用のパック10進数を表します。COBOLでは、ホスト変数は暗黙的な小数点を持つ符号付きCOMP-3フィールドであることが必要です。データ変換中に有効な数字がなくなると、値は宣言された長さに切り捨てられます。

DISPLAY

DISPLAYデータ型は数値文字データを表します。DISPLAYデータ型は、COBOLのDISPLAY SIGN LEADING SEPARATEの数値を参照し、PIC S9(n)にはn + 1バイトの記憶域が、PIC S9(n)V9(d)にはn + d + 1バイトの記憶域が必要です。

FLOAT

FLOATデータ型は、小数部分を持つ数値またはINTEGERデータ型の容量を超える数値を表します。FLOATは、COBOLデータ型COMP-1 (4バイトの浮動小数点)およびCOMP-2 (8バイトの浮動小数点)に関連しています。

Oracleでは、数値の内部形式が10進数であるため、浮動小数点の場合よりも大きい精度で数を表現できます。

注意: SQL文でFLOAT値を比較する場合、FLOATデータ型では数値がバイナリ(10進数ではない)で格納されるのでSQLファンクションROUNDを使用します。小数部分は正確に変換されません。

INTEGER

INTEGERデータ型は、小数部分のない数値を表します。整数は、2バイト、4バイトまたは8バイトの符号付き2進数です。ワード内のバイトの並びはプラットフォームによって異なります。入力および出力ホスト変数に長さを指定する必要があります。出力時に、列に小数部があると、小数点以降の桁が切り捨てられます。

LONG

LONGデータ型は、固定長の文字列を表します。LONGデータ型はVARCHAR2データ型と似ていますが、LONG値の最大長は2147483647バイト(2GB)である点で異なります。

LONG RAW

LONG RAWデータ型は、固定長バイナリ・データまたは固定長バイト文字列を表します。LONG RAW値の最大長は、2147483647バイト(2GB)です。

LONG RAWデータはLONGデータと似ていますが、OracleではLONG RAWデータの意味は解釈されず、LONG RAWデータをあるシステムから別のシステムへ送信してもキャラクタ・セットは変換されません。

LONG VARCHAR

LONG VARCHARデータ型は、可変長の文字列を表します。LONG VARCHAR変数では、4バイトの長さフィールドに文字列フィールドが続きます。文字列フィールドの最大長は2147483643バイトです。EXEC SQL VAR文では、4バイトの長さフィールドは含めないでください。

LONG VARRAW

LONG VARRAWデータ型は、バイナリ・データまたはバイト文字列を表します。LONG VARRAW変数では、4バイトの長さフィールドにデータ・フィールドが続きます。データ・フィールドの最大長は2147483643バイトです。EXEC SQL VAR文では、4バイトの長さフィールドは含めないでください。

NUMBER

NUMBERデータ型は、COBOLデータ型では表せないOracle NUMBERの内部書式を表します。

OVER-PUNCH

OVER-PUNCHは、COBOL言語用のデフォルトの符号付き数値です。各桁は10を基数としたASCII形式またはEBCDIC形式で格納され、1つの桁がコンピュータ記憶域の1バイトを占めます。符号は、使用されるバイトの1つの上位ニブルに格納されます。このデータ型がOVER-PUNCHと呼ばれるのは、符号が最初または最後のバイトのどちらかに格納された数字に埋め込まれるためです。デフォルトの符号位置は、後続バイトです。OVER-PUNCHの指定には、PIC S9(n)V9(m) TRAILINGまたはPIC S9(n)V9(m) LEADINGを使用します。

RAW

RAWデータ型は、固定長バイナリ・データまたは固定長バイト文字列を表します。ほとんどのプラットフォームでは、RAW値の最大長は65535バイトです。

RAWデータはCHARデータと似ていますが、OracleではRAWデータの意味は解釈されず、RAWデータをあるシステムから別のシステムへ送信してもキャラクタ・セットの変換は行われません。

ROWID

ROWIDデータ型は、COBOLのデータベース行識別子です。論理ROWIDおよび物理ROWIDの両方(およびOracle表以外のROWID)をサポートするために、ユニバーサルROWID (UROWID)が定義されています。このデータ型にはSQL-ROWID疑似型を使用します(「ユニバーサルROWID」を参照してください)。

VARCHAR2ホスト変数を使用すると、ROWIDを読込み可能な形式で格納できます。ROWIDを選択またはフェッチしてVARCHAR2ホスト変数に入れると、Oracleはそのバイナリ値を18バイトの文字列に変換し、次の書式で戻します。

BBBBBBBB.RRRR.FFFF

ここで、BBBBBBBBはデータベース・ファイルのブロック、RRRRはブロック内の行(最初の行は0)、FFFFはデータベース・ファイルを示します。これらの値は16進数です。たとえば、次のROWIDを考えます。

0000000E.000A.0007

これは、7番目のデータベース・ファイルの15番目のブロックの11行目を示します。

通常、ROWIDをフェッチしてVARCHAR2ホスト変数に入れてから、UPDATE文またはDELETE文のWHERE句に含まれるROWID疑似列とホスト変数を比較します。そのようにして、カーソルによってフェッチされた最終行を識別できます。「CURRENT OF句の擬似実行」の例を参照してください。

注意: 完全な移植性が必要な場合、またはアプリケーションでTransparent Gatewayを介してOracle以外のデータベースと通信する場合は、VARCHAR2ホスト変数の宣言時に最大長の256 (18ではない)バイトを指定します。また、アプリケーションがOracle Open Gatewayを介してOracle以外のデータ・ソースと通信する場合も、最大長として256バイトを指定します。ホスト変数の内容は何も類推できませんが、SQL文では正常に動作します。

STRING

STRINGデータ型はVARCHAR2データ型と似ていますが、STRING値は常にLOW-VALUE文字で終了する点が異なります。通常、このデータ型はPro*COBOLでは使用されません。

UNSIGNED

UNSIGNEDデータ型は符号なし整数を表します。通常、このデータ型はPro*COBOLでは使用されません。

VARCHAR

VARCHARデータ型は、可変長の文字列を表します。VARCHAR変数には、2バイトの長さフィールドと、その後に続く65533バイトの文字列フィールドがあります。ただし、VARCHAR配列要素では、文字列フィールドの最大長は65530バイトです。VARCHAR変数の長さを指定するときは、長さフィールド用に必ず2バイトを付加してください。さらに長い文字列には、LONG VARCHARデータ型を使用してください。EXEC SQL VAR文には、2バイトの長さフィールドを含めないでください。

VARCHAR2

VARCHAR2データ型は、可変長の文字列を表します。ほとんどのプラットフォームでは、VARCHAR2値の最大長は65535バイトです。

VARCHAR2(n)値の最大長は、文字数ではなくバイト数で指定します。したがって、VARCHAR2(n)変数にマルチバイト・キャラクタを格納する場合、最大長はn文字より少なくなります。

入力時: Oracleは入力ホスト変数に指定されたバイト数を読み込み、後続の空白文字を取り除き、入力値をターゲット・データベース列に格納します。

入力値がデータベース列の定義より長い場合は、エラーが発生します。すべて空白の入力値は、OracleではNULLとして扱われます。

文字値が有効な数値を表している場合は、Oracleはその文字値をNUMBER列値に変換できます。文字値が有効な数値を表していない場合は、エラーが発生します。

出力時: Oracleからは出力ホスト変数に指定したバイト数が戻され、必要に応じて空白が埋め込まれて、出力値がターゲット・ホスト変数に割り当てられます。NULLが戻されると、Oracleはホスト変数に空白文字を埋めます。

出力値がホスト変数の宣言長より長い場合、Oracleはホスト変数に割り当てる前に出力値を切り捨てます。標識変数が使用可能な場合、標識変数は出力値の元の長さに設定されます。

Oracleでは、NUMBER列値を文字値に変換できます。文字ホスト変数の長さによって精度が決定します。ホスト変数の長さがその数に対して短すぎる場合は、科学表記法が使用されます。たとえば、列値123456789を選択して長さ6のホスト変数に入れると、Oracleはホスト変数に値1.2E08を戻します。

VARNUM

VARNUMデータ型は書式がNUMBERと似ていますが、通常はPro*COBOLでは使用されません。

VARRAW

VARRAWデータ型は、可変長バイナリ・データまたは可変長バイト文字列を表します。VARRAWデータ型はRAWデータ型に似ていますが、VARRAW変数の場合は2バイトの長さフィールドに<= 65533バイトのデータ・フィールドが続きます。さらに長い文字列には、LONG VARRAWデータ型を使用してください。EXEC SQL VAR文では、2バイトの長さフィールドは含めないでください。VARRAW変数の長さを取得するには、長さフィールドを参照します。

SQL疑似列および関数

SQLは、表4-4に示す疑似列を認識します。これらの疑似列は、特定のデータ項目を戻します。

表4-4 擬似列および内部データ型

疑似列

内部データ型

CURRVAL

NUMBER

LEVEL

NUMBER

NEXTVAL

NUMBER

ROWID

ROWID

ROWNUM

NUMBER

疑似列は、実際に表に存在する列ではありません。ただし、疑似列は列のように扱われるため、疑似列の値を表からSELECTする必要があります。疑似列の値は、ダミー表からSELECTする方が便利な場合もあります。

さらにSQLは、表4-5に示すパラメータなしの関数を認識します。これらの関数も、特定のデータ項目を戻します。

表4-5 関数および内部データ型

機能

内部データ型

SYSDATE

DATE

UID

NUMBER

USER

VARCHAR2

SQLの疑似列および関数は、SELECT文、INSERT文、UPDATE文およびDELETE文で参照できます。次の例では、従業員の雇用後の月数の計算にSYSDATEを使用しています。

EXEC SQL SELECT MONTHS_BETWEEN(SYSDATE, HIREDATE)
INTO :MONTHS-OF-SERVICE
FROM EMP
WHERE EMPNO = :EMP-NUMBER
END EXEC.

これから、SQLの疑似列および関数を簡単に説明します。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

CURRVALは、指定された順序における現行の番号を戻します。CURRVALを参照する前に、NEXTVALを使用して順序番号を生成する必要があります。

LEVELは、ツリー構造におけるノードのレベル番号を戻します。ルートはレベル1、ルートの子はレベル2、孫はレベル3になります。

SELECT CONNECT BY文でLEVELを使用して、表の一部の行または全部の行をツリー構造に取り込むことができます。また、ORDER BY句またはGROUP BY句でLEVELを使用すると、ツリー内の各レベルでデータが分離されます。

問合せでツリーが検索される方向(ルートから下へ、またはブランチから上へ)は、PRIOR演算子で指定します。ツリーのルートを識別する条件は、START WITH句で指定します。

NEXTVALは、指定された順序における次の番号を戻します。順序を作成した後、それを使用してトランザクション用に一意の順序番号を作成できます。次の例では、順序partnoで部品番号を割り当てます。

EXEC SQL INSERT INTO PARTS
VALUES (PARTNO.NEXTVAL, :DESCRIPTION, :QUANTITY, :PRICE
END EXEC.

トランザクションで順序番号が生成された場合は、そのトランザクションをコミットまたはロールバックすると順序番号が増分されます。NEXTVALを参照すると、現行の順序番号がCURRVALに格納されます。

ROWNUMは、表から行が選択された順序を示す番号を戻します。最初に選択された行のROWNUMは1に、2番目に戻された行のROWNUMは2になります。SELECT文にORDER BY句が含まれている場合は、ソート選択された行にROWNUMが割り当てられた後にソートされます。

ROWNUMを使用して、SELECT文で戻される行数を制限できます。また、UPDATE文でROWNUMを使用して、表の各行に一意の値を割り当てることもできます。WHERE句でROWNUMを使用した場合は、取り出される行数のみが制限され、SELECT文の処理は停止されません。WHERE句でのROWNUMの適切な使用方法は、次の方法のみです。

... WHERE ROWNUM < constant END-EXEC.

これは、ROWNUMの値は行が取り出されるときにのみ増加するためです。次のように指定した場合、4行目までは取り出されないため、この検索条件が満たされません。

... WHERE ROWNUM = 5 END-EXEC.

SYSDATEは、現在の日付と時刻を戻します。

UIDは、Oracleユーザーに割り当てられた一意のID番号を戻します。

USERは、Oracleカレント・ユーザーの名前を戻します。

日時および時間隔のデータ型記述子

Pro*COBOLでサポートされるOCI日時および時間隔のデータ型を簡単に説明します。

関連項目
日時データ型記述子の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

ANSI DATE

ANSI DATEはDATEを基本としていますが、時間部分は含まれていません。(したがって、タイム・ゾーンも含まれていません。)ANSI DATEは、DATEデータ型のANSI仕様部の後に指定します。ANSI DATEをDATEまたはタイムスタンプ・データ型に割り当てると、Oracle DATEの時間部分およびタイムスタンプがゼロに設定されます。DATEまたはタイムスタンプをANSI DATEに割り当てた場合、時間部分は無視されます。

このデータ型ではなく、日付および時刻が含まれているTIMESTAMPデータ型の使用をお薦めします。

TIMESTAMP

TIMESTAMPデータ型は、DATEデータ型の拡張機能です。DATEデータ型の年、月、日の他、時、分、秒の値が格納されます。タイム・ゾーンは含まれていません。TIMESTAMPデータ型の書式は次のようになります。

TIMESTAMP(fractional_seconds_precision)

fractional_seconds_precision(オプション)は、SECOND日時フィールドの小数部で、0から9の数を指定します。デフォルトは6です。

TIMESTAMP WITH TIME ZONE

TIMESTAMP WITH TIME ZONE (TSTZ)データ型はTIMESTAMPの改良型で、その値に明示的なタイム・ゾーン置換が含まれています。タイムゾーンによる時差は、地方時とUTC(協定世界時、旧称はグリニッジ標準時)との時差(時および分単位)です。TIMESTAMP WITH TIME ZONEデータ型の書式は次のとおりです。

TIMESTAMP(fractional_seconds_precision) WITH TIME ZONE

fractional_seconds_precision(オプション)は、SECOND日時フィールドの小数部で、0から9の数を指定します。デフォルトは6です。

TIMESTAMP WITH TIME ZONE値が2つある場合、それらがUTCの同一の時間を示している場合、データにTIME ZONEオフセットが格納されているかどうかにかかわらず同一とみなされます。

TIMESTAMPWITHLOCALTIMEZONE

TIMESTAMP WITH LOCAL TIME ZONE (TSLTZ)は、値にタイム・ゾーンによる時差を含んだTIMESTAMPのもう1つの変形です。格納の書式はTIMESTAMPと同じです。TIMESTAMP WITH TIME ZONEとは、データベースに格納されるデータがデータベース・タイム・ゾーンに正規化される点と、タイム・ゾーンによる時差が列データに格納されない点が異なります。ユーザーがデータを取り出すと、そのユーザーのローカル・セッション・タイム・ゾーンでデータが戻されます。

タイムゾーンによる時差は、地方時とUTC(協定世界時、旧称はグリニッジ標準時)との時差(時および分単位)です。TIMESTAMP WITH LOCAL TIME ZONEデータ型の書式は次のとおりです。

TIMESTAMP(fractional_seconds_precision) WITH LOCAL TIME ZONE

fractional_seconds_precision(オプション)は、SECOND日時フィールドの小数部で、0から9の数を指定します。デフォルトは6です。

INTERVALYEARTOMONTH

INTERVAL YEAR TO MONTHは、YEARおよびMONTHの日時フィールドを使用して、時間を格納します。INTERVAL YEAR TO MONTHデータ型の書式は次のようになります。

INTERVAL YEAR(year_precision) TO MONTH

year_precision(オプション)には、YEAR日時フィールドの桁数を指定します。year_precisionのデフォルト値は2です。

INTERVALDAYTOSECOND

INTERVAL DAY TO SECONDは、日、時、分および秒で時間を格納します。INTERVAL DAY TO SECONDデータ型の書式は次のようになります。

INTERVAL DAY (day_precision) TO SECOND(fractional_seconds_precision)

パラメータは次のとおりです。

- day_precisionには、DAY日時フィールドの桁数を指定します。これはオプションです。0から9の値を指定できます。デフォルトは2です。

- fractional_seconds_precisionには、SECOND日時フィールドの小数部の桁数を指定します。これはオプションです。0から9の値を指定できます。デフォルトは6です。

注意:
日時データに対するDML操作で予期しない結果が出ないようにするには、組込みSQLファンクションDBTIMEZONEおよびSESSIONTIMEZONEに対して問合せを実行してデータベース・タイム・ゾーンおよびセッション・タイム・ゾーンを検証します。タイム・ゾーンが手動で設定されていない場合、デフォルトではオペレーティング・システムのタイム・ゾーンが使用されます。オペレーティング・システムのタイム・ゾーンがOracleで有効なタイム・ゾーンではない場合、UTCがデフォルト値として使用されます。

ホスト変数

ホスト変数は、ホスト・プログラムおよびサーバーで通信する際のキーとなります。一般的に、ホスト・プログラムはサーバーにデータを入力し、サーバーはホスト・プログラムにデータを出力します。サーバーは入力データをデータベース列に格納し、出力データをプログラムのホスト変数に格納します。

ホスト変数の宣言

ホスト変数は、Pro*COBOLでサポートされているCOBOLデータ型を使用しCOBOLの規則に従って宣言します。COBOLデータ型には、ソース/ターゲット・データベース列との互換性が必要です。

サポートされているCOBOL変数宣言とその説明、対応する外部データ型およびOracleデータ型コードは、表4-6を参照してください。

表4-6 ホスト変数の宣言

変数宣言

説明

外部データ型

型コード

PIC X...X

PIC X(n)

PIC X...X VARYING

PIC X(n) VARYING

1バイト文字からなる固定長文字列(1)

1バイト文字からなる長さnの文字列

1バイト文字からなる可変長文字列(1、2)

1バイト文字からなる可変長文字列(最大長n)(2)

CHARF

VARCHAR

96

9

PIC N...N

PIC G...G

PIC N(n)

PIC G(n)

PIC N...N VARYING

PIC N(n) VARYING

PIC G...G VARYING

PIC G(n) VARYING

マルチバイトNCHAR文字からなる固定長文字列

文字(1、3)

マルチバイトNCHAR文字からなるn文字の文字列

(3)

マルチバイト・キャラクタからなる可変長文字列(2、3)

マルチバイト・キャラクタからなる可変長文字列(最大長n)

文字(2、3)

CHARF

VARCHAR

96

9

PIC S9...9 BINARY

PIC S9(n) BINARY

PIC S9...9 COMP

PIC S9(n) COMP

PIC S9...9 COMP-4

PIC S9(n) COMP-4

整数(4、5、7)

INTEGER

3

PIC S9...9 COMP-5

PIC S9(n) COMP-5

バイトスワップ整数(4、5、6、7)

INTEGER

3

COMP-1

COMP-2

浮動小数点数(5)

FLOAT

4

PIC S9...9[V9...9] COMP-3

PIC S9(n)[V9(n)] COMP-3

PIC S9...9[V9...9]

PACKED-DECIMAL

PIC S9(n)[V9(n)]

PACKED-DECIMAL

パック10進数(4、5)

DECIMAL

7

PIC S9...9[V9...9] DISPLAY

SIGN LEADING SEPARATE

PIC S9(n)[V9(m)] DISPLAY

SIGN LEADING SEPARATE

PIC S9...9[V9...9] DISPLAY

SIGN TRAILING SEPARATE

PIC S9(n)[V9(m)] DISPLAY

SIGN TRAILING SEPARATE

先行符号表示(8、11)

後続符号表示(8)

DISPLAY

DISPLAY TRAILING

91

152

PIC 9...9 DISPLAY

PIC 9(n)[V9(m)] DISPLAY

符号なし表示(9)

UNSIGNED DISPLAY

153

PIC S9...9[V9...9] DISPLAY

SIGN TRAILING

PIC S9(n)[V9(m)] DISPLAY

SIGN TRAILING

PIC S9...9[V9...9] DISPLAY

SIGN LEADING

PIC S9(n)[V9(m)] DISPLAY

SIGN LEADING

埋込み後続符号付き(9)

埋込み先行符号付き(9)

OVER-PUNCH

TRAILING

OVER-PUNCH LEADING

154

172

SQL-CURSOR

カーソル変数

SQL-CONTEXT

ランタイム・コンテキスト

SQL-ROWID

ユニバーサルROWID

UROWID

104

SQL-BFILE

外部バイナリ・ファイル

BFILE

112

SQL-BLOB

バイナリLOB

BLOB

113

SQL-CLOB

キャラクタLOB

CLOB

114

注意:

1. X...Xおよび9...9は、Xまたは9の個数(n)をそれぞれ表します。可変長文字列の場合、nは最大長です。

2. キーワードVARYINGは、外部データ型VARCHARを文字列に割り当てます。詳細は、「VARCHAR変数の宣言」を参照してください。

3. Pro*COBOLのソース・ファイルでPIC NまたはPIC Gデータ型を使用する場合は、そのデータ型がCOBOLコンパイラでサポートされていることを事前に確認してください。

4. 符号付きの数(PIC S...)のみ使用できます。ただし、浮動小数点数の場合はPIC文字列は受け入れられません。

5. すべてのCOBOLコンパイラで、これらのデータ型が必ずサポートされているとはかぎりません。

6. COMPまたはCOMP-5では、小数部分を持つ数値は受け入れられません。また、スケーリングされた2進数はサポートされません。SPARC Solarisの64ビット・プラットフォームでは、COMP-5はサポートされません。かわりにCOMPを使用してください。

7. 整数の最大値はnから18です。この値は、オペレーティング・システムおよびPro*CobolとCobolのコンパイラによって異なります。

8. DISPLAYおよびSIGNはどちらも省略できます。

9. DISPLAYは省略できます。

10. TRAILINGを省略した場合、埋め込まれる符号の位置はオペレーティング・システムによって異なります。

11. LEADINGは省略できます。

表4-6および表4-7の記号{と}は、中に省略可能なエントリが含まれることを示します。記号{および}は、記号|で区切られたトークンのどちらかを選択する必要があることを示します。

表4-7は、各内部データ型の間で変換可能なすべてのCOBOLデータ型を示します。

表4-7 互換性のあるOracleの内部データ型

内部データ型

注意

COBOLデータ型

説明

CHAR(x) VARCHAR2(y)

(1)

(1)

PIC X(n)

PIC X...X

PIC X(n) VARYING

PIC X...X VARYING

PIC S9...9 COMP

PIC S9(n) COMP

PIC S9...9 BINARY

PIC S9(n) BINARY

PIC S9...9 COMP-5

PIC S9(n) COMP-5

COMP-1

COMP-2

PIC S9...9[V9...9] COMP-3

PIC S9(n)[V9(n)] COMP-3

PIC S9...9[V9...9] DISPLAY

PIC S9(n)[V9(n)] DISPLAY

文字列

n文字の文字列

可変長文字列

整数

整数

整数

浮動小数点数

パック10進数

表示

NCHAR(u) NVARCHAR2(v)

(2)

(2)

PIC {N...N | G...G}

PIC { N(n) | G(n)}

各国語キャラクタ文字列

n文字の各国語キャラクタ文字列

BLOB

CLOB

NCLOB

BFILE

SQL-BLOB

SQL-CLOB

SQL-NCLOB

SQL-BFILE

バイナリLOB

キャラクタLOB

各国語キャラクタLOB

外部バイナリ・ファイル

NUMBER

NUMBER (p,s)

(3)

PIC S9...9 COMP

PIC S9(n) COMP

PIC S9...9 BINARY

PIC S9(n) BINARY

PIC S9...9 COMP-5

PIC S9(n) COMP-5

COMP-1

COMP-2

PIC S9...9V9...9 COMP-3

PIC S9(n)V9(n) COMP-3

PIC S9...9V9...9 DISPLAY

PIC S9(n)V9(n) DISPLAY

PIC [X...X| N...N| G...G]

PIC [X(n)| N(n)| G(n)]

PIC X...X VARYING

PIC X(n) VARYING

整数

整数

整数

浮動小数点数

パック10進数

表示

文字列(4)

n文字の文字列(4)

可変長文字列

nバイトの可変長文字列

DATE

LONG

RAW

LONG RAW

ROWID

(5)

(1)

(6)

PIC X(n)

PIC X...X

PIC X(n)

PIC X(n) VARYING

PIC X...X VARYING

SQL-ROWID

nバイトの文字列

文字列

nバイトの可変長文字列

ユニバーサルROWID

注意:

1. 1<=x <= 2000バイト、デフォルトは1。1<=y <=4000 バイト、デフォルトは1。

2. 1<=u<=2000バイト、デフォルトは1。1<=v<=4000バイト、デフォルトは1。

3. pの範囲は2から38で、sの範囲は-84から127です。

4. 文字列が、0から9、ピリオド(.)、+、-、E、e、の変換可能な文字で構成されている場合は、文字列を数値に変換できます。システムのグローバリゼーション・サポート(旧称National Language SupportまたはNLS)の設定によっては、小数点がピリオド(.)からカンマ(,)へ変更になる場合があります。

5. 文字列型に変換された場合のDATEのデフォルトのサイズは、システムで有効になっているNCHARの設定によって決まります。2進値に変換された場合の長さは7バイトです。

6. 文字列型に変換すると、ROWIDには18から4000バイト必要です。ROWIDも文字型に変換できます。すべての新規プログラムにSQL-ROWIDを使用することをお薦めします。

宣言の例

次の例では、この後で使用するいくつかのホスト変数を宣言しています。

...
01  STR1  PIC X(3).
01  STR2  PIC X(3) VARYING.
01  NUM1  PIC S9(5) COMP.
01  NUM2  COMP-1.
01  NUM3  COMP-2.
...

次の例に示すように、簡単なCOBOL型の1次元表を宣言することもできます。

...
01  XMP-TABLES.
05  TAB1  PIC XXX OCCURS 3 TIMES.
05  TAB2  PIC XXX VARYING OCCURS 3 TIMES.
05  TAB3  PIC S999 COMP-3 OCCURS 3 TIMES.
...

初期化

ホスト変数(疑似型のホスト変数を除く)は、次の例に示すように、VALUE句を使用して初期化できます。

01  USERNAME    PIC X(10) VALUE "SCOTT".
01  MAX-SALARY  PIC S9(4) COMP VALUE 5000.

文字変数に割り当てられた文字列値がその変数の宣言長より短い場合は、文字列の右側に空白が埋め込まれます。文字変数に割り当てられた文字列値が宣言長より長い場合は、文字列は切り捨てられます。

疑似型の変数にVALUES句を指定しても、すべて無視され、廃棄されます(エラーや警告は発行されません)。

制限

アルファベット文字(PIC A)変数および編集済データ項目はホスト変数として使用できません。このため、host変数について次の変数宣言はできません。

....
01  AMOUNT-OF-CHECK  PIC ****9.99.
01  FIRST-NAME       PIC A(10).
01  BIRTH-DATE       PIC 99/99/99.

....

ホスト変数の参照

ホスト変数は、SQL DML文で使用します。次の例に示すように、SQL文ではホスト変数の前にコロン(:)を付ける必要がありますが、COBOL文ではコロンを付けません。

WORKING-STORAGE SECTION.
...
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  EMP-NUMBER  PIC S9(4) COMP VALUE ZERO.
01  EMP-NAME    PIC X(10) VALUE SPACE.
01  SALARY      PIC S9(5)V99 COMP-3.
EXEC SQL END DECLARE SECTION END-EXEC.
...
PROCEDURE DIVISION.
...
DISPLAY "Employee number? " WITH NO ADVANCING.
ACCEPT EMP-NUMBER.
EXEC SQL SELECT ENAME, SAL
INTO :EMP-NAME, :SALARY FROM EMP
WHERE EMPNO = :EMP-NUMBER
END-EXEC.
COMPUTE BONUS = SALARY / 10.
...

次の例に示すように、表または列と同じ名前をホスト変数に指定できます。ただし、このようにすると混乱を招く恐れがあります。

WORKING-STORAGE SECTION.
...
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  EMPNO  PIC S9(4) COMP VALUE ZERO.
01  ENAME  PIC X(10) VALUE SPACE.
01  COMM   PIC S9(5)V99 COMP-3.
EXEC SQL END DECLARE SECTION END-EXEC.
...
PROCEDURE DIVISION.
...
EXEC SQL SELECT ENAME, COMM
INTO :ENAME, :COMM FROM EMP
WHERE EMPNO = :EMPNO
END-EXEC.

ホスト変数としてのグループ項目

Pro*COBOLでは、埋込みSQL文内でグループ項目を使用できます。基本項目(1つのレベルで構成)を持つグループ項目は、ホスト変数として使用できます。ホスト・グループ項目(ホスト構造体)は、SELECT文またはFETCH文のINTO句、およびINSERT文のVALUESリストで参照できます。グループ項目をホスト変数として使用する場合は、SQL文ではグループ名のみ使用します。次に例を示します。

01  DEPARTURE.
05 HOUR    PIC X(2).
05 MINUTE  PIC X(2).

このように宣言した場合、次の文は有効です。

EXEC SQL SELECT DHOUR, DMINUTE
INTO :DEPARTURE
FROM SCHEDULE
WHERE ...

メンバーがグループ項目で宣言される順序は、SQL文中の対応する列の順序と一致する必要があります。また、INSERT文で列のリストが省略されている場合は、データベース表の列の順序と一致する必要があります。グループ項目をホスト変数として使用する場合、グループ項目を基本項目に置換する構文を使用します。先の例では、:DEPARTUREを:DEPARTURE.HOUR, :DEPARTURE.MINUTEに置換します。

ホスト変数として使用するグループ項目には、ホスト表を含めることができます。次の例では、表を含んだグループ項目を使用して、SCHEDULE表に3つのエントリをINSERTしています。

01  DEPARTURE.
05  HOUR    PIC X(2) OCCURS 3 TIMES.
05  MINUTE  PIC X(2) OCCURS 3 TIMES.
...
EXEC SQL INSERT INTO SCHEDULE (DHOUR, DMINUTE)
VALUES (:DEPARTURE) END-EXEC.

VARCHAR=YESと指定した場合、Pro*COBOLでは暗黙的なVARCHARが認識されます。ネストされたグループ項目定義がVARCHARホスト変数と類似している場合、そのグループ項目全体がVARYING型の1つの基本項目のように扱われます。詳細は、「VARCHAR」を参照してください。

グループ項目ではなく基本項目をホスト変数として参照する場合、基本項目名は次の構文で修飾できるため、一意である必要はありません。

group_item.elementary_item

このネーミング変換はSQL文中でのみ行うことができます。COBOLのIN (またはOF)句に類似しています。次に例を示します。

MOVE MINUTE IN DEPARTURE TO MINUTE-OUT.
DISPLAY HOUR OF DEPARTURE.

COBOLのIN (またはOF)句は、SQL文では使用できません。混乱しないように、基本項目名を修飾してください。次に例を示します。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  DEPARTURE.
05  HOUR    PIC X(2).
05  MINUTE  PIC X(2).
01  ARRIVAL.
05  HOUR    PIC X(2).
05  MINUTE  PIC X(2).
EXEC SQL END DECLARE SECTION END-EXEC.
...
EXEC SQL SELECT DHR, DMIN INTO :DEPARTURE.HOUR, :DEPARTURE.MINUTE
FROM TIMETABLE
WHERE ...

制限

ホスト変数は、列、表またはSQL文中の他のオブジェクトでは置換できません。また、Oracle予約語も使用できません。予約語およびキーワードのリストは、付録B「予約語、キーワードおよびネームスペース」を参照してください。.

標識変数

任意のホスト変数に任意指定の標識変数を関連付けることができます。標識変数に関連付けたホスト変数をSQL文内で使用するたびに、結果コードが対応する標識変数内に格納されます。つまり、標識変数によってホスト変数を監視できます。

VALUES句またはSET句中の標識変数を使用して、入力ホスト変数にNULL値を割り当てたり、INTO句中の標識変数を使用して、出力ホスト変数内のNULL値(または文字列の切り捨てられた値)を検出できます。

標識変数の使用方法

標識変数に割り当てることのできる変数は、次のとおりです。

入力時

プログラムが標識変数に割り当てる値の意味は、次のとおりです。

標識変数

説明

-1

Oracleによって、その列にNULLが割り当てられます。このホスト変数の値は無視されます。

>=0

Oracleは、このホスト変数の値を列に割り当てます。

出力時

Oracleが標識変数に割り当てる値の意味は、次のとおりです。

標識変数

説明

-1

この列の値はNULLです。したがって、このホスト変数の値は予測不能です。

0

列の値がそのままこのホスト変数に割り当てられました。

>0

切り捨てられた列の値がこのホスト変数に割り当てられました。標識変数によって返される整数は、列値の元の長さです。SQLCAのSQLCODEが0(ゼロ)に設定されます。

-2

Oracleによって切り捨てられた列値がこのホスト変数に割り当てられました。ただし、元の列値は決定できませんでした(LONG列など)。

標識変数の宣言

標識変数はPIC S9(4) COMPとして明示的に宣言する必要があります。また、予約語は使用できません。次の例では、COMM-IND(名前は任意)という標識変数を宣言しています。

WORKING-STORAGE SECTION.
...
01  EMP-NAME    PIC X(10) VALUE SPACE.
01  SALARY      PIC S9(5)V99 COMP-3.
01  COMMISSION  PIC S9(5)V99 COMP-3.
01  COMM-IND    PIC S9(4) COMP.
...

標識変数の参照

SQL文では、標識変数は前にコロンを付け、対応するホスト変数の直後に記述する必要があります。COBOL文では、標識変数の前にコロンを付けたり、対応するホスト変数の直後に標識変数を記述しないでください。次に、例を示します。

EXEC SQL SELECT SAL, COMM
INTO :SALARY, :COMMISSION:COMM-IND FROM EMP
WHERE EMPNO = :EMP-NUMBER
END-EXEC.
IF COMM-IND = -1
COMPUTE PAY = SALARY
ELSE
COMPUTE PAY = SALARY + COMMISSION.

判読しやすくするため、それぞれの標識変数の前にINDICATORのオプションのキーワードを置くこともできます。その場合も、標識変数の前にはコロンを付ける必要があります。正しい構文は次のとおりです。

:host_variableINDICATOR:indicator_variable

これは、次の構文と同じです。

:host_variable:indicator_variable

ホスト・プログラムでは、両方の形式の式を使用できます。

WHERE句での使用

WHERE句では、標識変数によるNULLの検索はできません。たとえば、次のDELETE文を実行するとエラーが発生します。

*    Set indicator variable.
COMM-IND = -1
EXEC SQL
DELETE FROM EMP WHERE COMM = :COMMISSION:COMM-IND
END-EXEC.

正しい構文は次のとおりです。

EXEC SQL
DELETE FROM EMP WHERE COMM IS NULL
END-EXEC.

エラー・メッセージの回避

インジケータを持たないホスト変数にNULLをSELECTまたはFETCHすると、Oracleはエラー・メッセージを出力します。

コマンドラインにUNSAFE_NULL=YESも指定すると、エラー・メッセージは出力されません。詳細は、第14章「プリコンパイラ・オプション」を参照してください。

ANSIの要件

MODE=ORACLEの場合、切り捨てられた列値をSELECTまたはFETCHして標識変数に関連付けられていないホスト変数に格納すると、Oracleはエラー・メッセージを出力します。

ただし、MODE={ANSI | ANSI14 | ANSI13}の場合にはエラーは発生しません。標識変数の値は、第5章「埋込みSQL」を参照してください。

マルチバイトNCHAR変数の標識変数

マルチバイトNCHAR文字変数の標識変数は、他のホスト変数の場合と同様に使用できます。ただし、正の値(SELECTまたはFETCHの結果が切り捨てられた結果)は、1バイト文字ではなくマルチバイト・キャラクタ単位の文字列の長さを表します。

ホスト・グループ項目の標識変数

標識変数をホスト・グループ項目に使用するには、グループ項目の各NULL値可能な変数に対する標識変数を含むグループ項目を別に設定するか、ハーフ・ワード整変数の表を使用します。グループ項目の各変数に標識変数を設定する必要はありませんが、インジケータを使用したいNULL値可能フィールドは、データ・グループ項目の先頭に配置する必要があります。次のインジケータグループ項目は、DEPARTUREグループ項目に使用できます。

01  DEPARTURE-IND.
05  HOUR-IND   PIC S9(4) COMP.
05  MINUTE-IND PIC S9(4) COMP.

インジケータ表を使用する場合、ホスト・グループ項目内のメンバー数と同じ数の要素を持つ表を宣言する必要はありません。次のインジケータ表は、DEPARTUREグループ項目に使用できます。

01 DEPARTURE-IND PIC S9(4) COMP OCCURS 2 TIMES.

SQL文でインジケータ・グループ項目を参照する方法は、ホスト標識変数を参照する方法と同じです。

EXEC SQL SELECT DHOUR, DMINUTE
INTO :DEPARTURE:DEPARTURE-IND
FROM SCHEDULE
WHERE ...

問合せが完了すると、選択された各コンポーネントがNULL状態かNOT NULL状態かの情報がホスト・インジケータ・グループ項目に設定されます。インジケータ・ホスト変数に関する制限事項およびANSI必要条件は、ホスト・インジケータ・グループ項目にも適用されます。

VARCHAR変数

COBOL文字列データ型は固定長です。ただし、Pro*COBOLではVARCHARと呼ばれる可変長文字列擬似型を宣言できます。VARCHAR変数は、データベースに格納するデータおよびデータベースに渡すデータの長さを正確に指定できる擬似型です。

VARCHAR変数の宣言

VARCHARホスト変数は、次の例に示すように、キーワードVARYINGを宣言に追加することによって定義します。

01  ENAME  PIC X(15) VARYING.

注意:
PIC NおよびPIC Gは、VARYINGを使用した定義では使用できません。VARCHAR変数でのPIC NおよびPIC Gの正しい使用方法は、「暗黙的なVARCHARグループ項目」を参照してください。

注意:
Pro*COBOLは、VARYINGで宣言される変数名に4文字追加します。したがって、COBOLコンパイラが長さがnの変数名をサポートする場合、Pro*COBOLはそれより4文字少ない変数名(n-4)をサポートします。

COBOLのVARYING句は、添字および索引を増分するために、PERFORM文およびSEARCH文で使用するものです。前述の例のPro*COBOLのVARYING句と混同しないでください。

VARCHARは、Pro*COBOLの拡張データ型または宣言済グループ項目と考えられます。たとえば、Pro*COBOLでは、VARCHAR宣言を展開して

01  ENAME  PIC X(15) VARYING.

次のような長さフィールドおよび文字列フィールドを持つグループ項目にします。

01  ENAME.
05  ENAME-LEN  PIC S9(4) COMP.
05  ENAME-ARR  PIC X(15).

長さフィールド(接尾辞-LEN)には、文字列フィールド(接尾辞-ARR)に格納されている値の現在の長さが含まれます。VARCHARホスト変数宣言での最大長は1から9,999バイトの範囲内であることが必要です。

VARCHAR変数の利点は、長さフィールドを明示的に設定および参照できることです。Pro*COBOLは、入力ホスト変数を使用して長さフィールドの値を読み取り、そこに指定された数だけ、文字列フィールドの文字を使用します。出力ホスト変数では、Pro*COBOLは、長さの値を文字列フィールドに格納された文字列の長さに設定します。

暗黙的なVARCHARグループ項目

Pro*COBOLは、プリコンパイラ・オプションVARCHAR=YESがコマンドラインで指定された場合、一部のグループ項目を暗黙的にVARCHARホスト変数として認識します。可変長シングルバイト・キャラクタ・タイプの場合は、次の構造を使用してください(長さはシングルバイト文字で表します)。

nn   data-name-1.
49  data-name-2 PIC S9(4) COMP.
49  data-name-3 PIC X(length).

nnには01から48を指定する必要があります。

可変長マルチバイトNCHAR文字列の場合は、次の書式を使用します(長さはダブルバイト文字で表します)。

nn  DATA-NAME-1.
49 DATA-NAME-2  PIC  S9(4)  COMP.
49 DATA-NAME-3  PIC  N(length).

nn  DATA-NAME-1.
49 DATA-NAME-2  PIC  S9(4)  COMP.
49 DATA-NAME-3  PIC  G(length).

The elementary items in these group-item structures must be declared as level 49 for Pro*COBOL to recognize them as VARCHAR host variables.

Pro*COBOLにVARCHARグループ項目の拡張書式を認識させるには、VARCHARオプションをコマンドラインでVARCHAR=YESと指定する必要があります。VARCHAR=NOと指定した場合は、前述の書式と似た宣言はどれも通常のグループ項目として解釈されます。VARCHAR=YESと指定しても、グループ項目定義の書式が拡張VARCHAR書式と類似しているが同じではない場合には、その項目はVARCHARグループ項目ではなく通常のグループ項目と解釈されます。たとえば、VARCHAR=YESと指定して、次のように記述したとします。

01  LASTNAME.
48 LASTNAME-LEN  PIC S9(4) COMP.
48 LASTNAME-TEXT PIC X(15).

このグループ項目の要素にはレベル49ではなくレベル48が使用されているため、この項目はVARCHARグループ項目ではなく通常のグループ項目と解釈されます。

Pro*COBOL VARCHARオプションの詳細は、第14章「プリコンパイラ・オプション」を参照してください。

VARCHAR変数の参照

SQL文でVARCHAR変数を参照する場合は、次の例のように、グループ名の前にコロンを付けたものを使用します。

WORKING-STORAGE SECTION.
...
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01  PART-NUMBER  PIC X(5).
01  PART-DESC    PIC X(20) VARYING.
EXEC SQL END DECLARE SECTION END-EXEC.
...
PROCEDURE DIVISION.
...

EXEC SQL
SELECT PDESC INTO :PART-DESC FROM PARTS
WHERE PNUM = :PART-NUMBER
END-EXEC.

問合せの実行後、データベースから取り出され、PART-DESC-ARRに格納された文字列の実際の長さが、PART-DESC-LENに格納されます。

文字データの処理

この項では、Pro*COBOLが文字ホスト変数をどのように処理するかを説明します。文字ホスト変数には、シングルバイト文字ホスト変数およびマルチバイト・グローバリゼーション・サポート(旧称「NLS」)文字ホスト変数がそれぞれ2種類あります。

- PIC X(n)(またはPIC X...X)

- PIC X(n) VARYING (またはPIC X...X VARYING)

- PIC N(n)(またはPIC N...N)またはPIC G(n)(またはPIC G...G)

注意:
マルチバイトNCHARデータ型を使用する前に、使用しているCOBOLコンパイラがPIC Nデータ型またはPIC Gデータ型に対応していることを確認してください。

PIC Xのデフォルト

PIC Xのデフォルトのデータ型はCHARFです(リリース8.0より前はVARCHAR2でした)。下位互換性を保つために、プリコンパイラ・コマンドライン・オプションPICXが用意されています。PICXはコマンドラインまたは構成ファイルにのみ入力できます。詳細は、「PICX」を参照してください。

PICXオプションの効果

PICXオプションによって、文字列内のデータをPro*COBOLがどのように扱うかが決定されます。PICXオプションを使用すると、プログラムでANSI固定長文字列を使用したり、データベース・サーバーおよびPro*COBOLの旧バージョンとの互換性を維持できます。

リリース8.0より前のPro*COBOLと同じ結果を取得するには、PICX=VARCHAR2 (デフォルトではありません)を使用する必要があります。あるいは、次の文を使用します。

EXEC SQL varname IS VARCHAR2 END-EXEC.

この文は、変数ごとに使用します。

固定長文字変数

固定長文字変数は、PIC X(n)、PIC G(n)およびPIC N(n)データ型を使用して宣言します。これらの変数の型では、文字データはそのロールに基づいて、入力変数または出力変数として扱われます。

入力時

PICX=VARCHAR2の場合、プログラム・インタフェースは値をデータベースに送る前に、後続の空白を削除します。固定長CHAR列に挿入した場合、Pro*COBOLはそのデータベース列の長さに達するまで、後続の空白を再度追加します。これに対し、可変長VARCHAR2列に挿入した場合は、Pro*COBOLは空白を追加されません。

PICX=CHARFの場合は、後続の空白は削除されません。

マルチバイト・グローバリゼーション・サポート・データのホスト入力変数の場合、後続のダブルバイトの空白は削除されません。lengthコンポーネントは、バイト単位ではなく文字単位のデータの長さとみなされます。

入力値に余分な文字が後続していないことを確認してください。値がPIC X(n)変数にACCEPTまたはMOVEされると、COBOLによってその変数の長さまで空白が追加されるため、これは通常は問題になりません。

この点について、次の例で示します。

WORKING-STORAGE SECTION.
...
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  EMPLOYEES.
05  EMP-NAME     PIC X(10).
05  DEPT-NUMBER  PIC S9(4) VALUE 20 COMP.
05  EMP-NUMBER   PIC S9(9) VALUE 9999 COMP.
05  JOB-NAME     PIC X(8).
...
EXEC SQL END DECLARE SECTION END-EXEC.
...
PROCEDURE DIVISION.
...
DISPLAY "Employee name? " WITH NO ADVANCING.
ACCEPT EMP-NAME.
*    Assume that the name MILLER was entered
*    EMP-NAME contains "MILLER    " (4 trailing blanks)
MOVE "SALES" TO JOB-NAME.
*    JOB-NAME now contains "SALES   " (3 trailing blanks)
EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO, JOB)
VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER, :JOB-NAME
END-EXEC.
...

最後の例で、PICX=VARCHAR2を指定してプリコンパイルした場合に、ターゲット・データベース列がVARCHAR2であれば、プログラム・インタフェースによって入力時に後続の空白が削除され、6文字の文字列「MILLER」および5文字の文字列「SALES」のみデータベースに挿入されます。これに対し、ターゲット・データベース列がCHARの場合には、列の幅に達するまで文字列に空白が埋め込まれます。

最後の例で、PICX=CHARFを指定してコンパイルした場合に、JOB列がCHAR(10)として定義されていると、JOB列に挿入される値は「SALES#####」(後続の空白は5個)になります。ただし、JOB列がVARCHAR2(10)として定義されている場合、ホスト変数はPIC X(8)として宣言されているため、挿入される値は「SALES###」(後続の空白は3個)になります。このように、期待したとおりの結果にならない場合があるため、注意してください。

出力時

PICXオプションは、固定長文字変数に対する出力には影響しません。PIC X(n)変数を出力ホスト変数として使用すると、Pro*COBOLによって空白が埋め込まれます。たとえば、プログラムがデータベースから文字列「MILLER」をフェッチした場合、EMP-NAME内の値は「MILLER####」(後続の空白は4個)になります。この文字列は、そのまま別のSQL文への入力として使用できます。

可変長変数

VARCHAR変数では、文字データはそのロールに基づいて、入力変数または出力変数として扱われます。

入力時

VARCHAR変数を入力ホスト変数として使用する場合は、次の例に示すように、拡張VARCHAR宣言の長さフィールドおよび文字列フィールドに値を割り当てる必要があります。

IF ENAME-IND = -1
MOVE "NOT AVAILABLE" TO ENAME-ARR
MOVE 13 TO ENAME-LEN.

文字列変数に空白を埋め込む必要はありません。SQL操作では、Pro*COBOLは空白も含めて、長さフィールドで指定されたとおりの文字数を使用します。

出力時

VARCHAR変数を出力ホスト変数として使用すると、Pro*COBOLによって長さフィールドが設定されます。次に、例を示します。

WORKING-STORAGE SECTION.
...
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  EMPNO  PIC S9(4) COMP.
01  ENAME  PIC X(15) VARYING.
...
EXEC SQL END DECLARE SECTION END-EXEC.
...
PROCEDURE DIVISION.
...
EXEC SQL
SELECT ENAME INTO :ENAME FROM EMP
WHERE EMPNO = :EMPNO
END-EXEC.
IF ENAME-LEN = 0
MOVE FALSE TO VALID-DATA.

VARCHAR変数が固定長文字列より優れている点は、Pro*COBOLによって戻された値の長さをそのまま使用できることです。固定長文字列を使用した場合は、値の長さを取得するには文字数をカウントする必要があります。

マルチバイトNCHARデータのホスト出力変数には何も埋め込まれません。バッファの長さは、文字単位ではなくバイト単位の長さに設定されます。

注意:
PICN_ENDIAN=OSの場合、マルチバイトNCHARデータのバッファの長さは、バイト単位ではなく、文字単位の長さに設定されます。

ユニバーサルROWID

データベース・サーバーでは、ヒープ表と索引構成表の2種類の表編成が使用されます。

ヒープ表はデフォルトです。これは、Oracleより前のすべての表で使用される編成です。物理的な行アドレス(ROWID)は、ヒープ表の行を識別するためのパーマネント・プロパティです。物理ROWIDの外部文字書式は、ベース64でエンコーディングした18バイトの文字列です。

索引構成表には、パーマネント識別子としての物理的な行アドレスがありません。そのような表には、論理ROWIDが定義されます。索引構成表からのSELECT ROWID...文を使用するとき、ROWIDは、表の主キー、制御情報、および物理的な推測を含む不透明な構造です。表から値を検索するために、「WHERE ROWID = ...」などの句を含むSQL文でこのROWIDを使用できます。

ユニバーサルROWIDは、Oracle 8.1 Databaseのリリースで導入されました。ユニバーサルROWIDは、物理ROWIDと論理ROWIDの両方で使用できます。表編成の変更はアプリケーションに影響しないため、ユニバーサルROWIDを使用すると、ヒープ表または索引構成表のデータにアクセスできます。ROWIDに使用される列データ型はUROWID(length)で、lengthはオプションです。

新しいアプリケーションでは、ユニバーサルROWIDを使用してください。

ユニバーサルROWIDの詳細は、『Oracle Database概要』を参照してください。

疑似型SQL-ROWIDを使用したユニバーサルROWIDの宣言の例を次に示します。

01  MY-ROWID SQL-ROWID.

ユニバーサルROWIDのメモリーは、ALLOCATE文を使用して割り当てます。

EXEC SQL ALLOCATE :MY-ROWID END-EXEC.

SQL DML文でMY-ROWIDを次のように使用します。

EXEC SQL SELECT ROWID INTO :MY-ROWID FROM MYTABLE WHERE ... END-EXEC.
...
EXEC SQL UPDATE MYTABLE SET ... WHERE ROWID = :MY-ROWID END-EXEC.
...

必要なくなった場合には、FREEディレクティブを使用してメモリーを解放します。

EXEC SQL FREE :MY-ROWID END-EXEC.

また、18から4000の幅を持つ文字ホスト変数を、ユニバーサルROWIDのホスト・バインド変数として使用することもできます。文字ベースのユニバーサルROWIDはヒープ表でもサポートされていますが、下位互換性しかありません。ユニバーサルROWIDは可変長であるため、選択時に切り捨てられる場合があります。

文字変数の使用例を次に示します。

01  MY-ROWID-CHAR PIC X(4000) VARYING.
...
EXEC SQL ALLOCATE :MY-ROWID-CHAR END-EXEC.
EXEC SQL SELECT ROWID INTO :MY-ROWID-CHAR FROM MYTABLE WHERE ... END-EXEC.
...
EXEC SQL UPDATE MYTABLE SET ... WHERE ROWID = :MY-ROWID-CHAR END-EXEC.
...
EXEC SQL FREE :MY-ROWID-CHAR END-EXEC.

ユニバーサルROWIDを使用して位置付けされた更新の例は、「位置付け更新」を参照してください。

サブプログラムSQLROWIDGET

OracleサブプログラムSQLROWIDGETを使用して、最後に挿入、更新または選択した行のROWIDを取得できます。SQLROWIDGETにはコンテキストまたはNULLおよびROWIDが引数として必要です。

デフォルトのコンテキストを使用するには、SQLROWIDGETへのコールの最初のパラメータとして表意定数NULLを渡します。

ユニバーサルROWIDは、コール前に宣言および割当てを行う必要があります。コンテキストを使用する場合、コール前に宣言および割当てを行う必要があります。構文は次のとおりです。

CALL "SQLROWIDGET" USING NULL rowid.

または

CALL "SQLROWIDGET" USING context rowid.

この場合、各変数の意味は次のとおりです。

context(IN)

擬似型SQL-CONTEXTのランタイム・コンテキスト変数またはデフォルト・コンテキストの場合は表意定数NULL。ランタイム・コンテキストの詳細は、「ランタイム・コンテキストの埋込みSQL文およびディレクティブ」を参照してください。

rowid(OUT)

疑似型SQL-ROWIDのユニバーサルROWID変数。コールの実行が正常に終了すると、この変数は有効なユニバーサルROWIDを指します。エラーが発生した場合は、rowidは定義されません。

次にデフォルト・コンテキストを使用した例を示します。

01  MY-ROWID SQL-ROWID.
...
EXEC SQL ALLOCATE :MY-ROWID END-EXEC.

* INSERT, or UPDATE or DELETE Goes here:
...
CALL "SQLROWIDGET" USING NULL MY-ROWID.
* MY-ROWID now has the universal rowid descriptor for the last row
...
EXEC SQL FREE :MY-ROWID END-EXEC.
...

使用するコンパイラでCALL文に表意定数NULLを使用できない場合は、次のように、実際のS9(9) COMP VALUE 0を使用して変数を宣言し、SQLROWIDGETへのコールにその変数とBY VALUE句を指定してください。

01 NULL-CONTEXT  PIC S9(9) COMP VALUE ZERO.
01 MY-ROWID SQLROWID.
....
CALL "SQLROWIDGET" USING BY VALUE NULL-CONTEXT BY REFERENCE MY-ROWID.

グローバリゼーション・サポート

広く使用されている7ビットまたは8ビットのASCIIキャラクタ・セットおよびEBCDICキャラクタ・セットが英数字を表すのに十分であっても、日本語などのアジアの言語の中には、数千という文字があるものもあります。このような言語では、個々の文字を表すのに16ビット以上必要です。Oracleは、これらの異なる言語をどのように扱っているでしょうか。

Oracleには、シングルバイトおよびマルチバイト・キャラクタ・データを処理し、キャラクタ・セット間で変換できるように、グローバリゼーション・サポート(旧称National Language SupportまたはNLS)が用意されています。これによって、異なる言語環境でアプリケーションを実行できます。グローバリゼーション・サポートでは、数値書式および日付書式はユーザー・セッション用に指定された言語規則に自動的に適応します。したがって、グローバリゼーション・サポートにより、世界中のユーザーがそれぞれの母国語でOracleと対話できます。

様々なグローバリゼーション・サポート・パラメータを指定して、言語によって異なる機能の操作を制御できます。デフォルト・パラメータ値は初期化ファイルで設定できます。表4-8に、各グローバリゼーション・サポート・パラメータの指定内容を示します。

表4-8 グローバリゼーション・サポート・パラメータ

グローバリゼーション・サポート・パラメータ

指定内容

NLS_LANGUAGE

言語によって異なる表記法

NLS_TERRITORY

地域によって異なる表記法

NLS_DATE_FORMAT

日付書式

NLS_DATE_LANGUAGE

日および月の名前に使用する言語

NLS_NUMERIC_CHARACTERS

10進数文字およびグループ・セパレータ

NLS_CURRENCY

各国通貨記号

NLS_ISO_CURRENCY

ISO通貨記号

NLS_SORT

ソート基準

主なパラメータは、NLS_LANGUAGEおよびNLS_TERRITORYです。NLS_LANGUAGEでは、言語によって異なる次の機能のデフォルト値を指定します。

- サーバー・メッセージに使用する言語

- 日および月の名前に使用する言語

- ソート基準

NLS_TERRITORYには、地域によって異なる機能のデフォルト値を指定します。この機能には次が含まれます。

- 日付書式

- 10進数文字

- グループ・セパレータ

- 各国通貨記号

- ISO通貨記号

パラメータNLS_LANGを次のように指定して、ユーザー・セッション用に言語ごとに異なるグローバリゼーション・サポート機能の操作を制御できます。

NLS_LANG = language_territory.character set

languageはユーザー・セッション用のNLS_LANGUAGEの値、territoryはNLS_TERRITORYの値、character setは端末に使用されるコード体系を指します。コード体系(通常はキャラクタ・セットまたはコード・ページと呼ばれる)は、端末で表示できるキャラクタ・セットに対応する数値コードの範囲です。また、これには端末との通信を制御するコードも入っています。

NLS_LANGは、環境変数(または使用しているシステムでこれに相当するもの)として定義します。たとえば、Cシェルを使用するUNIXでは、NLS_LANGを次のように定義できます。

setenv NLS_LANG French_France.WE8ISO8859P1

セッション中にグローバリゼーション・サポート・パラメータの値を変更する場合は、次のようなALTER SESSION文を使用します。

ALTER SESSION SET nls_parameter = value

Pro*COBOLは、Oracle Databaseに格納されている多言語のデータをアプリケーションで処理するためのグローバリゼーション・サポート機能をすべてサポートしています。たとえば、外国語の文字変数を宣言し、それをINSTRB、LENGTHB、SUBSTRBなどの文字列関数に渡すことができます。これらの関数には、それぞれINSTR、LENGTHおよびSUBSTR関数と共通の構文がありますが、文字単位ではなく、バイト単位の操作になります。

関数NLS_INITCAP、NLS_LOWERおよびNLS_UPPERを使用して、大/小文字変換の特別なインスタンスを扱うことができます。さらに、関数NLSSORTを使用して、バイナリ順序ではなく言語上の順序でWHERE句の比較を指定できます。グローバリゼーション・サポート・パラメータをTO_CHAR、TO_DATEおよびTO_NUMBER関数に渡すこともできます。グローバリゼーション・サポートの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。

Pro*COBOLのUnicodeサポート

Pro*COBOLでは、Unicodeで記述されたソース・コードをサポートしていません。ロケールにUTF8を設定する場合は、ASCIIコードのみを使用してソース・コードを記述する必要があります。

Unicode変数を使用する場合は、次の点に注意してください。

- Pro*COBOLでは、「USAGE NATIONAL」をサポートしていません。Unicode変数を使用する場合は、COBOLプログラムをMF Cobolでコンパイルするために-C NSYMBOL="NATIONAL"を指定します。

- Unicodeは、PIC XおよびPIC Nで使用できます。

- AL32UTF8およびUTF8は、PIC Xで使用できます。

- AL16UTF16は、PIC Nで使用できます。

- NLS_NCHAR環境変数は、PIC Nで使用するクライアント側キャラクタ・セットと等価にします。NLS_NCHARが設定されていない場合は、NLS_LANGが使用されます。

- NLS_LANG環境変数は、PIC Xで使用するクライアント側キャラクタ・セットと等価にします。

- AL16UTF16、JA16SJISFIXEDおよびJA16EUCFIXEDは、NLS_NCHARで設定できます。

- JA16SJISおよびJA16SJISTILDEも、NLS_NCHARで設定できます。

- JA16EUCおよびJA16EUCTILDEは、NLS_NCHARで使用できません。

関連項目
NLS_LANGで使用可能なキャラクタ・セットの詳細は、グローバリゼーション・サポート・ガイドを参照してください。

PICX=charf/varchar2はUnicode PIC X変数に対して機能し、PIC Nに対しては前述のリストに示した制限に従って機能します。

NLS_LOCAL=YESの制限事項

プリコンパイラ・オプションNLS_LOCALをYESと指定した場合、グローバリゼーション・サポート・マルチバイト・データ型の空白埋込みおよび空白削除はランタイム・ライブラリ(SQLLIB)によって実行されます。

NLS_LOCAL=YESの場合、PL/SQLブロック内では、マルチバイトNCHAR機能はサポートされません。これらの機能は、N付き引用符で表された文字リテラルおよび固定長の文字変数を組み込みます。

そのため、次の制限が適用されます。

配列は使用できません。PIC NまたはPIC Gデータ型を使用して宣言するホスト変数として、配列を使用できません。

奇数バイト幅はありません。マルチバイトのNCHAR文字の格納に、Oracle CHAR列を使用しないでください。奇数バイトのデータがシングルバイト列からマルチバイトのNCHARホスト変数にFETCHされると、ランタイム・エラーが発生します。

ホスト変数の同値化は行えません。EXEC SQL VAR文を使用してマルチバイトNCHAR文字変数を同値化できません。

動的SQLは使用できません。Pro*COBOLでは、NCHARマルチバイト・キャラクタ文字列ホスト変数に動的SQLを使用できません。

マルチバイト・グローバリゼーション・サポートのデータが格納されている列に対しては、関数を使用しないでください。

埋込みSQL内の文字列

埋込みSQL文内のマルチバイト・グローバリゼーション・サポート文字列は、文字Nと、その後に続く引用符(')で囲まれた文字列で構成されます。

たとえば、次のように指定します。

EXEC SQL
SELECT EMPNO INTO :EMP-NUM FROM EMP
WHERE ENAME=N'NLS_string'
END-EXEC.

埋込みDDL

プリコンパイラ・オプションがNLS_LOCAL=YESと設定されている場合、NCHARデータを格納する列は埋込みデータ定義言語(DDL)文では使用できません。この制限はプリコンパイル時には適用されないため、NCHARなどの拡張された列型を埋込みDDL文で使用すると、プリコンパイル・エラーではなく実行エラーになります。

これらのオプションの詳細は、第14章「プリコンパイラ・オプション」内の各項目を参照してください。

空白埋込み

Pro*COBOL文字変数をマルチバイト・グローバリゼーション・サポート変数として定義すると、その変数の外部データ型に応じて、次の空白埋込みおよび空白削除の規則が適用されます。詳細は「文字データの処理」を参照してください。

CHARF: 入力データから、後続のダブルバイトの空白文字が削除されます。ただし、文字列がマルチバイト空白文字のみで構成されている場合は、標識としてマルチバイトの空白文字が1つバッファに残されます。

出力ホスト変数には、マルチバイトの空白が埋め込まれます。

VARCHAR.入力時に、ホスト変数からは後続のダブルバイト空白文字が削除されません。lengthコンポーネントは、バイト単位ではなく文字単位のデータの長さとみなされます。

出力では、ホスト変数には空白は埋め込まれません。バッファの長さは、バイト単位ではなく文字単位のデータの長さに設定されます。

STRING/LONG VARCHAR: これらのホスト変数は、グローバリゼーション・サポート・データには対応していません。これらのホスト変数を指定するには動的SQLまたはデータ型の同値化を使用する必要がありますが、グローバリゼーション・サポート・データはそのどちらにも対応していないためです。

標識変数

マルチバイトのグローバリゼーション・サポート文字変数でも、他の変数の場合と同様に、標識変数を使用できますが、列の長さの値はバイト単位ではなく文字単位で表されます。使用可能な値の一覧は、「標識変数の使用方法」を参照してください。

PIC X/PIC N変数とNCHAR/CHAR列の様々な組合せ

Pro*COBOLでは、コマンドライン・オプションcharset_picxおよびcharset_picnによるSELECT、INSERTおよびUPDATE文でのPIC X /PIC N変数とNCHAR/CHAR列の様々な組合せがサポートされています。

PIC XとNCHAR列

デフォルトでは、PIC X変数は、CHAR列で使用できるようにサーバー側のデータベース・キャラクタ・セットに変換されます。したがって、NCHAR列でPIC X変数を使用すると、一部のデータが失われる可能性があります。これを回避するには、次のコマンドを使用して、PIC X変数で使用するキャラクタ・セットの形式をNCHARに設定します。

charset_picx=nchar_charset

PIC NとCHAR列

デフォルトでは、PIC N変数は、CHAR列で使用できるようにサーバー側の各国語キャラクタ・セットに変換されます。したがって、NCHAR列でPIC N変数を使用すると、パフォーマンスに影響を及ぼす可能性があります。これを回避するには、次のコマンドを使用して、PIC N変数で使用するキャラクタ・セットの形式をCHARに設定します。

charset_picn=db_charset

CHARSET_PICXおよびCHARSET_PICNの詳細は、「Pro*COBOLプリコンパイラ・オプションの使用」を参照してください。

新しいオプションの使用方法

次の表に、新しいオプションの使用方法を示します。

- ホスト変数: ホスト変数のタイプ

- DBの列のタイプ: CHAR/NCHAR

- charset_picx: charset_picxオプションの値

- charset_picn: charset_picnオプションの値

- NLS_NCHAR: NLS_NCHARの値

- データのキャラクタ・セット: ホスト変数のキャラクタ・セット

ホスト変数

DBの列のタイプ

charset_picx

charset_picN

NLS_NCHAR

データのキャラクタ・セット

PIC X

CHAR

nchar_charset

-

設定

NLS_NCHAR

db_charset

-

設定

NLS_LANG

nchar_charset

-

未設定

NLS_LANG

db_charset

-

未設定

NLS_LANG

NCHAR

nchar_charset

-

設定

NLS_NCHAR

db_charset

-

設定

NLS_LANG

nchar_charset

-

未設定

NLS_LANG

db_charset

-

未設定

NLS_LANG

PIC N

CHAR

-

nchar_charset

設定

NLS_NCHAR

-

db_charset

設定

NLS_NCHAR

NCHAR

-

nchar_charset

未設定

NLS_LANG

-

db_charset

未設定

NLS_LANG

-

nchar_charset

設定

NLS_NCHAR

-

db_charset

設定

NLS_NCHAR

-

nchar_charset

未設定

NLS_LANG

-

db_charset

未設定

NLS_LANG

データ型変換

プリコンパイル時に、各ホスト変数に外部データ型が割り当てられます。たとえば、Pro*COBOLはPIC S9(n) COMP型のホスト変数にINTEGER外部データ型を割り当てます。SQL文で使用するすべてのホスト変数のデータ型コードは、実行時にOracleに渡されます。Oracleは、コードを使用して内部データ型と外部データ型の間で変換します。

Oracleは、SELECTした列値を出力ホスト変数に割り当てる前に、必ずソース列の内部データ型をホスト変数のデータ型に変換します。同様に、入力ホスト変数の値の、列への割当てまたは比較を行う場合は、その前に必ずホスト変数の外部データ型をターゲット列の内部データ型に変換します。

内部データ型と外部データ型との変換は、通常のデータ変換規則に従って行われます。たとえば、CHAR値1234はPIC S9(4) COMP値に変換できます。ただし、CHAR値123465543 (大きすぎる数)や10F (10進数ではない数)をPIC S9(4) COMP値に変換することはできません。同様に、アルファベット文字を含むPIC X(n)値はNUMBER値に変換できません。

ホスト変数のデータ型は、データベース列のデータ型と互換性が必要です。必ず、変換可能な値を指定してください。たとえば、文字列値YESTERDAYをDATE列値に変換しようとすると、エラーが発生します。内部データ型と外部データ型との変換は、通常のデータ変換規則に従って行われます。たとえば、CHAR値1234を2バイトの整数に変換できます。しかし、CHAR値65543(大きすぎる数)や10F(10進数ではない数)を2バイトの整数に変換することはできません。同様に、アルファベット文字を含む文字列値はNUMBER値に変換できません。

数値の変換は、Oracle初期化ファイルのグローバリゼーション・サポート・パラメータで指定された規則に従って行われます。たとえば、ピリオド(.)ではなくカンマ(,)を小数点として認識するようにシステムが構成されている場合があります。グローバリゼーション・サポートの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。

次の表は、サポートされている内部データ型と外部データ型の間での変換を示します。

表4-9 内部データ型と外部データ型の間での変換

外部

内部

-

-

-

-

-

-

-

CHAR

I/O

I/O(2)

I/O

I (3)

I/O

I/O(3)

I/O(1)

CHARF

I/O

I/O(2)

I/O

I(3)

I/O

I/O(3)

I/O(1)

CHARZ

I/O

I/O(2)

I/O

I(3)

I/O

I/O(3)

I/O(1)

DATE

I/O

I/O

I

-

-

-

--

DECIMAL

I/O(4)

-

I

-

-

I/O

-

-

DISPLAY

I/O (4)

-

I

-

-

I/O

-

-

FLOAT

I/O(4)

-

I

-

-

I/O

-

-

INTEGER

I/O(4)

-

I

-

-

I/O

-

-

LONG

I/O

I/O(2)

I/O

I (3、5)

-

I/O

I/O(3)

I/O(1)

LONG RAW

O (6)

-

I (5、6)

I/O

-

-

I/O

-

LONG VARCHAR

I/O

I/O (2)

I/O

I (3、5)

-

I/O

I/O (3)

I/O(1)

LONG VARRAW

I/O(6)

-

I (5、6)

I/O

-

-

I/O

-

NUMBER

I/O(4)

-

I

-

-

I/O

-

-

RAW

I/O(6)

-

I (5、6)

I/O

-

-

I/O

-

ROWID

I

-

I

-

-

-

-

I/O

STRING

I/O

I/O(2)

I/O

I (3、5)

-

I/O

I/O(3)

I/O(1)

UNSIGNED

I/O(4)

-

I

-

-

I/O

-

-

VARCHAR

I/O

I/O(2)

I/O

I (3、5)

-

I/O

I/O(3)

-

VARCHAR2

I/O

I/O(2)

I/O

I(3)

-

I/O

I/O(3)

I/O(1)

VARNUM

I/O(4)

-

I

-

-

I/O

-

-

VARRAW

I/O(6)

-

I (5、6)

I/O

-

-

I/O

-

前述の表の値の意味は、次のとおりです。

- I = 入力のみ

- O = 出力のみ

- I/O = 入出力

注意:
入力時には、ホスト文字列をOracle'BBBBBBBB.RRRR.FFFF'の形式にする必要があります。
出力時には、列値は同じ形式で戻されます。

入力時には、ホスト文字列をデフォルトのDATE文字形式にする必要があります。

出力時には、列値は同じ形式で戻されます。

入力時には、ホスト文字列を16進フォーマットにする必要があります。

出力時には、列値は同じ形式で戻されます。

出力時には、列値は有効な数値を表している必要があります。

入力時には、長さが2000以下であることが必要です。

DATE文字列フォーマットの明示的な制御

Oracleでは、DATE列値を選択して文字ホスト変数に格納する場合、内部バイナリ値を外部文字値に変換する必要があります。このため、デフォルトの日付書式で文字列を戻すSQL関数TO_CHARが暗黙的にコールされます。デフォルトの日付書式は、Oracleの初期化パラメータNLS_DATE_FORMATで設定します。時刻やユリウス暦の日付などのその他の情報を取得するには、書式マスクを指定して明示的にTO_CHARをコールする必要があります。

文字ホスト値をDATE列に挿入する際にも変換が必要です。Oracleは、デフォルトの日付書式を予期するSQL関数TO_DATEを暗黙的にコールします。その他の書式の日付を挿入する場合は、書式マスクを指定して明示的にTO_DATEをコールする必要があります。

Pro*COBOLには、他のバージョンのSQLとの互換性を保証するために、次のような日付文字列を指定するためのプリコンパイラ・オプションが用意されています。

DATE_FORMAT={ISO | USA | EUR | JIS | LOCAL | 'fmt'

DATE_FORMATオプションは、コマンドラインまたは構成ファイル内で指定する必要があります。指定できる日付文字列を次の表に示します。

表4-10 日付文字列用の書式

書式名

略称

日付書式

国際標準化機構規格

ISO

yyyy-mm-dd

USA標準

USA

mm/dd/yyyy

ヨーロッパ標準

EUR

dd.mm.yyyy

日本工業規格

JIS

yyyy-mm-dd

インストール定義

LOCAL

インストール時に定義した任意の書式。

'fmt'は、'Month dd, yyyy'などの日付書式モデルです。日付書式モデル要素の一覧は、『Oracle Database SQL言語リファレンス』を参照してください。個別にコンパイルした単位を後でリンクする場合、すべての単位が同じDATE_FORMAT値を使用している必要があります。

データ型の同値化

データ型の同値化により、Oracleで入力データを解釈する方法と出力データの書式を設定する方法を制御できます。対応しているCOBOLのデータ型は、変数単位で外部データ型に同値化できます。

同値化の有用性

データ型の同値化には、いくつかの利点があります。たとえば、COBOLプログラムで 可変長文字列を使用するとします。PIC Xホスト変数を宣言した後に、これを外部データ型VARCHAR2に同値化できます。

また、デフォルトのデータ型変換を変更する場合に、データ型の同値化を使用できます。初期化ファイルのグローバリゼーション・サポート・パラメータで特に指定されていない場合、DATE列値を選択して文字ホスト変数に入れると、Oracleは次のような書式の9バイトの文字列を戻します。

DD-MON-YY

文字ホスト変数をDATE外部データ型に同値化すると、Oracleは内部形式の7バイトの値を戻します。

ホスト変数の同値化

デフォルトでは、Pro*COBOLはすべてのホスト変数に特定の外部データ型を割り当てます。デフォルトの割当ては、ホスト変数を外部データ型に同値化することによって変更できます。これをホスト変数の同値化と呼びます。

VAR埋込みSQL文の構文は、次のとおりです。

EXEC SQL
VAR host_variable IS datatype [CONVBUFSZ [IS] (size)]
END-EXEC

または

EXEC SQL VAR host_variable [CONVBUFSZ [IS] (size)] END-EXEC

この場合、datatypeは次のとおりです。

SQL datatype [ ( {length | precision, scale } ) ]

この2つの句のどちらか1つまたは両方を必ず指定する必要があります。

パラメータは次のとおりです。

表4-11 ホスト変数の同値化

変数

説明

precisionおよびscale

それぞれ有効桁数と四捨五入が実行される点を表す整数リテラル。たとえば位取りが2のときは、1/100の倍数の近似値に値が四捨五入される(3.456は3.46になる)ことを意味します。また位取りが-3のときは、1000の倍数の近似値に値が四捨五入される(3456が3000になる)ことを意味します。

1から99までのprecisionおよび-84から99までのscaleを指定できます。ただし、データベース列の精度および位取りの最大値は、それぞれ38と127です。したがって、precisionが38を超えていると、host_variableの値はデータベース列に挿入できません。一方、列値の位取りが99を超えていると、host_variableに入れる値の選択もフェッチもできません。

precisionおよびscaleは、type_nameがDECIMALまたはDISPLAYの場合にのみ指定してください。

length

前に宣言された入力または出力ホスト変数(あるいはホスト表)。

VARCHARおよびVARRAW外部データ型が2バイト長のフィールドで、nバイトのデータ・フィールドが続く場合、nの値の範囲は1から65533になります。そのため、type_nameがVARCHARまたはVARRAWの場合、host_variableには少なくとも3バイトの長さが必要です。

LONG VARCHARおよびLONG VARRAW外部データ型が4バイト長のフィールドで、nバイトのデータ・フィールドが続く場合、nの値の範囲は1から2147483643になります。そのため、type_nameがLONG VARCHARまたはLONG VARRAWの場合、host_variableには少なくとも5バイトの長さが必要です。

size

指定したhost_variableから別のキャラクタ・セットへの変換に使用するバッファのサイズ(バイト数)を示す整数。

SQL datatype

RAW、STRINGなどの有効な外部データ型の名前。

host_variable

前に宣言された入力または出力ホスト変数あるいはホスト表。

VARCHARおよびVARRAW外部データ型が2バイト長のフィールドで、nバイトのデータ・フィールドが続く場合、nの値の範囲は1から65533になります。そのため、type_nameがVARCHARまたはVARRAWの場合、host_variableには少なくとも3バイトの長さが必要です。

LONG VARCHARおよびLONG VARRAW外部データ型が4バイト長のフィールドで、nバイトのデータ・フィールドが続く場合、nの値の範囲は1から2147483643になります。そのため、type_nameがLONG VARCHARまたはLONG VARRAWの場合、host_variableには少なくとも5バイトの長さが必要です。

表4-12に、各外部データ型に使用するパラメータを示します。

CONVBUFSZ句の詳細は、「VAR文のCONVBUFSZ句」を参照してください。

NCHARホスト変数(PIC GまたはPIC N句を含む変数)には、EXEC SQL VARは使用できません。

DECLARE_SECTION=TRUEの場合は宣言部が必要であり、また、宣言部にEXEC SQL VAR文を記述する必要があります。

この文の構造図は、「VAR (Oracle埋込みSQLディレクティブ)」を参照してください。

ext_type_nameがFLOATの場合はlengthを指定してください。ext_type_nameがDECIMALの場合は、lengthではなく、precisionおよびscaleを指定してください。

ホスト変数の同値化には、いくつかの利点があります。たとえば、Oracleにデータを格納するが解析は行わない場合に、ホスト変数の同値化を利用できます。4バイトの整数からなるホスト表をRAWデータベース列に格納するとします。この場合は、次に示すように、ホスト表をRAW外部データ型に同値化します。

WORKING-STORAGE SECTION.
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  EMP-TABLES.
05  EMP-NUMBER  PIC S9(4) COMP OCCURS 50 TIMES.
...
*    Reset default datatype (INTEGER) to RAW.
EXEC SQL VAR EMP-NUMBER IS RAW (200) END-EXEC.
EXEC SQL END DECLARE SECTION END-EXEC.

ホスト表を使用する場合、指定したlengthは表を保持するのに必要なバッファ・サイズと一致する必要があります。最後の例では、lengthに200を指定しています。これは50個の4バイト整数に必要なバッファ・サイズです。

使用するグループ項目をLONG VARCHARとして宣言することもできます。

01  MY-LONG-VARCHAR.
05 UC-LEN PIC S9(9) COMP.
05 UC-ARR PIC X(6000).
EXEC SQL VAR MY-LONG-VARCHAR IS LONG VARCHAR(6000).

VAR文のCONVBUFSZ句

EXEC SQL VAR文には、オプションのCONVBUFSZ句を使用できます。指定したホスト変数のキャラクタ・セット間での変換に使用する、ランタイム・ライブラリ内のバッファのサイズ(バイト数)を指定します。

CONVBUFSZ句を指定しないと、ランタイム・ライブラリが、ホスト変数のキャラクタ・サイズ(NLS_LANGで判別)とデータベース・キャラクタ・セットのキャラクタ・サイズとの割合でバッファ・サイズを自動的に決定します。これによって、LONGサイズのバッファが作成されることがあります。データベースでは、LONG列を1つしか指定できません。複数のLONG値が指定されると、エラーとなります。

このようなエラーを回避するには、LONGのサイズよりも短い長さを使用します。キャラクタ・セットの変換の結果、CONVBUFSZで指定される長さよりも長い値になった場合、Pro*COBOLはエラーを戻します。

例

EMP表から従業員の名前を選択して、ヌル文字で終了した文字列を要求するC言語のルーチンに渡すとします。これらの名前に、明示的にヌル終端文字を付ける必要はありません。次のように、ホスト変数をSTRING外部データ型に同値化するのみです。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01   EMP-NAME  PIC X(11).
EXEC SQL VAR EMP-NAME IS STRING (11) END-EXEC.
EXEC SQL END DECLARE SECTION END-EXEC.

ENAME列の幅は10文字のため、ヌル終端文字を含めるために新しいEMP-NAMEには11文字を割り当てます。(lengthのデフォルト値はホスト変数の長さのため、lengthの指定は任意です。)ENAME列から値を選択してEMP-NAMEに入れると、その値はOracleによってヌル文字で終了にされます。

表4-12 ホスト変数を同値化するためのパラメータ

外部データ型

長さ

精度

位取り

デフォルトの長さ

CHAR

オプション

該当なし

該当なし

変数の宣言長

CHARZ

オプション

該当なし

該当なし

変数の宣言長

DATE

該当なし

該当なし

該当なし

7バイト

DECIMAL

該当なし

必須

必須

なし

DISPLAY

該当なし

必須

必須

なし

DISPLAY TRAILING

該当なし

必須

必須

なし

UNSIGNED DISPLAY

該当なし

必須

必須

なし

OVERPUNCH TRAILING

該当なし

必須

必須

なし

OVERPUNCH LEADING

該当なし

必須

必須

なし

FLOAT

オプション(4または8)

該当なし

該当なし

変数の宣言長

INTEGER

オプション(1、2、4または8)

該当なし

該当なし

変数の宣言長

LONG

オプション

該当なし

該当なし

変数の宣言長

LONG RAW

オプション

該当なし

該当なし

変数の宣言長

LONG VARCHAR

必須(注意1)

該当なし

該当なし

なし

LONG VARRAW

必須(注意1)

該当なし

該当なし

なし

NUMBER

該当なし

該当なし

該当なし

該当なし

STRING

オプション

該当なし

該当なし

変数の宣言長

RAW

オプション

該当なし

該当なし

変数の宣言長

ROWID

該当なし

該当なし

該当なし

18バイト(注意2)

UNSIGNED

オプション(1、2または4)

該当なし

該当なし

変数の宣言長

VARCHAR

必須

該当なし

該当なし

なし

VARCHAR2

オプション

該当なし

該当なし

変数の宣言長

VARNUM

該当なし

該当なし

該当なし

22バイト

VARRAW

オプション

該当なし

該当なし

なし

1. データ・フィールドが65533バイトを超える場合は、-1を渡します。

2. 一般的な値ですが、デフォルトはポートによって異なります。

CHARFデータ型指定子の使用方法

VAR文でデータ型指定子CHARFを使用すると、COBOLのデータ型を固定長のANSIデータ型CHARに同値化できます。

PICX=CHARFの場合は、VAR文でデータ型CHARを指定すると、ホスト言語のデータ型は固定長のANSIデータ型CHAR (Oracleの外部データ型コード96)に同値化されます。PICX=VARCHAR2の場合は、ホスト言語のデータ型は可変長のデータ型VARCHAR2 (コード1)に同値化されます。

ホスト言語のデータ型をいつでも固定長のANSIデータ型CHARに同値化できます。これには、VAR文でデータ型CHARFを指定します。CHARFを使用すると、PICX=VARCHAR2に設定されている場合でも、ホスト言語のデータ型は固定長のANSIデータ型CHARに同値化されます。

ガイドライン

VARNUM値およびDATE値は、必ずOracleの内部形式で入力してください。Oracleは、VARNUM値およびDATE値の出力には内部形式を使用します。

列値を選択してVARNUMホスト変数に格納した後、先頭バイトをチェックして値の長さを調べることができます。表4-1に、戻されるVARNUM値の例を示します。

表4-13 VARNUMの例

10進数

長さバイト

指数バイト

仮数バイト

終了文字バイト

5

2

193

6

該当なし

-5

3

62

96

102

2767

3

194

28, 68

該当なし

-2767

4

61

74, 34

102

100000

2

195

11

該当なし

1234567

5

196

2, 24, 46, 68

該当なし

DATE値の変換ついては、「DATE文字列フォーマットの明示的な制御」を参照してください。

必要とするOracleの外部データ型がない場合は、VARCHAR2ベースまたはRAWベースの外部データ型を使用してください。

RAWおよびLONG RAWの値

Oracleでは、RAW列値またはLONG RAW列値を選択して文字ホスト変数に格納する場合、内部バイナリ値を外部文字値に変換する必要があります。この場合、OracleはRAWデータまたはLONG RAWデータの各バイナリ・バイトを文字のペアとして戻します。個々の文字は、ニブル(1/2バイト)の等価の16進値を表します。たとえば、バイナリ・バイト11111111は文字のペア「FF」として戻されます。SQL関数RAWTOHEXはこれと同じ変換を実行します。

文字ホスト値をRAW列またはLONG RAW列に挿入するときも変換が必要です。ホスト変数内の文字のペアはそれぞれ、バイナリ・バイトの等価の16進値を表している必要があります。文字がニブルの16進値を表していない場合、Oracleはエラー・メッセージを発行します。

データ型変換の詳細は、「サンプル・プログラム4: データ型の同値化」を参照してください。

プラットフォームのエンディアン形式のサポート

Oracleでは、Unicodeデータ(UTF16)は、常にビッグ・エンディアン形式で格納されます。現在、クライアント・アプリケーションは様々なプラットフォームで実行されます。LinuxおよびWindowsではリトル・エンディアン形式が、Solarisではビッグ・エンディアン形式が使用されています。Pro*Cobolでは、UTF16のデータが挿入または選択されると、サーバーとクライアント間のエンディアン形式が変換されません。このため、PIC N変数のUTF16 (UCS2)の文字列が破損します。

コマンドライン・オプションpicn_endianを使用すると、PIC N変数のプラットフォームのエンディアン形式(LinuxおよびWindowsの場合はリトル・エンディアン形式、Solarisの場合はビッグ・エンディアン形式)を保持できます。

新しいコマンドライン・オプション

picn_endian={BIG|OS}

picn_endian=bigの場合、PIC N変数はキャラクタ・セットID AL16UTF16にバインドされます。

picn_endian=osの場合、PIC N変数はキャラクタ・セットID UCS2にバインドされます。

このオプションのデフォルト値は「big」で、現行の動作が保持されます。NLS_NCHARがAL16UTF16でない場合、このオプションは無視されます。

PIC N変数のキャラクタ・セットの形式は、既存のPro*Cobolコマンドライン・オプションを使用して設定できます。

charset_picn={nchar_charset|db_charset}

PICN_ENDIAN=OSの場合のvarcharホスト変数の詳細は、「可変長変数」を参照してください。

サンプル・プログラム4: データ型の同値化

次のプログラムは、Oracleに接続した後、SCOTTアカウントにIMAGEの名前のデータベースの表を作成し、この表への従業員番号のビットマップ・イメージの挿入をシミュレートします。データ型の同値化により、このプログラムはOracle外部データ型LONG RAWを使用してビットマップ・イメージを表現できます。後でユーザーが従業員番号を入力すると、その番号のビットマップがIMAGE表から選択され、端末の画面に表示されます。

* This program simulates the storage and retrieval of bitmap images into table
* IMAGE, which is created in the SCOTT account after logging on to ORACLE.
* Datatype equivalencing allows an ORACLE external type of LONG RAW to be
* specified for the programs representation of the images.

IDENTIFICATION DIVISION.
PROGRAM-ID. DTY-EQUIV.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME          PIC X(10) VARYING.
01  PASSWD            PIC X(10) VARYING.
01  EMP-REC-VARS.
05  EMP-NUMBER    PIC S9(4) COMP.
05  EMP-NAME      PIC X(10) VARYING.
05  SALARY        PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
05  COMMISSION    PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
05  COMM-IND      PIC S9(4) COMP.

EXEC SQL VAR SALARY IS DISPLAY(8,2) END-EXEC.
EXEC SQL VAR COMMISSION IS DISPLAY(8,2) END-EXEC.

01  BUFFER-VAR.
05  BUFFER        PIC X(8192).
EXEC SQL VAR BUFFER IS LONG RAW END-EXEC.

01  INEMPNO           PIC S9(4) COMP.
EXEC SQL END DECLARE SECTION END-EXEC.
EXEC SQL INCLUDE SQLCA END-EXEC.

01  DISPLAY-VARIABLES.
05  D-EMP-NAME    PIC X(10).
05  D-SALARY      PIC $Z(4)9.99.
05  D-COMMISSION  PIC $Z(4)9.99.
05  D-INEMPNO     PIC 9(4).
01  REPLY             PIC X(10).
01  INDX              PIC S9(9) COMP.
01  PRT-QUOT          PIC S9(9) COMP.
01  PRT-MOD           PIC S9(9) COMP.

PROCEDURE DIVISION.

BEGIN-PGM.
EXEC SQL WHENEVER SQLERROR
DO PERFORM SQL-ERROR END-EXEC.

PERFORM LOGON.
DISPLAY "OK TO DROP THE IMAGE TABLE? (Y/N)  "
WITH NO ADVANCING.

ACCEPT REPLY.

IF (REPLY NOT = "Y") AND (REPLY NOT = "y")
GO TO SIGN-OFF-EXIT.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL DROP TABLE IMAGE END-EXEC.
DISPLAY " ".
IF (SQLCODE = 0) DISPLAY
"TABLE IMAGE DROPPED - CREATING NEW TABLE."
ELSE IF (SQLCODE = -942) DISPLAY
"TABLE IMAGE DOES NOT EXIST - CREATING NEW TABLE."
ELSE PERFORM SQL-ERROR.
EXEC SQL WHENEVER SQLERROR
DO PERFORM SQL-ERROR END-EXEC.
EXEC SQL CREATE TABLE IMAGE
(EMPNO NUMBER(4) NOT NULL, BITMAP LONG RAW)
END-EXEC.
EXEC SQL DECLARE EMPCUR CURSOR FOR
SELECT EMPNO, ENAME FROM EMP
END-EXEC.
EXEC SQL OPEN EMPCUR END-EXEC.
DISPLAY " ".
DISPLAY
"INSERTING BITMAPS INTO IMAGE FOR ALL EMPLOYEES ...".
DISPLAY " ".

INSERT-LOOP.
EXEC SQL WHENEVER NOT FOUND GOTO NOT-FOUND END-EXEC.
EXEC SQL FETCH EMPCUR
INTO :EMP-NUMBER, :EMP-NAME
END-EXEC.
MOVE EMP-NAME-ARR TO D-EMP-NAME.
DISPLAY "EMPLOYEE ", D-EMP-NAME WITH NO ADVANCING.
PERFORM GET-IMAGE.
EXEC SQL INSERT INTO IMAGE
VALUES (:EMP-NUMBER, :BUFFER)
END-EXEC.
DISPLAY " IS DONE!".
MOVE SPACES TO EMP-NAME-ARR.
GO TO INSERT-LOOP.

NOT-FOUND.
EXEC SQL CLOSE EMPCUR END-EXEC.
EXEC SQL COMMIT WORK END-EXEC.
DISPLAY " ".
DISPLAY
"DONE INSERTING BITMAPS.  NEXT, LET'S DISPLAY SOME.".

DISP-LOOP.
MOVE 0 TO INEMPNO.
DISPLAY " ".
DISPLAY "ENTER EMPLOYEE NUMBER (0 TO QUIT):  "
WITH NO ADVANCING.

ACCEPT D-INEMPNO.

MOVE D-INEMPNO TO INEMPNO.
IF (INEMPNO = 0)
GO TO SIGN-OFF.
EXEC SQL WHENEVER NOT FOUND GOTO NO-EMP END-EXEC.
EXEC SQL SELECT EMP.EMPNO, ENAME, SAL, NVL(COMM, 0), BITMAP
INTO :EMP-NUMBER, :EMP-NAME, :SALARY,
:COMMISSION:COMM-IND, :BUFFER
FROM EMP, IMAGE
WHERE EMP.EMPNO = :INEMPNO
AND EMP.EMPNO = IMAGE.EMPNO
END-EXEC.
DISPLAY " ".
PERFORM SHOW-IMAGE.
MOVE EMP-NAME-ARR TO D-EMP-NAME.
MOVE SALARY TO D-SALARY.
MOVE COMMISSION TO D-COMMISSION.
DISPLAY "EMPLOYEE ", D-EMP-NAME, " HAS SALARY ", D-SALARY
WITH NO ADVANCING.
IF COMM-IND = -1
DISPLAY " AND NO COMMISSION."
ELSE
DISPLAY " AND COMMISSION ", D-COMMISSION, "."
END-IF.
MOVE SPACES TO EMP-NAME-ARR.
GO TO DISP-LOOP.

NO-EMP.
DISPLAY "NOT A VALID EMPLOYEE NUMBER - TRY AGAIN.".
GO TO DISP-LOOP.

LOGON.
MOVE "SCOTT" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "TIGER" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE AS USER:  ", USERNAME-ARR.
DISPLAY " ".

GET-IMAGE.
PERFORM MOVE-IMAGE
VARYING INDX FROM 1 BY 1 UNTIL INDX > 8192.

MOVE-IMAGE.
STRING '*' DELIMITED BY SIZE
INTO BUFFER
WITH POINTER INDX.
DIVIDE 256 INTO INDX
GIVING PRT-QUOT REMAINDER PRT-MOD.
IF (PRT-MOD = 0) DISPLAY "." WITH NO ADVANCING.

SHOW-IMAGE.
PERFORM VARYING INDX FROM 1 BY 1 UNTIL INDX > 10
DISPLAY "               *************************"
END-PERFORM.
DISPLAY " ".

SIGN-OFF.
EXEC SQL DROP TABLE IMAGE END-EXEC.
SIGN-OFF-EXIT.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY.".
DISPLAY " ".
EXEC SQL COMMIT WORK RELEASE END-EXEC.
STOP RUN.

SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:  ".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

5 埋込みSQL

この章では、埋込みSQLプログラムの基本的な方法を説明します。内容は次のとおりです。

- ホスト変数の使用方法

- 標識変数の使用方法

- 基本的なSQL文

- カーソル

- スクロール可能カーソル

- B領域の長さの柔軟性

- 固定実行計画

- サンプル・プログラム2: カーソル操作

ホスト変数の使用方法

データベースからプログラムにデータおよびステータス情報を渡すとき、またデータベースにデータを渡すときには、ホスト変数を使用します。

出力ホスト変数および入力ホスト変数

ホスト変数は、使用方法によって出力ホスト変数または入力ホスト変数と呼ばれます。SELECT文またはFETCH文のINTO句内のホスト変数は、Oracleによって出力される列の値が入るため出力ホスト変数と呼ばれます。Oracleは、列の値をINTO句内の対応する出力ホスト変数に割り当てます。

SQL文のその他のホスト変数の値は、プログラムがそれをOracleに入力するため、すべて入力ホスト変数と呼ばれます。たとえば、INSERT文のVALUES句内およびUPDATE文のSET句内では入力ホスト変数を使用します。入力ホスト変数はWHERE句、HAVING句およびFOR句内でも使用されます。実際、入力ホスト変数は、SQL文内で値または式を使用できる位置であればどこにでも使用できます。

入力ホスト変数は、SQLキーワードまたはデータベース・オブジェクトの名前を指定するためには使用できません。つまり、ALTER、CREATEおよびDROPなどのデータ定義文(DDLとも呼ばれます)では入力ホスト変数を使用できません。次の例のDROP TABLE文は無効です。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 TABLE-NAME    PIC X(30) VARYING.
...
EXEC SQL END DECLARE SECTION END-EXEC.
...
DISPLAY 'Table name? '.
ACCEPT TABLE-NAME.
EXEC SQL DROP TABLE :TABLE-NAME END-EXEC.
*  -- host variable not allowed

注意:
ORDER BY句ではホスト変数が使用できますが、定数またはリテラルとして扱われるのでホスト変数の内容は無効になります。たとえば、次のようなSQL文があるとします。

EXEC SQL SELECT ENAME, EMPNO INTO :NAME, :NUMBER
FROM EMP
ORDER BY :ORD
END-EXEC.

この文では、入力ホスト変数ORDが使用されていますが、この場合のホスト変数は定数として扱われます。そのため、ORDの値が何であっても順序付けは行われません。

入力ホスト変数を含むSQL文をOracleで実行する前に、それらの入力ホスト変数に値を割り当てる必要があります。次の例を考えてみます。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01     EMP-NUMBER   PIC S9(4) COMP.
01     EMP-NAME     PIC X(20) VARYING.
EXEC SQL END DECLARE SECTION END-EXEC.
...
* -- get values for input host variables
DISPLAY 'Employee number? '.
ACCEPT EMP-NUMBER.
DISPLAY 'Employee name? '.
ACCEPT EMP-NAME.
EXEC SQL INSERT INTO EMP (EMPNO, ENAME)
VALUES (:EMP-NUMBER, :EMP-NAME)
END-EXEC.

INSERT文のVALUES句内で入力ホスト変数の前にコロンが付いていることに注意してください。

標識変数の使用方法

任意のホスト変数に任意指定の標識変数を関連付けることができます。標識変数に関連付けたホスト変数をSQL文内で使用するたびに、結果コードが対応する標識変数内に格納されます。つまり、標識変数によってホスト変数を監視できます。

VALUES句またはSET句中の標識変数を使用して、入力ホスト変数にNULLを割り当てたり、INTO句中の標識変数を使用して、出力ホスト変数内のNULLまたは切り捨てられた値を検出できます。

入力変数

入力ホスト変数の場合、プログラムが標識変数に割り当てる値の意味は次のとおりです。

変数

意味

-1

Oracleによって、その列にNULLが割り当てられます。このホスト変数の値は無視されます。

>= 0

Oracleによって、このホスト変数の値が列に割り当てられます。

出力変数

出力ホスト変数の場合、Oracleが標識変数に割り当てる値の意味は次のとおりです。

変数

意味

-2

列の値を切り捨ててホスト変数に割り当てましたが、数値が大きすぎるため、元の長さのまま標識変数に割り当てられませんでした。

-1

この列の値はNULLです。したがって、このホスト変数の値は予測不能です。

0

列の値がそのままこのホスト変数に割り当てられました。

> 0

列の値を切り捨ててホスト変数に割り当てました。列の元の長さ(マルチバイト・グローバリゼーション・サポートのホスト変数では、バイト数ではなく文字数で表される)を標識変数に割り当て、SQLCA内のSQLCODEを0 (ゼロ)に設定しました。

標識変数は、2バイトの整数として宣言する必要があります。また、SQL文中では、標識変数の前にコロンを付けてホスト変数の直後に置く必要があります(キーワードINDICATORを使用しない場合)。

NULLの挿入

標識変数を使用して、NULLを挿入できます。挿入の前に、次に示すように、NULLにする列に対応する標識変数をそれぞれ-1に設定します。

MOVE -1 TO IND-COMM.
EXEC SQL INSERT INTO EMP (EMPNO, COMM)
VALUES (:EMP-NUMBER, :COMMISSION:IND-COMM)
END-EXEC.

標識変数IND-COMMにより、COMM列にNULLを入れるように指定されます。

次のように、NULLをハードコードにすることもできます。

EXEC SQL INSERT INTO EMP (EMPNO, COMM)
VALUES (:EMP-NUMBER, NULL)
END-EXEC.

しかし、この方法は柔軟性がありません。

一般的には、次の例に示すように条件的にNULLを挿入します。

DISPLAY 'Enter employee number or 0 if not available: '
WITH NO ADVANCING.
ACCEPT EMP-NUMBER.
IF EMP-NUMBER = 0
MOVE -1 TO IND-EMPNUM
ELSE
MOVE 0 TO IND-EMPNUM
END-IF.
EXEC SQL INSERT INTO EMP (EMPNO, SAL)
VALUES (:EMP-NUMBER:IND-EMPNUM, :SALARY)
END-EXEC.

戻されたNULLの処理

標識変数を使用すると、次の例に示すように、戻されたNULLを操作することもできます。

EXEC SQL SELECT ENAME, SAL, COMM
INTO :EMP-NAME, :SALARY, :COMMISSION:IND-COMM
FROM EMP
WHERE EMPNO = :EMP_NUMBER
END-EXEC.
IF IND-COMM = -1
MOVE SALARY TO PAY.
*   -- commission is null; ignore it
ELSE
ADD SALARY TO COMMISSION GIVING PAY.
END-IF.

NULLのフェッチ

プリコンパイラ・オプションUNSAFE_NULL=YESと設定されている場合は、次の例に示すように、標識変数を持たないホスト変数に対してNULLを選択またはフェッチできます。

* --  assume that commission is NULL
EXEC SQL SELECT ENAME, SAL, COMM
INTO :EMP-NAME, :SALARY, :COMMISSION
FROM EMP
WHERE EMPNO = :EMP-NUMBER
END-EXEC.

SQLCA内のSQLCODEが0 (ゼロ)に設定されます。これは、Oracleがエラーまたは例外を検出せずにその文を実行したことを示します。

標識変数を使用しないと、NULLが戻されたかどうか知ることができません。ホスト変数の値は未定義です。標識変数を使用しない場合は、プリコンパイラ・オプションUNSAFE_NULLをYESに設定してください。したがって、既存のプログラムをアップグレードするときにのみUNSAFE_NULL=YESに設定し、新規プログラムに対しては常に標識変数を使用することをお薦めします。

ただしUNSAFE_NULL=NOの場合は、標識変数を持たないホスト変数に対してNULLを選択またはフェッチすると、エラー・メッセージが発行されます。

詳細は、「UNSAFE_NULL」を参照してください。

NULLのテスト

次の例のようにWHERE句で標識変数を使用して、NULLをテストできます。

EXEC SQL SELECT ENAME, SAL
INTO :EMP-NAME, :SALARY
FROM EMP
WHERE :COMMISSION:IND-COMM IS NULL ...

しかし、関係演算子を使用してNULLとNULL、またはNULLと他の値を比較することはできません。たとえば、COMM列に1つ以上のNULLが含まれる場合、次のSELECT文ではエラーが出力されます。

EXEC SQL SELECT ENAME, SAL
INTO :EMP-NAME, :SALARY
FROM EMP
WHERE COMM = :COMMISSION:IND-COMM
END-EXEC.

次の例は、値のうちのいくつかがNULLである可能性がある場合の、値の等価性を比較する方法を示します。

EXEC SQL SELECT ENAME, SAL
INTO :EMP_NAME, :SALARY
FROM EMP
WHERE (COMM = :COMMISSION) OR ((COMM IS NULL) AND
(:COMMISSION:IND-COMM IS NULL))
END-EXEC.

切り捨てられた値のフェッチ

値がホスト変数にフェッチされる時に切り捨てられた場合、エラーは発生しません。いずれの場合もWARNINGが発生します(see 「警告フラグ」を参照)。標識変数が文字列に使用されている場合、値が切り捨てられたとき、標識変数はデータベース内の値の長さに設定されます。数値が切り捨てられる場合、警告は出ないことに注意してください。

基本的なSQL文

実行SQL文を使用すると、Oracleデータの問合せ、操作および制御ができます。さらに、表、ビューおよび索引などのOracleオブジェクトの作成、定義およびメンテナンスができます。この章では、データベース表のデータを操作する文(DMLと呼ばれることもある)およびカーソル制御文に重点を置いて説明します。

次のSQL文はOracleデータの問合せおよび操作に使用します。

SQL文

説明

SELECT

1つ以上の表から行を戻します。

INSERT

表に新しい行を追加します。

UPDATE

表内の行を変更します。

DELETE

表から行を削除します。

INSERT、UPDATEまたはDELETEなどのDML文を実行する場合は、更新された行数と処理結果を知る必要があります。これは、SQLCAを調べればわかります。(SQL文を実行すると、SQLCA変数が設定されます。)次の2通りの方法で調べることができます。

- WHENEVER文による暗黙的なチェック

- SQLCA変数の明示的なチェック

MODE={ANSI | ANSI14}のときは、状態変数SQLSTATEまたはSQLCODEをチェックすることもできます。詳細は、「ANSI SQLSTATE変数」を参照してください。

ただし、SELECT文(問合せ)を実行している場合は、戻されたデータ行の処理もする必要があります。問合せは次のように分類されます。

- 行を戻さない問合せ(有無のみを調べる)

- 1行のみ戻す問合せ

- 複数行を戻す問合せ

複数行を戻す問合せには、明示的に宣言されたカーソルまたはカーソル変数が必要です。明示カーソルの定義および制御は、次の埋込みSQL文で行います。

SQL文

説明

DECLARE

カーソルに名前を付け、問合せに関連付けます。

OPEN

問合せを実行してアクティブ・セットを決定します。

FETCH

カーソルを移動して、アクティブ・セット内の各行を1つずつ取り出します。

CLOSE

カーソルを使用禁止にします(アクティブ・セットは未定義)。

次の項では、最初にINSERT、UPDATE、DELETEおよび単一行のSELECT文を記述する方法を説明します。次に、複数行のSELECT文の使用方法を説明します。各文およびその句の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

行の選択

データベースへの問合せは日常的なSQL処理です。問合せを発行するには、SELECT文を使用します。次の例では、EMP表を問い合せています。

EXEC SQL SELECT ENAME, JOB, SAL + 2000
INTO :emp_name, :JOB-TITLE, :SALARY
FROM EMP
WHERE EMPNO = :EMP-NUMBER
END-EXEC.

キーワードSELECTの後の列名と式により、選択リストが作成されます。例の選択リストには、3つの項目が含まれています。WHERE句(および存在する場合はそれに続く句)で指定された条件のもと、OracleではINTO句のホスト変数に列値を戻します。選択リスト内の項目数は、INTO句内のホスト変数と同数であり、すべての戻り値を格納する場所があります。

最も簡単な例として、問合せで1行のみ戻される場合の形式は前述の例のようになります(EMPNOは一意のキーです)。これに対し、問合せで複数行が戻される可能性がある場合は、カーソルを使用して行をフェッチするか、行を選択してホスト配列に入れる必要があります。

1行のみ戻すように作成した問合せで、実際には複数の行が戻される可能性がある場合、エラーになるかどうかはオプションSELECT_ERRORの指定によって決まります。SELECT_ERROR=YES (デフォルト)の場合は、複数行が戻されるとOracleはエラー・メッセージを発行します。

SELECT_ERROR=NOの場合は、1行のみ戻され、エラーにはなりません。

使用可能な句

SELECT文では、INTO、FROM、WHERE、CONNECT BY、START WITH、GROUP BY、HAVING、ORDER BYおよびFOR UPDATE OFなどの標準SQL句がすべて使用できます。

行の挿入

INSERT文を使用すると、表またはビューに行を追加できます。次の例では、EMP表に1行追加します。

EXEC SQL INSERT INTO EMP (EMPNO, ENAME, SAL, DEPTNO)
VALUES (:EMP_NUMBER, :EMP-NAME, :SALARY, :DEPT-NUMBER)
END-EXEC.

列リスト内に指定する各列は、INTO句で指定した表に含まれている必要があります。VALUES句には、挿入する行の値を指定します。指定する値は、定数、ホスト変数、SQL式または疑似列(USER、SYSDATEなど)のどの値でもかまいません。

VALUES句内の値の数は、列リスト内の名前の数と等しくする必要があります。CREATE TABLEで定義された順序と同じ順序で表の各列の値がVALUES句に含まれている場合は列リストを省略できますが、表の定義は変更されることがあるため、この方法はお薦めできません。

DML RETURNING句

INSERT、UPDATEおよびDELETE文では、オプションでDML RETURNING句を設定し、標識変数ivを付けて列値の式exprをホスト変数hvに戻すことができます。RETURNING句の構文は次のとおりです。

{RETURNING | RETURN} {expr [,expr]}
INTO {:hv [[INDICATOR]:iv] [, :hv [[INDICATOR]:iv]]}

式の個数は、ホスト変数の個数と等しくする必要があります。この句を使用すると、INSERTまたはUPDATEの後、およびアプリケーションに対して情報を記録する必要がある場合のDELETEの前に、行を選択する必要がなくなります。DML returning clauseによって、ネットワークの非効率的なラウンドトリップ、余分な処理およびサーバーの使用メモリーを低減できます。たとえば、1つのトリガーでデフォルト値または主キー値を挿入できます。

RETURNING句は、副問合せでは使用できません。VALUES句の後でのみ使用できます。

たとえば、前のINSERTの例の最後に次の句を入れることができます。

RETURNING EMPNO, ENAME, DEPTNO INTO :NEW-EMP-NUMBER, :NEW-EMP-NAME, :DEPT

DELETE、INSERTおよびUPDATEのエントリは、付録E「埋込みSQL文およびプリコンパイラ・ディレクティブ」を参照してください。

副問合せの使用方法

副問合せはネストされたSELECT文です。副問合せを使用すると、複数部分の検索を処理できます。副問合せは、次の処理に使用できます。

- SELECT、UPDATEおよびDELETE文のWHERE、HAVINGおよびSTART WITH句内の比較のための値を指定します。

- CREATE TABLEまたはINSERT文によって挿入する行の集合を定義します。

- UPDATE文のSET句に対して値を定義します。

たとえば、ある表から別の表に複数の行をコピーする場合は、次の例に示すように、INSERT文のVALUES句を副問合せに置き換えます。

EXEC SQL INSERT INTO EMP2 (EMPNO, ENAME, SAL, DEPTNO)
SELECT EMPNO, ENAME, SAL, DEPTNO FROM EMP
WHERE JOB = :JOB-TITLE
END-EXEC.

INSERT文が中間結果を得るためにどのように副問合せを使用しているのか注意してください。

行の更新

UPDATE文を使用すると、表またはビュー内の指定した列の値を変更できます。次の例では、EMP表内のSAL列およびCOMM列を更新します。

EXEC SQL UPDATE EMP
SET SAL = :SALARY, COMM = :COMMISSION
WHERE EMPNO = :EMP-NUMBER
END-EXEC.

オプションのWHERE句を使用して、行を更新する条件を指定できます。「WHERE句の使用」を参照してください。

SET句には、値を指定する必要のある1つ以上の列の名前の並びを指定します。次の例に示すように、副問合せを使用すると値を指定できます。

EXEC SQL UPDATE EMP
SET SAL = (SELECT AVG(SAL)*1.1 FROM EMP WHERE DEPTNO = 20)
WHERE EMPNO = :EMP-NUMBER
END-EXEC.

行の削除

DELETE文を使用すると、表またはビューから行を削除できます。次の例では、EMP表から指定した部内の全従業員を削除します。

EXEC SQL DELETE FROM EMP
WHERE DEPTNO = :DEPT-NUMBER
END-EXEC.

オプションのWHERE句を使用して、行を削除する条件を指定できます。

WHERE句の使用

WHERE句を使用すると、表またはビュー内で検索条件を満たす行のみを選択、更新または削除できます。WHERE句の検索条件は論理式であり、スカラー・ホスト変数、ホスト配列(SELECT文を除く)および副問合せを使用できます。

WHERE句を省略した場合は、表またはビュー内のすべての行が処理されます。UPDATEまたはDELETE文でWHERE句を省略すると、OracleはSQLCAのSQLWARN(5)を「W」に設定して、すべての列が処理されたことを示します。

カーソル

Oracleでは、SQL文を処理するためにプライベートSQL領域と呼ばれる作業領域がオープンされます。このプライベートSQL領域にはSQL文の実行に必要な情報が格納されます。カーソルと呼ばれる識別子を使用すると、SQL文に名前を付け、そのプライベートSQL領域に保存されている情報にアクセスし、その処理をある程度まで制御できます。

静的SQL文には、明示的および暗黙的という2種類のカーソルがあります。Oracleでは、INTO文を使用するSELECT文を含め、すべてのデータ定義文およびDML文についてカーソルが1つ暗黙的に宣言されます。

取得された一連の行は結果セットと呼ばれ、そのサイズは問合せの検索条件と何行一致するかによって異なります。現在処理している行(カレント行と呼ばれる)を識別するには、明示カーソルを使用します。

問合せで複数行を戻す場合、明示的にカーソルを定義して次の処理を行うことができます。

- 問合せによって戻された最初の行以後の処理

- 現在どの行が処理されているかの追跡および記録

カーソルは、問合せによって戻された行の集合内におけるカレント行を示します。これによって、プログラムは一度に1行ずつ処理できます。次の文を使用してカーソルを定義および操作します。

- DECLARE

- OPEN

- FETCH

- CLOSE

最初にDECLARE文(正確にはディレクティブ)を使用して、カーソルに名称を付け、問合せに関連付けます。

OPEN文によって問合せが実行され、この問合せの検索条件を満たす行がすべて判別されます。これらの行は、カーソルのアクティブ・セットと呼ばれる集合を形成します。カーソルをオープンした後、対応する問合せによって戻された行を取り出すことができます。

アクティブ・セットの行は1行ずつ取り出されます(ホスト配列を使用していない場合)。FETCH文を使用してアクティブ・セット内のカレント行を取り出します。FETCHは、すべての行が取り出されるまで繰返し実行できます。

アクティブ・セットからの行のフェッチが終了した後、CLOSE文によってカーソルを使用禁止にします(アクティブ・セットは未定義になります)。

カーソルの宣言

次の例に示すように、DECLARE文でカーソルに名称を与えることでカーソルを定義できます。

EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT ENAME, EMPNO, SAL
FROM EMP
WHERE DEPTNO = :DEPT_NUMBER
END-EXEC.

カーソル名は、ホスト変数やプログラム変数ではなく、プリコンパイラが使用する識別子であるため、COBOL文では定義しないでください。したがって、あるプリコンパイル単位から別のプリコンパイル・ユニットにカーソル名を渡すことはできません。カーソル名にハイフンは使用できません。長さは任意ですが、重要な意味があるのは先頭の31文字までです。ANSI互換性を維持するため、カーソル名は18文字までにしてください。

コマンドラインまたは構成ファイルでプリコンパイラ・オプションCLOSE_ON_COMMITが使用できます。CLOSE_ON_COMMIT=YESに設定すると、WITH HOLD句なしで宣言されたカーソルはすべてCOMMITまたはROLLBACKの後でクローズされます。詳細は、「DECLARE CURSOR文でのWITH HOLD句の使用」および「CLOSE_ON_COMMIT」を参照してください。

CLOSE_ON_COMMITより高いレベルでMODEが指定されていると、MODEが優先されます。デフォルトはMODE=ORACLEおよびCLOSE_ON_COMMIT=NOです。MODE=ANSIと指定した場合は、WITH HOLD句を使用していないカーソルはCOMMIT時にクローズされます。カーソルのクローズおよび再オープンの回数が多くなるため、アプリケーションの動作は遅くなります。MODE=ANSIのときは、CLOSE_ON_COMMIT=NOと設定するとパフォーマンスが向上します。MODEなどのマクロ・オプションがCLOSE_ON_COMMITなどのマイクロ・オプションに与える影響は、「オプション値の優先順位」を参照してください。

カーソルに関連付けられたSELECT文にINTO句を含めることはできません。INTO句および出力ホスト変数のリストはFETCH文の一部として指定します。

DECLARE文は宣言部なので、そのカーソルを参照する他のすべてのSQL文よりも物理的に(論理的にというだけでなく)前にあることが必要です。つまり、カーソルの前方参照は許可されていません。次の例では、OPEN文の位置が誤っています。

EXEC SQL OPEN EMPCURSOR END-EXEC.
*    -- MISPLACED OPEN STATEMENT
EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT ENAME, EMPNO, SAL
FROM EMP
WHERE ENAME = :EMP-NAME
END-EXEC.

カーソル制御文(DECLARE、OPEN、FETCH、CLOSE)はすべて同一のプリコンパイル・ユニット内で指定する必要があります。たとえば、ソース・ファイルA.PCOではカーソルを宣言できませんが、ソース・ファイルB.PCOではカーソルをオープンするという処理ができます。

ホスト・プログラムでは、必要な数のカーソルを宣言できます。ただし、指定されたファイル内ではそれぞれのDECLARE文は一意であることが必要です。つまり、カーソルのスコープはファイル内でグローバルなので、1つのプリコンパイル・ユニットの中では、ブロックやプロシージャが異なる場合でも同じ名前のカーソルを2つ宣言することはできません。

MODE=ANSIまたはCLOSE_ON_COMMIT=YESを使用する場合は、DECLAREセクションにWITH HOLD句を使用して、2つのオプションで定義される動作をオーバーライドできます。これらのオプションを設定すると、COMMITが発行されたときにすべてのカーソルがクローズされます。この場合、処理を続行するのにカーソルを再びオープンする必要があるため、オーバーヘッドが生じてパフォーマンスが低下します。WITH HOLD句を適切に使用して処理を高速化するには、プリコンパイラがANSI規格に適合しているプログラムであることが必要です。

カーソルのオープン

OPEN文を使用して、問合せを実行し、アクティブ・セットを決定します。次の例では、EMPCURSORの名前のカーソルがオープンされます。

EXEC SQL OPEN EMPCURSOR END-EXEC.

OPENによって、カーソルはアクティブ・セットの最初の行の直前に位置付けられます。ただし、この時点では実際に取り出される行はありません。行の取出しはFETCH文によって行われます。

カーソルをオープンすると、問合せの入力ホスト変数はカーソルを再オープンするまで再検査されません。つまり、アクティブ・セットは変更されません。アクティブ・セットを変更するには、カーソルを再オープンします。

OPENによって行われる作業量は、HOLD_CURSOR、RELEASE_CURSORおよびMAXOPENCURSORSの3つのプリコンパイラ・オプションの値によって決まります。詳細は、「Pro*COBOLプリコンパイラ・オプションの使用」を参照してください。

カーソルからのフェッチ

FETCH文を使用すると、アクティブ・セットから行を取り出し、結果を格納する出力ホスト変数を指定できます。カーソルに関連付けられたSELECT文にはINTO句を組み込めないことを思い出してください。INTO句および出力ホスト変数のリストはFETCH文の一部として指定します。次の例では、フェッチした行を3つのホスト変数に格納します。

EXEC SQL FETCH EMPCURSOR
INTO :EMP-NAME, :EMP-NUMBER, :SALARY
END-EXEC.

カーソルは、あらかじめ宣言し、オープンしておく必要があります。最初にFETCH文を実行すると、アクティブ・セットの最初の行より前にあるカーソルが最初の行に移動します。この行がカレント行になります。その後FETCHを実行するたびに、カレント行を変更しながら、カーソルをアクティブ・セットの次の行に進めます。カーソルはアクティブ・セット内を順方向にしか進みません。すでにフェッチした行に戻るには、カーソルを再オープンし、アクティブ・セットの最初の行からやり直す必要があります。

アクティブ・セットを変更する場合は、カーソルに対応する問合せの入力ホスト変数に新しい値を割り当て、カーソルを再オープンしてください。MODE=ANSIに設定されている場合は、再オープンする前にカーソルをクローズする必要があります。

次の例に示すように、異なる出力ホスト変数セットを使用して同じカーソルからフェッチできます。しかし、各FETCH文のINTO句内の対応するホスト変数は、同じデータ型であることが必要です。

EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT ENAME, SAL FROM EMP WHERE DEPTNO = 20
END-EXEC.
...
EXEC SQL OPEN EMPCURSOR END-EXEC.
EXEC SQL WHENEVER NOT FOUND DO ...
LOOP.
EXEC SQL FETCH EMPCURSOR INTO :EMP-NAME1, :SAL1 END-EXEC
EXEC SQL FETCH EMPCURSOR INTO :EMP-NAME2, :SAL2 END-EXEC
EXEC SQL FETCH EMPCURSOR INTO :EMP-NAME3, :SAL3 END-EXEC
...
GO TO LOOP.
...
END-PERFORM.

アクティブ・セットが空であるか、行がなくなると、FETCHは「データが見つかりません」というOracle警告コードをSQLCAのSQLCODEに戻します(MODE=ANSIに設定されている場合は、オプションのSQLSTATE変数も設定されます)。出力ホスト変数のステータスは不確定です。(通常のプログラムでは、WHENEVER NOT FOUND文でこのエラーが検出されます。)カーソルを再利用するには、再オープンする必要があります。

カーソルのクローズ

アクティブ・セットからの行のフェッチ終了後、カーソルをクローズし、そのカーソルのオープンによって獲得していたリソース(記憶域など)を解放します。カーソルがクローズされると、解析ロックが解放されます。どのリソースが解放されるかは、オプションHOLD_CURSORおよびRELEASE_CURSORの指定によって異なります。次の例では、EMPCURSORの名前のカーソルをクローズします。

EXEC SQL CLOSE EMPCURSOR END-EXEC.

クローズしたカーソルのアクティブ・セットは未定義になるため、クローズしたカーソルからフェッチすることはできません。必要であれば、(たとえば、入力ホスト変数に新しい値を指定して)カーソルを再オープンできます。

CLOSE_ON_COMMIT=NO (MODE=ORACLEの場合のデフォルト)の場合、COMMITまたはROLLBACKを発行しても、クローズされるのはFOR UPDATE句を使用して宣言されたカーソルまたはCURRENT OF句で参照されるカーソルのみです。その他のカーソルはCOMMITまたはROLLBACK文による影響を受けず、オープンされている場合はオープンされたままです。ただし、CLOSE_ON_COMMIT=YES (MODE=ANSIの場合のデフォルト)のときにCOMMITまたはROLLBACKを発行すると、すべてのカーソルがクローズします。詳細は、「CLOSE_ON_COMMIT」を参照してください。

CURRENT OF句の使用方法

DELETE文またはUPDATE文でCURRENT OF cursor_name句を使用すると、指定したカーソルから最後にフェッチした行を参照できます。カーソルをオープンし、行に位置付けておく必要があります。フェッチが1度も行われていない場合や、そのカーソルがオープンされていない場合には、CURRENT OF句を使用するとエラーが発生し、1行も処理されません。

UPDATE文またはDELETE文のCURRENT OF句で参照するカーソルを宣言するときに、FOR UPDATE OF句を任意で指定できます。CURRENT OF句は、必要に応じてFOR UPDATE句を追加するようにプリコンパイラに指示します。詳細は、「CURRENT OF句の擬似実行」を参照してください。

次の例では、CURRENT OF句を使用して、EMPCURSORの名前のカーソルから最後にフェッチした行を参照します。

EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT ENAME, SAL FROM EMP WHERE JOB = 'CLERK'
END-EXEC.
...
EXEC SQL OPEN EMPCURSOR END-EXEC.
EXEC SQL WHENEVER NOT FOUND DO ...
LOOP.
EXEC SQL FETCH EMPCURSOR INTO :EMP-NAME, :SALARY
END-EXEC.
...
EXEC SQL UPDATE EMP SET SAL = :NEW-SALARY
WHERE CURRENT OF EMPCURSOR
END-EXEC.
GO TO LOOP.

制限

明示的なFOR UPDATE OFまたは暗黙的なFOR UPDATEによって行の排他ロックが取得されます。いずれの行も、フェッチされるときではなくオープン時にロックされ、コミットまたはロールバックを行うとロックは解除されます。コミットした後でFOR UPDATEカーソルからフェッチしようとすると、エラーが発行されます。

結合で宣言されたカーソルにCURRENT OF句を使用することはできません。内部的にはCURRENT OFメカニズムはROWID擬似列を使用し、どの表にROWIDが関連するかを指定する方法がないためです。他の方法は、「CURRENT OF句の擬似実行」を参照してください。さらに、動的SQLではCURRENT OF句を使用できません。

一般的な文の順序

次の例は、CURRENT OF句とFOR UPDATE句を使用した一般的なカーソル制御文の順序を示しています。

* --  Define a cursor.
EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT ENAME, JOB FROM EMP
WHERE EMPNO = :EMP-NUMBER
FOR UPDATE OF JOB
END-EXEC.
* --  Open the cursor and identify the active set.
EXEC SQL OPEN EMPCURSOR END-EXEC.
* --  Exit if the last row was already fetched.
EXEC SQL
WHENEVER NOT FOUND GOTO NO-MORE
END-EXEC.
* --  Fetch and process data in a loop.
LOOP.
EXEC SQL FETCH EMPCURSOR INTO :EMP-NAME, :JOB-TITLE
END-EXEC.
* -- host-language statements that operate on the fetched data
EXEC SQL UPDATE EMP
SET JOB = :NEW-JOB-TITLE
WHERE CURRENT OF EMPCURSOR
END-EXEC.
GO TO LOOP.
...
MO-MORE.
* --  Disable the cursor.
EXEC SQL CLOSE EMPCURSOR END-EXEC.
EXEC SQL COMMIT WORK RELEASE END-EXEC.
STOP RUN.

位置付け更新

次の例は、「ユニバーサルROWID」に定義されているユニバーサルROWIDを使用した位置付け更新を示しています。

...
01  MY-ROWID SQL-ROWID.
...
EXEC SQL ALLOCATE :MY-ROWID END-EXEC.
EXEC SQL DECLARE C CURSOR FOR
SELECT ROWID, ... FROM MYTABLE FOR UPDATE OF ... END-EXEC.
EXEC SQL OPEN C END-EXEC.
EXEC SQL FETCH C INTO :MY-ROWID ... END-EXEC.
* Process retrieved data.
...
EXEC SQL UPDATE MYTABLE SET ... WHERE ROWID = :MY-ROWID END-EXEC.
...
NO-MORE-DATA:
EXEC SQL CLOSE C END-EXEC.
EXEC SQL FREE :MY-ROWID END-EXEC.
...

PREFETCHプリコンパイラ・オプション

プリコンパイラ・オプションPREFETCHを使用すると、行をプリフェッチすることによって問合せの効率を上げることができます。これにより、必要なサーバーのラウンドトリップ回数と必要なメモリーが減少します。構成ファイルまたはコマンドラインのPREFETCHオプション値で設定した行数は、標準の優先順位規則に従って、明示カーソルを含むすべての問合せに使用されます。

インラインで使用する場合は、次に示すカーソル文の前にPREFETCHオプションを指定する必要があります。

- EXEC SQL OPEN cursor

- EXEC SQL OPEN cursor USING host_var_list

- EXEC SQL OPEN cursor USING DESCRIPTOR desc_name

OPENを実行すると、問合せの実行時にプリフェッチする行数がPREFETCHの値によって指定されます。0 (プリフェッチなし)から9999までの値を設定できます。デフォルト値は1です。

注意:
PREFETCHプリコンパイラ・オプションは、単一行フェッチのパフォーマンスを向上させるためのものです。配列フェッチを実行する場合、PREFETCHの値は割り当てた値に関係なく無効になります。

スクロール可能カーソル

スクロール可能カーソルは、SQL文が実行され、実行中に処理された情報が格納される作業領域です。

カーソルが実行されると、結果セットと呼ばれる一連の行に問合せ結果が入れられます。結果セットは、順番にフェッチすることも、順不同でフェッチすることもできます。順不同の結果セットをスクロール可能カーソルと呼びます。

スクロール可能カーソルを使用すると、ユーザーは前から、後ろからまたはランダムな方法でデータベース結果セットの行にアクセスできます。これにより、プログラムは結果セットの任意の行をフェッチできます。『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください。

スクロール可能カーソルの使用方法

次の文を使用して、スクロール可能カーソルを定義および操作します。

DECLARE SCROLL CURSOR

DECLARE <cursor name> SCROLL CURSOR文を使用して、スクロール可能カーソルに名前を付け、問合せに対応付けます。

OPEN

OPEN文は、スクロール不可カーソルの場合と同じように使用できます。

FETCH

FETCH文を使用すると、必要な行をランダムな方法でフェッチできます。アプリケーションでは、行を上方向へまたは下方向へフェッチしたり、最初または最後の行を直接フェッチしたり、または任意の1行をランダムにフェッチできます。

FETCH文には次のオプションがあります。

1. FETCH FIRST
結果セットの最初の行をフェッチします。

2. FETCH PRIOR
カレント行の直前の行をフェッチします。

3. FETCH NEXT
現在位置の次の行をフェッチします。これは、スクロール不可カーソルのFETCHに相当します。

4. FETCH LAST
結果セットの最後の行をフェッチします。

5. FETCH CURRENT
カレント行をフェッチします。

6. FETCH RELATIVE n
カレント行を基準にしてn番目の行をフェッチします。nはオフセットです。

7. FETCH ABSOLUTE n
n番目の行をフェッチします。nは、結果セットの始まりからのオフセットです。

次の例は、結果セットの最後の行をFETCHする方法を示します。

EXEC SQL DECLARE emp_cursor SCROLL CURSOR FOR
SELECT ename, sal FROM emp WHERE deptno=20;
...
EXEC SQL OPEN emp_cursor;
EXEC SQL FETCH LAST emp_cursor INTO :emp_name, :sal;
EXEC SQL CLOSE emp_cursor;

CLOSE

CLOSE文は、スクロール不可カーソルの場合と同じように使用できます。

注意:
スクロール可能カーソルをREFカーソルとして使用することはできません。

CLOSE_ON_COMMITプリコンパイラ・オプション

CLOSE_ON_COMMITマイクロ・プリコンパイラ・オプションを使用すると、マクロ・オプションMODE=ANSIでCOMMITが実行されるときにすべてのカーソルをクローズするかどうかを選択できます。MODE=ANSIのとき、CLOSE_ON_COMMITのデフォルト値はYESです。明示的にCLOSE_ON_COMMIT=NOと設定すると、COMMITが実行されてもカーソルはクローズされず、カーソルを再オープンして解析する必要がなくなるためパフォーマンスが向上します。

PREFETCHプリコンパイラ・オプション

プリコンパイラ・オプションPREFETCHを使用すると、一定の行数をプリフェッチすることによって問合せの効率を上げることができます。これにより、必要なサーバーのラウンドトリップ回数とメモリー使用量全体が減少します。PREFETCHオプションで設定した行数は、標準の優先順位規則に従って、明示カーソルを含むすべての問合せに使用されます。インラインで使用する場合は、次に示すカーソル文の前にPREFETCHオプションを指定する必要があります。

- EXEC SQL OPEN cursor

- EXEC SQL OPEN cursor USING host_var_list

- EXEC SQL OPEN cursor USING DESCRIPTOR desc_name

OPENを実行すると、問合せの実行時にプリフェッチする行数がPREFETCHの値によって指定されます。0 (プリフェッチなし)から65535までの値を設定できます。デフォルト値は1です。

注意:
PREFETCHオプションのデフォルト値は1で、ラウンドトリップごとに1つの行が戻されます。PREFETCHオプションを使用しないように選択する場合は、コマンドラインでPREFETCHオプションを0に設定して、明示的に無効にする必要があります。
LONGまたはLOB列が取り出される場合は、PREFETCHが自動的に無効になります。

注意:
PREFETCHを使用すると、主に単一行フェッチのパフォーマンスが向上します。配列フェッチの使用時には、PREFETCHは無効です。

注意:
PREFETCHオプションは、状況に応じて広範囲に使用する必要があります。特定のFETCH文のパフォーマンスが最適化されるように、適切なプリフェッチ値を選択してください。そのためには、コマンドラインのPREFECTHオプションのかわりにインラインのPREFECTHオプションを使用します。

注意:
FETCH文にホスト変数とともに標識変数を使用するだけで、多数の大型アプリケーションのパフォーマンスを改善できます。
プリコンパイラ・アプリケーションで、単一行フェッチに対するPREFETCHオプションの使用による最大の利点が得られるように、標識変数を使用することをお薦めします。

B領域の長さの柔軟性

形式がANSIに設定されている場合、Pro*CobolプログラムのB領域の長さは72列に制限されていました。COBOLコンパイラでは、B領域の長さが最大253列までサポートされるようになりました。これにより、プログラマは72列より長い行を柔軟に入力できます。Pro*Cobolでは、Pro*Cobolアプリケーションが次のオプションでプリコンパイルされる場合にB領域の長さが最大253列までサポートされます。

FORMAT=VARIABLE IRECLEN=300

オプション。

固定実行計画

ある環境で開発した複数のモジュールを統合して、別の環境にデプロイするアプリケーション開発環境では、アプリケーションのパフォーマンスが影響を受けます。プリコンパイラ・アプリケーションのパフォーマンスは、データベース環境の変更によって影響を受けることがあります。これらの変更には、オプティマイザ統計の変更、オプティマイザ設定の変更またはメモリー構造のサイズに影響するパラメータの変更が含まれます。

開発環境においてPro*Cobolで使用されるSQLの実行計画を修正するには、プリコンパイル時にOracleのアウトライン機能を使用する必要があります。アウトラインは、SQL文と関連付けられた一連のオプティマイザ・ヒントとして実装されます。SQL文のアウトラインの使用を有効にすると、Oracleでは、格納されたヒントが自動的に考慮され、それらのヒントに従って実行計画を生成しようとします。これにより、モジュールの統合時および異なる環境へのデプロイ時に、パフォーマンスは影響を受けません。

次のSQL文を使用して、Pro*Cobolでアウトラインを作成できます。

- SELECT

- DELETE

- UPDATE

- INSERT... SELECT

- CREATE TABLE... AS SELECT

アウトライン・オプションが設定されている場合、プリコンパイルが正常に終了すると、2つのファイル(SQLファイルおよびLOGファイル)が生成されます。コマンドライン・オプションoutlineおよびoutlnprefixは、アウトラインの生成を制御します。

関連項目
コマンドライン・オプションの詳細は、第14章「プリコンパイラ・オプション」を参照してください。

生成される各アウトライン名は一意です。アプリケーションで使用するファイル名が一意であるため、アウトライン名の生成時にこの情報が使用されます。また、カテゴリ名も接頭辞として使用されます。

注意:
アウトライン名の最大長は30バイトです。この制限を超えると、プリコンパイラではエラーが発生します。outlnprefixオプションを使用すると、アウトライン名の長さを制限できます。

例5-1 アウトラインを含むSQLファイルの生成

次のプログラムのアウトラインがサポートされているすべてのSQL文のアウトラインを含むSQLファイルを生成するには、アウトライン・オプションを使用して、次のプログラムをプリコンパイルする必要があります。

*****************************************************************
* outlndemo:                                                    *

* Outlines will be created for the following SQL operations,    *
* 1. CREATE ... SELECT                                          *
* 2. INSERT ... SELECT                                          *
* 3. UPDATE                                                     *
* 4. DELETE                                                     *
* 5. SELECT                                                     *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID.  outlndemo.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.

* EMBEDDED COBOL (file "OUTNDEMO.PCO")

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME          PIC X(10) VARYING.
01  PASSWD            PIC X(10) VARYING.

01  ENAME PIC  X(10).
01  JOB PIC  X(9).
01  SAL PIC  X(6).
01  COMM PIC  X(6).

EXEC SQL END DECLARE SECTION END-EXEC.

01  STRINGFIELDS.
02 STR PIC X(18) VARYING.

EXEC SQL INCLUDE SQLCA END-EXEC.

PROCEDURE DIVISION.
BEGIN-PGM.
EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC.

PERFORM LOGON.

EXEC SQL INSERT INTO BONUS
SELECT ENAME, JOB, SAL, COMM FROM EMP
WHERE JOB LIKE 'SALESMAN'
END-EXEC.

EXEC SQL UPDATE BONUS
SET SAL = SAL * 1.1 WHERE SAL < 1500
END-EXEC.

EXEC SQL DECLARE C1 CURSOR FOR
SELECT ENAME, JOB, SAL, COMM FROM BONUS ORDER BY SAL
END-EXEC.
EXEC SQL OPEN C1 END-EXEC.
DISPLAY "Contents of updated BONUS table".
DISPLAY "ENAME       JOB     SAL  COMM".
DISPLAY " ".

EXEC SQL WHENEVER NOT FOUND GOTO END-FETCH END-EXEC.
FETCH-DATA.
EXEC SQL FETCH C1 INTO :ENAME, :JOB, :SAL, :COMM END-EXEC.
DISPLAY ENAME, JOB, SAL, COMM.
GO TO FETCH-DATA.

END-FETCH.
EXEC SQL CLOSE C1 END-EXEC.
EXEC SQL WHENEVER NOT FOUND DO PERFORM SQL-ERROR END-EXEC.

EXEC SQL DELETE FROM BONUS END-EXEC.

EXEC SQL CREATE TABLE OUTLNDEMO_TAB AS
SELECT EMPNO, ENAME, SAL FROM EMP WHERE DEPTNO = 10
END-EXEC.

EXEC SQL DROP TABLE OUTLNDEMO_TAB END-EXEC.

EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

LOGON.
MOVE "scott" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "tiger" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.

* HANDLES SQL ERROR CONDITIONS
SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

SQLファイル

生成されるファイル名の書式は次のとおりです。

<filename>_<filetype>.sql

Pro*Cobolでは、ファイル「abc.pco」の場合、生成されるSQLファイルはabc_pco.sqlになります。

生成されるファイル書式

outlnprefixオプションを使用しない場合は、アウトライン名およびコメントとして、次の一意識別子の書式が使用されます。

<category_name>_<filename>_<filetype>_<sequence no.>

outlnprefixオプションを使用する(outlnprefix=<prefix_name>)場合は、アウトライン名およびコメントとして、次の一意識別子の書式が使用されます。

<prefix_name>_<sequence no.>

outline=yes (デフォルトのカテゴリ)の場合、<category_name>はDEFAULTに、アウトライン名は次のいずれかになります。

DEFAULT_<filename>_<filetype>_<sequence no.>

または

<prefix_name>_<sequence no.>

<sequence no.>に使用できる値の範囲は、0000から9999です。

生成されたプリコンパイル済ファイルのSQLには、SQLのアウトラインで表示されるように、コメントが追加されます。

例

次の例を考えてみます。

例1

abc.pcoには、次の文が含まれています。

EXEC SQL select * from emp where empno=:var END-EXEC.
EXEC SQL select * from dept END-EXEC.

outline=mycat1で、outlnprefixを使用しない場合は、次のようになります。

abc_pco.sqlの内容

select * from emp where empno=:b1 /* mycat1_abc_pco_0000 */;で、カテゴリmycat1のアウトラインmycat1_abc_pco_0000を作成または置換します。

select * from dept /* mycat1_abc_pco_0001 */;で、カテゴリmycat1のアウトラインmycat1_abc_pco_0001を作成または置換します。

abc.cobの内容

01 SQ0001 GLOBAL.
02 FILLER PIC X(60) VALUE "select * from emp where empno=:b1
-  /* mycat1_abc_pco_0000 */
-    "".

例2

abc.pcoには、次の文が含まれています。

EXEC SQL select * from emp where empno=:var END-EXEC.
EXEC SQL select * from dept END-EXEC.

outline=mycat1で、outlnprefix=myprefixの場合は、次のようになります。

abc_pco.sqlの内容

select * from emp where empno=:b1 /* myprefix_0000 */;で、カテゴリmycat1のアウトラインmyprefix_0000を作成または置換します。

select * from dept /* myprefix_0001 */;で、カテゴリmycat1のアウトラインmyprefix_0001を作成または置換します。

abc.cobの内容

01 SQ0001 GLOBAL.
02 FILLER PIC X(60) VALUE "select * from emp where empno=:b1
-  /* myprefix_0000 */
- "".

例3

abc.pcoには、次の文が含まれています。

EXEC SQL select * from emp where empno=:var END-EXEC.
EXEC SQL select * from dept END-EXEC.

outline=yesで、outlnprefix=myprefixの場合は、次のようになります。

abc_pco.sqlの内容

select * from emp where empno=:b1 /* myprefix_0000 */;で、アウトラインmyprefix_0000を作成または置換します。

select * from dept /* myprefix_0001 */;で、アウトラインmyprefix_0001を作成または置換します。

abc.cobの内容

01 SQ0001 GLOBAL.
03 FILLER PIC X(60) VALUE "select * from emp where empno=:b1
-  /* myprefix_0000 */
- "".

LOGファイル

生成されるファイル名の書式は次のとおりです。

<filename>_<filetype>.log

Pro*Cobolでは、ファイル「abc.pco」の場合、生成されるLOGファイルはabc_pco.logになります。

次の例を考えてみます。

例1

abc.pcoには、次の文が含まれています。

EXEC SQL select * from emp END-EXEC.

abc_pco.logの内容

CATEGORY <Category_name>
Source SQL_0
SELECT * FROM emp
OUTLINE NAME
abc_pco_0000
OUTLINE SQL_0
Select * from emp /* abc_pco_0000 */

サンプル・プログラム2: カーソル操作

次のプログラムでは、Oracleにログインし、カーソルを宣言およびオープンします。次に、全営業担当者の名前、給料および歩合給をフェッチして結果を表示し、カーソルをクローズします。

最後の1つのフェッチを除くすべてのフェッチで1行ずつ戻され、フェッチ中にエラーが検出されなければ、成功のステータス・コードが戻されます。最後のフェッチは失敗し、「データが見つかりません」というOracle警告コードがSQLCAのSQLCODEに戻されます。実際にフェッチされた行の累積数は、SQLCAのSQLERRD(3)に示されています。

*****************************************************************
* Sample Program 2:  Cursor Operations                          *
*                                                               *
* This program logs on to ORACLE, declares and opens a cursor,  *
* fetches the names, salaries, and commissions of all           *
* salespeople, displays the results, then closes the cursor.    *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID. CURSOR-OPS.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME          PIC X(10) VARYING.
01  PASSWD            PIC X(10) VARYING.
01  EMP-REC-VARS.
05  EMP-NAME      PIC X(10) VARYING.
05  SALARY        PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
05  COMMISSION    PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
EXEC SQL VAR SALARY IS DISPLAY(8,2) END-EXEC.
EXEC SQL VAR COMMISSION IS DISPLAY(8,2) END-EXEC.
EXEC SQL END DECLARE SECTION END-EXEC.

EXEC SQL INCLUDE SQLCA END-EXEC.

01  DISPLAY-VARIABLES.
05  D-EMP-NAME    PIC X(10).
05  D-SALARY      PIC Z(4)9.99.
05  D-COMMISSION  PIC Z(4)9.99.

PROCEDURE DIVISION.

BEGIN-PGM.
EXEC SQL WHENEVER SQLERROR
DO PERFORM SQL-ERROR END-EXEC.
PERFORM LOGON.
EXEC SQL DECLARE SALESPEOPLE CURSOR FOR
SELECT ENAME, SAL, COMM
FROM EMP
WHERE JOB LIKE 'SALES%'
END-EXEC.
EXEC SQL OPEN SALESPEOPLE END-EXEC.
DISPLAY " ".
DISPLAY "SALESPERSON  SALARY      COMMISSION".
DISPLAY "-----------  ----------  ----------".

FETCH-LOOP.
EXEC SQL WHENEVER NOT FOUND
DO PERFORM SIGN-OFF END-EXEC.
EXEC SQL FETCH SALESPEOPLE
INTO :EMP-NAME, :SALARY, :COMMISSION
END-EXEC.
MOVE EMP-NAME-ARR TO D-EMP-NAME.
MOVE SALARY TO D-SALARY.
MOVE COMMISSION TO D-COMMISSION.
DISPLAY D-EMP-NAME, "     ", D-SALARY, "    ", D-COMMISSION.
MOVE SPACES TO EMP-NAME-ARR.
GO TO FETCH-LOOP.

LOGON.
MOVE "SCOTT" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "TIGER" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE AS USER:  ", USERNAME-ARR.

SIGN-OFF.
EXEC SQL CLOSE SALESPEOPLE END-EXEC.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY.".
DISPLAY " ".
EXEC SQL COMMIT WORK RELEASE END-EXEC.
STOP RUN.

SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

6 埋込みPL/SQL

PL/SQLトランザクション処理ブロックをプログラム内に埋め込むことにより、パフォーマンスを改善する方法を説明します。この章の内容は、次のとおりです。

- PL/SQLの埋込み

- PL/SQLの利点

- PL/SQLブロックの埋込み

- ホスト変数およびPL/SQL

- 標識変数およびPL/SQL

- ホスト表およびPL/SQL

- 埋込みPL/SQLでのカーソルの使用

- ストアドPL/SQLおよびJavaサブプログラム

- サンプル・プログラム9: ストアド・プロシージャのコール

- カーソル変数

PL/SQLの埋込み

Pro*COBOLは、PL/SQLブロックを単一の埋込みSQL文のように扱います。PL/SQLブロックは、SQL文を記述できる位置であればホスト・プログラム内のどこにでも記述できます。

ホスト・プログラムにPL/SQLブロックを埋め込むには、PL/SQLとの間で共有される変数を宣言し、PL/SQLブロックをEXEC SQL EXECUTEキーワードおよびEND-EXECキーワードで囲みます。

ホスト変数

PL/SQLブロックの中では、ホスト変数はブロック全体にわたるグローバルなものとして扱われ、PL/SQL変数を記述できる位置であればどこにでも記述できます。SQL文内におけるホスト変数と同様、PL/SQLブロック内のホスト変数も先頭にコロンを付ける必要があります。コロンは、ホスト変数とPL/SQL変数およびデータベース・オブジェクトとを区切ります。

VARCHAR変数

PL/SQLブロックに入ると、Oracleは自動的にVARCHARホスト変数の長さフィールドをチェックします。このため、ブロックに入る前に長さフィールドを設定する必要があります。入力変数の長さフィールドは、文字列フィールドに格納される値の長さに設定します。出力変数の場合は、長さフィールドにその文字列フィールドに許される最大の長さを設定します。

標識変数

PL/SQLブロックでは、標識変数は単独では参照できません。対応するホスト変数に追加する必要があります。また、標識変数付きでホスト変数を参照する場合、同一ブロック中では常に同じ方法で参照する必要があります。

NULLの処理

ブロックに入るとき、標識変数の値が-1であれば、PL/SQLによってNULLがホスト変数に自動的に割り当てられます。ブロックから出るとき、ホスト変数がNULLであれば、PL/SQLによって値-1が標識変数に自動的に割り当てられます。

切り捨てられた値の処理

PL/SQLでは、切り捨てられた文字列の値がホスト変数に割り当てられても、例外とはみなされません。ただし、標識変数を指定している場合には、PL/SQLによってその標識変数が文字列の元の長さに設定されます。

SQLCHECK

埋込みPL/SQLブロックを持つプログラムをプリコンパイルする際には、SQLCHECK=SEMANTICSを指定する必要があります。また、USERIDオプションも使用する必要があります。詳細は、第14章「プリコンパイラ・オプション」を参照してください。

PL/SQLの利点

この項では、PL/SQLによって提供される次のような機能および利点を説明します。

- パフォーマンスの向上

- Oracleとの統合

- カーソルFORループ

- プロシージャおよびファンクション

- パッケージ

- PL/SQL表

- ユーザー定義レコード

PL/SQLの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

パフォーマンスの向上

PL/SQLによって、オーバーヘッドの削減、パフォーマンスの改善および生産性の向上が図れます。たとえば、PL/SQLを使用しないと、Oracleは一度に1つずつSQL文を処理する必要があります。その結果、各SQL文によってサーバーへの別のコールが発生し、オーバーヘッドが増加します。ただし、PL/SQLを使用すると、サーバーにSQL文のブロック全体を送信することができます。これによって、アプリケーションとサーバーとの間の通信は最小限になります。

Oracleとの統合

PL/SQLはサーバーと密接に統合されます。たとえば、PL/SQLデータ型の大部分は、データ・ディクショナリに固有のデータ型です。さらに、次の例に示すとおり、データ・ディクショナリ内に格納された列定義に基づいて変数を宣言するための%TYPE属性が使用できます。

job_title  emp.job%TYPE;

したがって、列の厳密なデータ型を知る必要はありません。しかも、列定義を変更すると、変数宣言もそれに応じて自動的に変更されます。これによって、データ独立性を提供し、メンテナンス・コストを削減し、データベース変更時にプログラムが順応できるようになります。

カーソルFORループ

PL/SQLを使用すれば、カーソルを定義して操作するために、DECLARE、OPEN、FETCHおよびCLOSE文を使用する必要はありません。かわりに、カーソルFORループを使用でき、ループ索引をレコードとして暗黙的に宣言し、指定された問合せに関連付けられているカーソルをオープンして、データを繰り返しカーソルからフェッチしてレコードに入れてから、カーソルをクローズします。次に、例を示します。

DECLARE
...
BEGIN
FOR emprec IN (SELECT empno, sal, comm FROM emp) LOOP
IF emprec.comm / emprec.sal > 0.25 THEN ...
...
END LOOP;
END;

レコード中のフィールドの参照にはドット表記法を使用することに注意してください。

サブプログラム

PL/SQLにはプロシージャとファンクションと呼ばれる2種類のサブプログラムがあり、これらを使用すると、各動作を分離できるため、アプリケーションの開発が容易になります。一般的には、プロシージャを使用して処理を行い、ファンクションを使用して値を計算します。

プロシージャおよびファンクションには拡張性があります。つまり、プロシージャとファンクションを使用することにより、PL/SQL言語を必要に応じて調整できます。たとえば、新しい部門を作成するプロシージャが必要な場合、次のように記述します。

PROCEDURE create_dept
(new_dname  IN CHAR(14),
new_loc    IN CHAR(13),
new_deptno OUT NUMBER(2)) IS
BEGIN
SELECT deptno_seq.NEXTVAL INTO new_deptno FROM dual;
INSERT INTO dept VALUES (new_deptno, new_dname, new_loc);
END create_dept;

このプロシージャをコールすると、新しい部門名および場所が確立され、部門番号データベース順序内の次の値が選択され、新しい番号、名前および場所がdept表の中に挿入されます。次に、新しい番号がコール元に戻ります。

サブプログラムをそのつど再コンパイルせずに、複数のアプリケーションからコールできます。(CREATE FUNCTIONおよびCREATE PROCEDUREを使用してサブプログラムをデータベースに格納できます。)

パラメータ・モード

仮パラメータの動作を定義するには、パラメータ・モードを使用します。パラメータ・モードにはIN (デフォルト)、OUTおよびIN OUTの3つがあります。INパラメータを使用すると、コールされるサブプログラムに値を渡せます。OUTパラメータを使用すると、サブプログラムのコール元に値を戻せます。IN OUTパラメータを使用すると、コールされるサブプログラムに初期値を渡し、更新された値をコール元に戻すことができます。

それぞれの実パラメータのデータ型は、対応する仮パラメータのデータ型に変換可能であることが必要です。表6-1に、データ型間の有効な変換を示します。

パッケージ

PL/SQLでは、論理的に関連する型、プログラム・オブジェクトおよびサブプログラムを1つのパッケージにまとめることができます。パッケージは、コンパイルしてデータベースに格納できます。これにより、パッケージの内容を複数のアプリケーションで共有できるようになります。

パッケージには通常、仕様部および本体の2つの部分があります。仕様部とは、アプリケーションへのインタフェースで、使用可能な型、定数、変数、例外、カーソルおよびサブプログラムが宣言されます。本体は、カーソルおよびサブプログラムを定義して、仕様を実行します。次の例では、2つのプロシージャをパッケージ化しています。

PACKAGE emp_actions IS  -- package specification
PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...);
PROCEDURE fire_employee (emp_id NUMBER);
END emp_actions;

PACKAGE BODY emp_actions IS  -- package body
PROCEDURE hire_employee (empno NUMBER, ename CHAR, ...) IS
BEGIN
INSERT INTO emp VALUES (empno, ename, ...);
END hire_employee;
PROCEDURE fire_employee (emp_id NUMBER) IS
BEGIN
DELETE FROM emp WHERE empno = emp_id;
END fire_employee;
END emp_actions;

パッケージ仕様部内の宣言のみ参照可能で、アプリケーションからアクセスできます。パッケージ本体中の詳細な実装内容は非表示のためアクセスできません。

PL/SQL表

PL/SQLにはTABLEの名前の複合データ型が用意されています。TABLE型のオブジェクトは、PL/SQL表と呼ばれ、データベース表をモデルとしています(まったく同じではありません)。PL/SQL表は1列からなり、主キーを使用して、配列と同じ方法で行にアクセスします。列は、任意のスカラー型(CHAR、DATEまたはNUMBERなど)にできますが、主キーはBINARY_INTEGER型、PLS_INTEGER型またはVARCHAR2型にする必要があります。

ブロック、プロシージャ、ファンクションまたはパッケージのいずれかの宣言部でPL/SQL表型を宣言できます。次の例では、NumTabTypと呼ばれるTABLE型を宣言しています。

DECLARE
TYPE NumTabTyp IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
...
BEGIN
...
END;

次の例に示すように、一度NumTabTyp型を定義すると、その型のPL/SQL表を宣言できます。

num_tab  NumTabTyp;

識別子num_tabは、PL/SQL表全体を表しています。

配列に似た構文を使用してPL/SQL表の中の行を参照し、主キーの値を指定します。たとえば、num_tabの名前のPL/SQL表の中の9番目の行を参照するには次のように指定します。

num_tab(9) ...

ユーザー定義レコード

%ROWTYPE属性を使用して、データベース表の中の行を表すレコード、またはカーソルによってフェッチされる行を表すレコードを宣言できます。ただし、レコード内のフィールドのデータ型は指定できず、ユーザー独自のフィールドも定義できません。複合データ型RECORDを使用すると、これらの制限事項を取り除くことができます。

RECORD型のオブジェクトはレコードと呼ばれます。PL/SQL表とは異なり、レコードには一意の名前のフィールドがあり、フィールドのデータ型は異なっていてもかまいません。たとえば、ある従業員について異なる種類のデータ(名前、給与、雇用日など)があるとします。このデータは、型は異なりますが、論理的に関連しています。従業員の名前、給与および雇用日などのフィールドを持つレコードによって、1つの論理単位としてデータを処理できます。

ブロック、プロシージャ、ファンクションまたはパッケージのいずれかの宣言部で、レコード型およびレコード・オブジェクトを宣言できます。次の例では、DeptRecTypと呼ばれるRECORD型を宣言しています。

DECLARE
TYPE DeptRecTyp IS RECORD
(deptno  NUMBER(4) NOT NULL := 10,  -- must initialize
dname   CHAR(9),
loc     CHAR(14));

フィールド宣言は変数宣言と似ています。各フィールドには一意の名前および固有のデータ型を指定します。フィールド宣言にNOT NULLオプションを追加すると、そのフィールドにはNULLを割り当てられません。ただし、NOT NULLを指定したフィールドは初期化する必要があります。

次の例に示すように、一度DeptRecTypを定義すると、その型のレコードを宣言できます。

dept_rec  DeptRecTyp;

識別子dept_recは、レコード全体を表しています。

レコード内の個々のフィールドを参照するには、ドット表記法を使用します。たとえば、dept_recレコードのdnameフィールドを参照する場合は、次のように記述します。

dept_rec.dname ...

PL/SQLブロックの埋込み

Pro*COBOLは、PL/SQLブロックを単一の埋込みSQL文のように扱います。そのため、PL/SQLブロックは、SQL文を記述できる位置であればホスト・プログラム内のどこにでも記述できます。

PL/SQLブロックをホスト・プログラム内に埋め込むには、次のように、キーワードEXEC SQL EXECUTEおよびEND-EXECでPL/SQLブロックを囲みます。

EXEC SQL EXECUTE
DECLARE
...
BEGIN
...
END;
END-EXEC.

プログラムでPL/SQLブロックを埋め込む場合、Pro*COBOLでPL/SQLを解析する必要があるため、プリコンパイラ・オプションSQLCHECK=SEMANTICSを指定する必要があります。サーバーに接続する場合も、オプションUSERIDを指定する必要があります。詳細は、「Pro*COBOLプリコンパイラ・オプションの使用」を参照してください。

ホスト変数およびPL/SQL

ホスト変数は、ホスト言語とPL/SQLブロック間の通信を仲介します。ホスト変数はPL/SQLと共有できるので、PL/SQLではホスト変数の設定および参照ができます。

たとえば、ユーザーに情報の提供を求め、この情報をPL/SQLブロックに渡すためのホスト変数を使用するようにユーザーに指示できます。これにより、PL/SQLを使用してデータベースにアクセスし、ホスト変数を介してその結果をホスト・プログラムに戻せるようになります。

PL/SQLブロック内ではホスト変数はブロック全体のグローバル変数として扱われ、PL/SQL変数を使用できる位置であればどこにでも使用できます。SQL文内におけるホスト変数と同様、PL/SQLブロック内のホスト変数も先頭にコロンを付ける必要があります。コロンは、ホスト変数とPL/SQL変数およびデータベース・オブジェクトとを区切ります。

PL/SQLの例

次の例では、PL/SQLにおけるホスト変数の使用方法を示します。プログラムはユーザーに従業員番号の入力を要求し、その番号に応じて、従業員の役職名、雇用日および給与を表示します。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 USERNAME   PIC X(20) VARYING.
01 PASSWORD   PIC X(20) VARYING.
01 EMP-NUMBER PIC S9(4) COMP.
01 JOB-TITLE  PIC X(20) VARYING.
01 HIRE-DATE  PIC X(9) VARYING.
01 SALARY     PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
EXEC SQL END DECLARE SECTION END-EXEC.
EXEC SQL INCLUDE SQLCA END-EXEC.
...
DISPLAY 'Connected to Oracle'.
PERFORM
DISPLAY 'Employee Number (0 to end)? 'WITH NO ADVANCING
ACCEPT EMP-NUMBER
IF EMP-NUMBER = 0
EXEC SQL COMMIT WORK RELEASE END-EXEC
DISPLAY 'Exiting program'
STOP RUN
END-IF.
*   ---------------- begin PL/SQL block -----------------
EXEC SQL EXECUTE
BEGIN
SELECT job, hiredate, sal
INTO :JOB-TITLE, :HIRE-DATE, :SALARY
FROM EMP
WHERE EMPNO = :EMP-NUMBER;
END;
END-EXEC.
*    ---------------- end PL/SQL block -----------------
DISPLAY 'Number  Job Title  Hire Date  Salary'.
DISPLAY '------------------------------------'.
DISPLAY EMP-NUMBER, JOB-TITLE, HIRE-DATE, SALARY.
END-PERFORM.
...
SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
DISPLAY 'Processing error'.
STOP RUN.

ホスト変数EMP-NUMBERはPL/SQLブロックに入る前に設定され、ホスト変数JOB-TITLE、HIRE-DATEおよびSALARYはブロックの中で設定されていることに注意してください。

PL/SQLの複雑な例

次の例では、ユーザーは銀行口座番号、取引の種類および取引金額の入力を要求されます。その後、口座に取引が記帳されます。口座が存在しない場合は、例外が発生します。取引が完了すると、そのステータスが表示されます。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 USERNAME   PIC X(20) VARYING.
01 ACCT-NUM   PIC S9(4) COMP.
01 TRANS-TYPE PIC X(1).
01 TRANS-AMT  PIC PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
01 STATUS     PIC X(80) VARYING.
EXEC SQL END DECLARE SECTION END-EXEC.
EXEC SQL INCLUDE SQLCA END-EXEC.
DISPLAY 'Username? 'WITH NO ADVANCING.
ACCEPT USERNAME.
DISPLAY 'Password? '.
ACCEPT PASSWORD.
EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR.
EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWORD.
PERFORM
DISPLAY 'Account Number (0 to end)? '
WITH NO ADVANCING
ACCEPT ACCT_NUM
IF ACCT-NUM = 0
EXEC SQL COMMIT WORK RELEASE END-EXEC
DISPLAY 'Exiting program' WITH NO ADVANCING
STOP RUN
END-IF.
DISPLAY 'Transaction Type - D)ebit or C)redit? '
WITH NO ADVANCING
ACCEPT TRANS-TYPE
DISPLAY 'Transaction Amount? '
ACCEPT trans_amt
*   --------------------- begin PL/SQL block -------------------
EXEC SQL EXECUTE
DECLARE
old_bal      NUMBER(9,2);
err_msg      CHAR(70);
nonexistent  EXCEPTION;
BEGIN
IF :TRANS-TYP-TYPE = 'C' THEN       -- credit the account
UPDATE accts SET bal = bal + :TRANS-AMT
WHERE acctid = :acct-num;
IF SQL%ROWCOUNT = 0 THEN    -- no rows affected
RAISE nonexistent;
ELSE
:STATUs := 'Credit applied';
END IF;
ELSIF :TRANS-TYPe = 'D' THEN    -- debit the account
SELECT bal INTO old_bal FROM accts
WHERE acctid = :ACCT-NUM;
IF old_bal >= :TRANS-AMT THEN   -- enough funds
UPDATE accts SET bal = bal - :TRANS-AMT
WHERE acctid = :ACCT-NUM;
:STATUS := 'Debit applied';
ELSE
:STATUS := 'Insufficient funds';
END IF;
ELSE
:STATUS := 'Invalid type: ' || :TRANS-TYPE;
END IF;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND OR nonexistent THEN
:STATUS := 'Nonexistent account';
WHEN OTHERS THEN
err_msg := SUBSTR(SQLERRM, 1, 70);
:STATUS := 'Error: ' || err_msg;
END;
END-EXEC.
*     ------------------- end PL/SQL block -----------------------
DISPLAY 'Status: ', STATUS
END-PERFORM.
...
SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
DISPLAY 'Processing error'.
STOP RUN.

VARCHAR疑似型

VARCHAR疑似型は、可変長の文字列の宣言に使用できます。VARCHARが入力ホスト変数の場合は、予測される長さをPro*COBOLに通知する必要があります。このため長さフィールドは、文字列フィールドに格納される値の実際の長さに設定してください。

VARCHARが出力ホスト変数の場合、Pro*COBOLは自動的に長さフィールドを設定します。ただし、PL/SQLブロックでVARCHAR出力ホスト変数を使用するには、ブロックに入る前に長さフィールドを初期化する必要があります。したがって、次の例に示すように、長さフィールドを宣言された(最大の) VARCHAR長に設定してください。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 EMP-NUM   PIC S9(4) COMP.
01 EMP-NAME  PIC X(10) VARYING.
01 SALARY    PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
...
EXEC SQL END DECLARE SECTION END-EXEC.
PROCEDURE DIVISION.
...
* -- initialize length field
MOVE 10 TO EMP-NAME-LEN.
EXEC SQL EXECUTE
BEGIN
SELECT ename, sal INTO :EMP-NAME, :SALARY
FROM emp
WHERE empno = :EMP-NUM;
...
END;
END-EXEC.

標識変数およびPL/SQL

PL/SQLでは、NULLを操作できるため、標識変数は必要ありません。たとえば、PL/SQL内では、次のようにIS NULL演算子を使用してNULLをテストできます。

IF variable IS NULL THEN ...

次のように、代入演算子(:=)を使用してNULLを割り当てることができます。

variable := NULL;

ただし、ホスト言語はNULLを扱えないため、標識変数が必要です。埋込みPL/SQLでこの要件を満たすには、標識変数を次の用途に使用します。

- ホスト・プログラムからのNULL入力値の受入れ

- NULLまたは切り捨てられた値のホスト・プログラムへの出力

PL/SQLブロックで標識変数を使用する場合は、次の規則に従ってください。

- 標識変数によってホスト変数を参照する場合、同じブロック内では常にホスト変数を使用して標識変数を参照する必要があります。

次の例では、標識変数IND-COMMは、SELECT文でホスト変数COMMISSIONとともに記述されているため、IF文でもホスト変数とともに記述する必要があります。

EXEC SQL EXECUTE
BEGIN
SELECT ename, comm
INTO :EMP-NAME, :COMMISSION:IND-COMM FROM emp
WHERE empno = :EMP-NUM;
IF :COMMISSION:IND-COMM IS NULL THEN ...
...
END;
END-EXEC.

:COMMISSION:IND-COMMは、PL/SQLでは他の単純な変数と同じように扱われます。PL/SQLブロック内の標識変数は直接参照できませんが、PL/SQLでは、ブロックに入るときに標識変数の値がチェックされ、ブロックから出るときにその値が正しく設定されます。

NULLの処理

ブロックに入るとき、標識変数の値が-1であれば、PL/SQLによってNULLがホスト変数に自動的に割り当てられます。ブロックから出るとき、ホスト変数がNULLであれば、PL/SQLによって値-1が標識変数に自動的に割り当てられます。次の例で、PL/SQLブロックに入る前にIND-SALの値が-1になっていると、salary_missing例外が発生します。例外とは、名前が指定されたエラー条件です。

EXEC SQL EXECUTE
BEGIN
IF :SALARY:IND-SAL IS NULL THEN
RAISE salary_missing;
END IF;
...
END;
END-EXEC.

切り捨てられた値の処理

PL/SQLでは、切り捨てられた文字列の値がホスト変数に割り当てられても、例外とはみなされません。ただし、標識変数を指定している場合には、PL/SQLによってその標識変数が文字列の元の長さに設定されます。次の例では、ホスト・プログラムは、IND-NAMEの値をチェックして、切り捨てられた値がEMP-NAMEに割り当てられたかどうかを判別できます。

EXEC SQL EXECUTE
DECLARE
...
new_name  CHAR(10);
BEGIN
...
:EMP_NAME:IND-NAME := new_name;
...
END;
END-EXEC.

ホスト表およびPL/SQL

入力ホスト表およびインジケータ表は、PL/SQLブロックに渡せます。これらは、BINARY_INTEGER型またはPLS_INTEGER型のPL/SQL変数を使用して索引付けができます。VARCHAR2型のキーは使用できません。通常は、ホスト表全体がPL/SQLに渡されますが、ARRAYLEN文(後述)を使用すれば、より小さい表サイズを指定できます。

また、サブプログラム・コールを使用して、ホスト表内のすべての値をPL/SQL表内の行に割り当てることができます。表の添字範囲がmからnである場合、対応するPL/SQL表の索引範囲は常に1から(n-m+ 1)になります。たとえば、表の添字範囲が5から10であると、対応するPL/SQL表の索引範囲は1から(10-5+1)つまり1から6になります。

注意: Pro*COBOLでは、ホスト表の使用方法はチェックされません。たとえば、索引の範囲チェックは行われません。

次の例では、salaryというホスト表を、ファンクション・コールでホスト表を使用するPL/SQLブロックに渡しています。このファンクションは、一連の数値の中央値を検出するため、medianという名前が付いています。その仮パラメータには、num_tabというPL/SQL表が含まれています。このファンクション・コールにより、実パラメータsalary内のすべての値を仮パラメータnum_tab内の行に割り当てます。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01  SALARY OCCURS 100 TIMES PIC S9(6)V99 COMP-3.
01  MEDIAN-SALARY  PIC S9(6)V99 COMP-3.
EXEC SQL END DECLARE SECTION END-EXEC.
* -- populate the host table
EXEC SQL EXECUTE
DECLARE
TYPE NumTabTyp IS TABLE OF REAL
INDEX BY BINARY_INTEGER;
n  BINARY_INTEGER;
...
FUNCTION median (num_tab NumTabTyp, n INTEGER)
RETURN REAL IS
BEGIN
* -- compute median
END;
BEGIN
n := 100;
:MEDIAN-SALARY := median(:SALARY    END;
END-EXEC.

また、サブプログラム・コールを使用して、PL/SQL表内のすべての行の値をホスト表内の対応する要素に割り当てることもできます。「ストアドPL/SQLおよびJavaサブプログラム」の例を参照してください。

ホスト表とPL/SQLの間のインタフェースによって、データ型が厳密に制御されます。PIC Xのデフォルトの外部型はCHARF (固定長文字列)で、CHAR型のPL/SQL表にのみマップできます。

表6-1に、PL/SQL表内の行の値、およびホスト配列内の要素との間の有効な変換を示します。この表からわかるように、PIC X変数をVARCHAR2型の表に渡すには、データ型の同値化を使用して変数をVARCHAR2に同値化するか、コマンドラインでPICX=VARCHAR2を使用する必要があります。

表6-1 データ型の有効な変換

PL/SQL表

-

-

-

-

-

-

-

-

ホスト表

CHAR

DATE

LONG

LONG RAW

NUMBER

RAW

ROWID

VARCHAR2

CHARF

可

-

-

-

-

-

-

-

CHARZ

可

-

-

-

-

-

-

-

DATE

-

可

-

-

-

-

-

-

DECIMAL

-

-

-

-

可

-

-

-

DISPLAY

-

-

-

-

可

-

-

-

FLOAT

-

-

-

-

可

-

-

-

INTEGER

-

-

-

-

-

-

-

-

LONG

可

-

可

-

-

-

-

-

LONG VARCHAR

-

-

可

可

-

可

-

可

LONG VARRAW

-

-

-

可

-

可

-

-

NUMBER

-

-

-

-

可

-

-

RAW

-

-

-

可

-

可

-

-

ROWID

-

-

-

-

-

-

可

-

STRING

-

-

可

可

-

可

-

可

UNSIGNED

-

-

-

-

可

-

-

-

VARCHAR

-

-

可

可

-

可

-

可

VARCHAR2

-

-

可

可

-

可

-

可

VARNUM

-

-

-

-

可

-

-

-

VARRAW

-

-

-

可

-

可

-

-

ARRAYLEN文

入力ホスト表をPL/SQLブロックに渡して、処理する必要があるとします。デフォルトでは、このようなホスト表をバインドする際に、Pro*COBOLは宣言されたディメンションを使用します。ただし、表の一部のみ処理する場合もあります。このような場合には、ARRAYLEN文を使用してより小さい表ディメンションを指定できます。ARRAYLEN文は、ホスト表をより小さいディメンションを格納するホスト変数と関連付けます。構文は次のとおりです。

EXEC SQL ARRAYLEN host_array (dimension) EXECUTE END-EXEC.

dimensionは4バイトの整数ホスト変数であり、リテラルや式ではありません。

ARRAYLEN文は、host_arrayおよびdimensionの宣言の後に置く必要があります。ホスト表にオフセットは指定できません。ただし、そのためにCOBOL機能を使用できる場合があります。

次の例では、ARRAYLENを使用して、ホスト表BONUSのデフォルトのディメンションをオーバーライドしています。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 BONUS OCCURS 100 TIMES PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
01 MY-DIM  PIC S9(9) COMP.
...
EXEC SQL ARRAYLEN BONUS (MY-DIM) END-EXEC.
EXEC SQL END DECLARE SECTION END-EXEC.
* -- populate the host table
...
* -- set smaller table dimension
MOVE 25 TO MY-DIM.
EXEC SQL EXECUTE
DECLARE
TYPE NumTabTyp IS TABLE OF REAL
INDEX BY BINARY_INTEGER;
median_bonus  REAL;
FUNCTION median (num_tab NumTabTyp, n INTEGER)
RETURN REAL IS
BEGIN
* -- compute median
END;
BEGIN
median_bonus := median(:BONUS, :MY-DIM);
...
END;
END-EXEC.

ARRAYLENによってホスト表の要素が100から25に減らされるため、25の表要素のみPL/SQLブロックに渡されます。結果として、実行のためにPL/SQLブロックがサーバーに送信されるときに、一緒に送られるホスト表は、はるかに小さくなります。これにより、時間を節約し、ネットワーク化された環境でネットワークの通信量を削減できます。

ARRAYLEN文のEXECUTEオプション・キーワード

動的SQL方法2の文(「方法2の使用方法」を参照)で使用されるホスト表には、ARRAYLEN文のEXECUTEオプション・キーワードの有無によって2種類の解釈があります。 .

EXECUTEオプション・キーワードがない場合は、次のようになります。

- PL/SQLブロックが複数回実行されます。実行回数は使用されるARRAYLENの最小ディメンションによって決まります。

- ホスト配列は、PL/SQL表にバインドできません。

EXECUTEオプション・キーワードがある場合は、次のようになります。

- ホスト表は、索引表にバインドする必要があります。

- PL/SQLブロックは、1回のみ実行されます。

- EXEC SQL EXECUTE文で指定するホスト変数はすべて、次のいずれかにする必要があります。

- ARRAYLEN ... EXECUTE文の中で指定。

- スカラー値。

次のPro*COBOLの例に、ホスト表を使用してPL/SQLブロックの実行回数を決定する方法を示します。この例では、PL/SQLブロックは3回実行され、emp表に3行の新規の行が作成されます。

...
01  DYNSTMT   PIC X(80) VARYING.
01  EMPNOTAB  PIC S9(4) COMPUTATIONAL OCCURS 5 TIMES.
01  ENAMETAB  PIC X(10) OCCURS 3 TIMES.
...
MOVE 1111 TO EMPNOTAB(1).
MOVE 2222 TO EMPNOTAB(2).
MOVE 3333 TO EMPNOTAB(3).
MOVE 4444 TO EMPNOTAB(4).
MOVE 5555 TO EMPNOTAB(5).

MOVE "MICKEY" TO ENAMETAB(1).
MOVE "MINNIE" TO ENAMETAB(2).
MOVE "GOOFY" TO ENAMETAB(3).

MOVE "BEGIN INSERT INTO emp(empno, ename) VALUES :b1, :b2; END;"
TO DYNSTMT-ARR.
MOVE 57 TO DYNSTMT-LEN.

EXEC SQL PREPARE s1 FROM :DYNSTMT END-EXEC.
EXEC SQL EXECUTE s1 USING :EMPNOTAB, :ENAMETAB END-EXEC.
...

次のPL/SQLプロシージャを使用するとします。

CREATE OR REPLACE PACKAGE pkg AS
TYPE tab IS TABLE OF NUMBER(5) INDEX BY BINARY_INTEGER;
PROCEDURE proc1 (parm1 tab, parm2 NUMBER, parm3 tab);
END;

次のPro*COBOLの例は、動的方法2を使用してホスト表をPL/SQL索引表にバインドする方法を示します。EXEC SQL EXECUTE文に指定されたすべてのホスト配列についてARRAYLEN...EXECUTE文があることに注意してください。

...
01  DYNSTMT   PIC X(80) VARYING.
01  II        PIC S9(4) COMP VALUE 2.
01  INTTAB    PIC S9(9) COMP OCCURS 3 TIMES.
01  DIM       PIC S9(9) COMP VALUE 3.

EXEC SQL ARRAYLEN INTTAB (DIM) EXECUTE END-EXEC.
...
MOVE 1 TO INTTAB(1).
MOVE 2 TO INTTAB(2).
MOVE 3 TO INTTAB(3).

MOVE "BEGIN pkg.proc1 (:v1, :v2, :v3); end;";
TO DYNSTMT-ARR.
MOVE 37 TO DYNSTMT-LEN.

EXEC SQL PREPARE s1 FROM :DYNSTMT END-EXEC.
EXEC SQL EXECUTE s1 USING :INTTAB, :II, :INTTAB END-EXEC.
...

ただし、次のPro*COBOLの例ではINTTAB2にARRAYLEN...EXECUTE文が存在しないため、プリコンパイル時にエラーになります。

...
01  DYNSTMT   PIC X(80) VARYING.
01  INTTAB    PIC S9(9) COMP OCCURS 3 TIMES.
01  INTTAB2   PIC S9(9) COMP OCCURS 3 TIMES.
01  DIM       PIC S9(9) COMP VALUE 3.

EXEC SQL ARRAYLEN INTTAB (DIM) EXECUTE END-EXEC.
...
MOVE 1 TO INTTAB(1).
MOVE 2 TO INTTAB(2).
MOVE 3 TO INTTAB(3).

MOVE "BEGIN pkg.proc1 (:v1, :v2, :v3); end;";
TO DYNSTMT-ARR.
MOVE 37 TO DYNSTMT-LEN.

EXEC SQL PREPARE s1 FROM :DYNSTMT END-EXEC.
EXEC SQL EXECUTE s1 USING :INTTAB, :INTTAB2, :INTTAB END-EXEC.
...

埋込みPL/SQLでのカーソルの使用

プログラムで同時に使用できるカーソルの最大数は、データベースの初期化パラメータOPEN_CURSORSで決定します。通常、OPEN_CURSORSを超えないように、プリコンパイラで文のカーソルを管理できます。プリコンパイル・オプションのHOLD_CURSOR、RELEASE_CURSORおよびMAXOPENCURSORSが使用されます。(詳細は、「埋込みPL/SQLに関する考慮事項」を参照。)埋込みPL/SQLブロックの実行中には、PL/SQLブロック全体に対応付けられた1つの親カーソルと、PL/SQLブロックの実行中に実行される文ごとの1つの子カーソルがあります。PL/SQLブロックは実行時にサーバーに渡されるため、プリコンパイラのランタイム・ライブラリでは親カーソルのみ追跡できます。したがって、この方法で多数のカーソルを使用するアプリケーションでは、カーソルがOPEN_CURSORSで指定された数を上回る可能性があります。図6-1は、使用されるカーソルの最大数を計算する方法を示しています。

図6-1 使用されるカーソルの最大数の計算方法

開発者はカーソルの状況に注意して、OPEN_CURSORSおよびMAXOPENCURSORSを設定してください。

問題が解決しない場合は、SQL文の実行後に子カーソルをすべて解放することができます。

この場合は、RELEASE_CURSOR=YESおよびHOLD_CURSOR=NOの設定を使用します。最初の設定をプログラム全体に適用するとパフォーマンスが低下するため、これらのオプションの設定は次のようにします。

EXEC ORACLE OPTION (RELEASE_CURSOR=YES) END-EXEC.
* --  first embedded PL/SQL block
EXEC ORACLE OPTION (RELEASE_CURSOR=NO)END-EXEC.
* --  embedded SQL statements
EXEC ORACLE OPTION (RELEASE_CURSOR=YES)END-EXEC.
* --  second embedded PL/SQL block
EXEC ORACLE OPTION (RELEASE_CURSOR=NO)END-EXEC.
* --  embedded SQL statements

ストアドPL/SQLおよびJavaサブプログラム

無名ブロックとは異なり、PL/SQLサブプログラム(プロシージャおよびファンクション)およびJavaメソッドは、別々にコンパイルしてデータベースに格納し、起動できます。

SQL*PlusなどのOracleツールを使用して明示的に作成したサブプログラムを、ストアド・サブプログラムと呼びます。コンパイルされ、データ・ディクショナリに格納されたストアド・サブプログラムは、データベース・オブジェクトとなり、再コンパイルせずに再実行できます。

PL/SQLブロック内のサブプログラムまたはストアド・サブプログラムは、アプリケーションによってデータベースに送信されると、インライン・サブプログラムになり、データベースでコンパイルされます。Pro*COBOLは文をサーバーに送信し、文が実行されます。

パッケージ内で定義されているサブプログラムは、そのパッケージの一部とみなされ、パッケージ・サブプログラムと呼ばれます。パッケージで定義されていないストアド・サブプログラムは、スタンドアロン・サブプログラムと呼ばれます。

ストアド・サブプログラムの作成

次の例に示すように、SQL文CREATE FUNCTION、CREATE PROCEDUREおよびCREATE PACKAGEをCOBOLプログラムに埋め込むことができます。

EXEC SQL CREATE
FUNCTION sal_ok (salary REAL, title CHAR)
RETURN BOOLEAN AS
min_sal  REAL;
max_sal  REAL;
BEGIN
SELECT losal, hisal INTO min_sal, max_sal
FROM sals
WHERE job = title;
RETURN (salary >= min_sal) AND
(salary <= max_sal);
END sal_ok;
END-EXEC.

埋込みCREATE {FUNCTION | PROCEDURE | PACKAGE}文は混成であることに注意してください。他のすべてのCREATE埋込み文と同様、キーワードEXEC SQL (EXEC SQL EXECUTEではありません)で始まります。

埋込みCREATE {FUNCTION | PROCEDURE | PACKAGE}文が失敗した場合、Oracleはエラーではなく警告を発行します。CREATE文のすべての構文は、『Oracle Database SQL言語リファレンス』を参照してください。

ストアドPL/SQLまたはJavaサブプログラムのコール

ホスト・プログラムからストアド・サブプログラムをコールするには、無名PL/SQLブロックまたはCALL埋込みSQL文のどちらかを使用できます。

無名PL/SQLブロック

次の例では、raise_salaryの名前のスタンドアロン・プロシージャをコールします。

EXEC SQL EXECUTE
BEGIN
raise_salary(:emp_id, :increase);
END;
END-EXEC.

ストアド・サブプログラムにパラメータを組み込めることに注意してください。この例では、実パラメータemp_idおよびincreaseはホスト変数です。

次の例では、プロシージャraise_salaryがemp_actionsの名前のパッケージに格納されます。したがって、プロシージャ・コールを完全に修飾するにはドット表記法を使用する必要があります。

EXEC SQL EXECUTE
BEGIN
emp_actions.raise_salary(:emp_id, :increase);
END;
END-EXEC.

IN実パラメータには、リテラル、ホスト変数、ホスト表、PL/SQL定数、PL/SQL変数、PL/SQL表、PL/SQLユーザー定義レコード、サブプログラム・コールまたは式を使用できます。これに対してOUT実パラメータには、リテラル、サブプログラム・コールおよび式は使用できません。

埋込みPL/SQLブロックとともにプリコンパイラ・オプションSQLCHECK=SEMANTICSを使用する必要があります。

CALL文

前述の埋込みPL/SQLブロックに関する概念は、CALL文にも適用できます。CALL埋込みSQL文の書式は次のようになります。

EXEC SQL
CALL [schema.][package.]stored_proc[@db_link](arg1, ...)
[INTO :ret_var[[INDICATOR]:ret_ind]]
END-EXEC.

パラメータは次のとおりです。

schema

プロシージャを含むスキーマ

package

プロシージャを含むパッケージ

stored_proc

コールするJavaまたはPL/SQLストアド・プロシージャ

db_link

オプションのリモート・データベース・リンク

arg1...

引き渡す一連の引数(変数、リテラル、式)

ret_var

結果を受け取るオプションのホスト変数

ind_var

ret_varのオプションの標識変数。

CALL文とともにSQLCHECK=SYNTAXまたはSQLCHECK=SEMANTICSのどちらかを使用できます。

CALLの例

次に示すように、入力された整数を受け取り、その階乗を整数で戻すPL/SQLファンクションfact(パッケージmathpkgに格納されています)を作成済とします。

EXEC SQL CREATE OR REPLACE PACKAGE BODY mathpkg as
function fact(n IN INTEGER) RETURN INTEGER AS
BEGIN
IF (n <= 0) then return 1;
ELSE return n * fact(n - 1);
END IF;
END fact;
END mathpkge;
END-EXEC.

Pro*COBOLアプリケーションでfactを使用するには、次のように指定します。

...

01 N      PIC S9(4) COMP.
01 FACT   PIC S9(9) COMP.
...
EXEC SQL CALL mathpkge.fact(:N) INTO :FACT END-EXEC.
...

この文の詳細は、「CALL (実行可能埋込みSQL)」を参照してください。引数の引渡しなどの説明は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』の「外部ルーチン」の章を参照してください。

動的PL/SQLの使用

Pro*COBOLは、PL/SQLブロック全体を1つのSQL文のように扱います。つまり、PL/SQLブロックをホスト変数の文字列に格納できることを意味します。その場合、ブロックにホスト変数が含まれていなければ、動的SQL方法1を使用してPL/SQL文字列を実行できます。ブロックにホスト変数が含まれていて、その数がわかっている場合は、動的SQL方法2を使用してPL/SQL文字列を準備し、実行します。ブロックに含まれるホスト変数の数がわからない場合は、動的SQL方法4を使用する必要があります。詳細は、第9章「Oracle動的SQL」、第10章「ANSI動的SQL」および第11章「Oracle動的SQL: 方法4」を参照してください。

サブプログラムの制限事項

動的SQL方法4では、型がTABLEのパラメータを指定してホスト表をPL/SQLプロシージャにバインドできません。

サンプル・プログラム9: ストアド・プロシージャのコール

このサンプル・プログラムを実行する前に、次に示すPro*COBOLが提供するCALLDEMO.SQLスクリプトを実行して、calldemoの名前のPL/SQLパッケージを作成する必要があります。このスクリプトはPro*COBOLに付属のスクリプトで、Pro*COBOLデモ・ライブラリに入っています。このスクリプト名の正確なスペルは、使用しているシステム固有のOracleマニュアルを参照してください。

CREATE OR REPLACE PACKAGE calldemo AS

TYPE name_array IS TABLE OF emp.ename%type
INDEX BY BINARY_INTEGER;
TYPE job_array IS TABLE OF emp.job%type
INDEX BY BINARY_INTEGER;
TYPE sal_array IS TABLE OF emp.sal%type
INDEX BY BINARY_INTEGER;

PROCEDURE get_employees(
dept_number IN     number,    -- department to query
batch_size  IN     INTEGER,   -- rows at a time
found       IN OUT INTEGER,   -- rows actually returned
done_fetch  OUT    INTEGER,   -- all done flag
emp_name    OUT    name_array,
job         OUT    job_array,
sal         OUT    sal_array);

END calldemo;
/

CREATE OR REPLACE PACKAGE BODY calldemo AS

CURSOR get_emp (dept_number IN number) IS
SELECT ename, job, sal FROM emp
WHERE deptno = dept_number;

-- Procedure "get_employees" fetches a batch of employee
-- rows (batch size is determined by the client/caller
-- of the procedure).  It can be called from other
-- stored procedures or client application programs.
-- The procedure opens the cursor if it is not
-- already open, fetches a batch of rows, and
-- returns the number of rows actually retrieved. At
-- end of fetch, the procedure closes the cursor.

PROCEDURE get_employees(
dept_number IN     number,
batch_size  IN     INTEGER,
found       IN OUT INTEGER,
done_fetch  OUT    INTEGER,
emp_name    OUT    name_array,
job         OUT    job_array,
sal         OUT    sal_array) IS

BEGIN
IF NOT get_emp%ISOPEN THEN      -- open the cursor if
OPEN get_emp(dept_number);  -- not already open
END IF;

-- Fetch up to "batch_size" rows into PL/SQL table,
-- tallying rows found as they are retrieved. When all
-- rows have been fetched, close the cursor and exit
-- the loop, returning only the last set of rows found.

done_fetch := 0;  -- set the done flag FALSE
found := 0;

FOR i IN 1..batch_size LOOP
FETCH get_emp INTO emp_name(i), job(i), sal(i);
IF get_emp%NOTFOUND THEN    -- if no row was found
CLOSE get_emp;
done_fetch := 1;   -- indicate all done
EXIT;
ELSE
found := found + 1;  -- count row
END IF;
END LOOP;
END;
END;
/

次のサンプルプログラムはデータベースに接続し、ユーザーに部門番号の入力を要求し、その後calldemoパッケージに格納されたget_employeesというPL/SQLプロシージャをコールします。プロシージャでは、3つのPL/SQL表をOUT仮パラメータとして宣言し、その後、従業員のバッチ・データをPL/SQL表にフェッチします。一致する実パラメータはホスト表です。プロシージャの終了時に、PL/SQL表の行の値が、ホスト表の対応する要素に自動的に割り当てられます。プログラムでは、プロシージャを繰り返しコールし、データがなくなるまで、従業員データの各バッチを表示します。

*****************************************************************
* Sample Program 9: Calling a Stored Procedure
*
* This program connects to ORACLE, prompts the user for a
* department number, then calls a PL/SQL stored procedure named
* GET_EMPLOYEES, which is stored in package CALLDEMO.  The
* procedure declares three PL/SQL tables ast OUT formal
* parameters, then fetches a batch of employee data into the
* PL/SQL tables.  The matching actual parameters are host tables.
* When the procedure finishes, it automatically assigns all row
* values in the PL/SQL tables to corresponding elements in the
* host tables.  The program calls the procedure repeatedly,
* displaying each batch of employee data, until no more data
* is found.
* Use option picx=varchar2 when precompiling this sample program.
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID. CALL-STORED-PROC.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME         PIC X(15) VARYING.
01  PASSWD           PIC X(15) VARYING.
01  DEPT-NUM         PIC S9(9) COMP.
01  EMP-TABLES.
05  EMP-NAME     OCCURS 10 TIMES PIC X(10).
05  JOB-TITLE    OCCURS 10 TIMES PIC X(10).

05  SALARY       OCCURS 10 TIMES COMP-2.

01  DONE-FLAG        PIC S9(9) COMP.
01  TABLE-SIZE       PIC S9(9) COMP VALUE 10.
01  NUM-RET          PIC S9(9) COMP.
01  SQLCODE          PIC S9(9) COMP.
EXEC SQL END DECLARE SECTION END-EXEC.

01  COUNTER          PIC S9(9) COMP.
01  DISPLAY-VARIABLES.
05  D-EMP-NAME   PIC X(10).
05  D-JOB-TITLE  PIC X(10).

05  D-SALARY     PIC Z(5)9.

05  D-DEPT-NUM   PIC 9(2).

EXEC SQL INCLUDE SQLCA END-EXEC.

PROCEDURE DIVISION.

BEGIN-PGM.
EXEC SQL WHENEVER SQLERROR DO
PERFORM SQL-ERROR END-EXEC.

PERFORM LOGON.
PERFORM INIT-TABLES VARYING COUNTER FROM 1 BY 1
UNTIL COUNTER > 10.
PERFORM GET-DEPT-NUM.
PERFORM DISPLAY-HEADER.
MOVE ZERO TO DONE-FLAG.
MOVE ZERO TO NUM-RET.
PERFORM FETCH-BATCH UNTIL DONE-FLAG = 1.
PERFORM LOGOFF.

INIT-TABLES.
MOVE SPACE TO EMP-NAME(COUNTER).
MOVE SPACE TO JOB-TITLE(COUNTER).
MOVE ZERO TO SALARY(COUNTER).

GET-DEPT-NUM.
MOVE ZERO TO DEPT-NUM.
DISPLAY " ".
DISPLAY "ENTER DEPARTMENT NUMBER: "
WITH NO ADVANCING.

ACCEPT D-DEPT-NUM.

MOVE D-DEPT-NUM TO DEPT-NUM.

DISPLAY-HEADER.
DISPLAY " ".
DISPLAY "EMPLOYEE    JOB TITLE    SALARY".
DISPLAY "--------    ---------    ------".

FETCH-BATCH.
EXEC SQL EXECUTE
BEGIN
CALLDEMO.GET_EMPLOYEES
(:DEPT-NUM, :TABLE-SIZE,
:NUM-RET,  :DONE-FLAG,
:EMP-NAME, :JOB-TITLE, :SALARY);
END;
END-EXEC.
PERFORM PRINT-ROWS VARYING COUNTER FROM 1 BY 1
UNTIL COUNTER > NUM-RET.

PRINT-ROWS.
MOVE EMP-NAME(COUNTER) TO D-EMP-NAME.
MOVE JOB-TITLE(COUNTER) TO D-JOB-TITLE.
MOVE SALARY(COUNTER) TO D-SALARY.
DISPLAY D-EMP-NAME, "  ",
D-JOB-TITLE, "   ",
D-SALARY.

LOGON.
MOVE "SCOTT" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "TIGER" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE AS USER: ", USERNAME-ARR.

LOGOFF.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY.".
DISPLAY " ".
EXEC SQL COMMIT WORK RELEASE END-EXEC.
STOP RUN.

SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

それぞれの実パラメータのデータ型は、対応する仮パラメータのデータ型に変換可能であることが必要です。また、ストアド・サブプログラムが終了する前にすべてのOUT仮パラメータに値を割り当てる必要があります。そうしないと、対応する実パラメータの値が未確定になります。

リモート・アクセス

PL/SQLを使用すると、データベース・リンクを経由してリモート・データベースにアクセスできます。通常、データベース・リンクは、DBAが作成し、データ・ディクショナリに格納されます。データベース・リンクは、データベースの位置、そのデータベースへのパス、および使用するユーザー名とパスワードをプログラムに示します。次の例では、データベース・リンクdallasを使用して、raise_salaryプロシージャをコールします。

EXEC SQL EXECUTE
BEGIN
raise_salary@dallas(:emp_id, :increase);
END;
END-EXEC.

次の例に示すように、シノニムを作成して、リモート・サブプログラムに位置の透過性を与えることができます。

CREATE PUBLIC SYNONYM raise_salary FOR raise_salary@dallas;

カーソル変数

Pro*COBOLプログラムでカーソル変数を使用して、静的埋込みSQLによって複数行の問合せを処理できます。カーソル変数は、PL/SQLによってデータベース・サーバーで定義およびオープンされるカーソル参照を示します。カーソル変数の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

カーソル変数は、カーソルと同じように、複数行の問合せのアクティブ・セットの中のカレント行を指します。カーソルとカーソル変数との違いは、定数と変数との違いと同じです。カーソルは静的で、カーソル変数は特定の問合せに結び付けられていないため、動的です。カーソル変数は、型の互換性のある任意の問合せに対してオープンできます。

カーソル変数に新しい値を割り当てて、サブプログラム(データベースに格納されているサブプログラムなど)にパラメータとして渡せます。これにより、データ検索を簡単に集中化できます。

まず、カーソル変数を宣言します。カーソル変数を宣言した後、次の文を使用してカーソル変数を制御します。

- ALLOCATE

- OPEN ... FOR

- FETCH

- CLOSE

- FREE

カーソル変数を宣言してメモリーを割り当てた後、そのカーソル変数を入力ホスト変数(バインド変数)としてPL/SQLに渡します。次に、サーバー側でOPEN、FORを使用して複数行の問合せ用にオープンし、クライアント側でFETCHしてから、サーバー側かクライアント側のどちらかでCLOSEします。

カーソル変数の利点は、次のとおりです。

- メンテナンスのしやすさ。問合せは、カーソル変数をオープンするストアド・プロシージャに集中されます。カーソルを変更する必要がある場合は、ストアド・プロシージャの変更のみで済みます。各アプリケーションを変更する必要はありません。

- セキュリティの強化。アプリケーションのユーザー(Pro*COBOLアプリケーションがデータベースに接続した時のユーザー名)は、カーソルをオープンするストアード・プロシージャに対する実行権限を持っている必要があります。ただし、ユーザーには、問合せで使用される表に対する権限は必要ありません。この機能を使用して、表の列へのアクセスを制限できます。

カーソル変数の宣言

Pro*COBOLカーソル変数はSQL-CURSOR疑似型を使用して宣言します。次に例を示します。

WORKING-STORAGE SECTION.
...
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01  CUR-VAR  SQL-CURSOR.
...
EXEC SQL END DECLARE SECTION END-EXEC.

SQL-CURSOR変数は、Pro*COBOLが生成するコードにCOBOLグループ項目として実装されます。カーソル変数は、他のPro*COBOLホスト変数とまったく同じです。

カーソル変数の割当て

カーソル変数をOPENするとき、またはその後で情報をFETCHするときには、Pro*COBOLのALLOCATEコマンドを使用してカーソル変数を初期化しておく必要があります。たとえば、前の項で宣言したカーソル変数CUR-VARを初期化するには、次の文を使用します。

EXEC SQL ALLOCATE :CUR-VAR END-EXEC.

カーソル変数の割当てには、プリコンパイル時も実行時もサーバーをコールする必要はありません。

ALLOCATE文ではAT句は使用できません。

注意: カーソル変数を割り当てると、ヒープ・メモリーが使用されます。したがって、プログラム・ループではカーソル変数を割り当てないでください。

カーソル変数のオープン

データベース・サーバーでカーソル変数をオープンするには、埋込み無名PL/SQLブロックを使用する必要があります。無名PL/SQLブロックは、カーソルをオープンする(また、同じ文でカーソルを定義する) PL/SQLストアド・プロシージャをコールして間接的にカーソルをオープンするか、Pro*COBOLプログラムから直接カーソルをオープンします。

PL/SQLストアド・プロシージャによる間接的なオープン

次のPL/SQLパッケージがデータベースに格納されているとします。

CREATE PACKAGE demo_cur_pkg AS
TYPE EmpName IS RECORD (name VARCHAR2(10));
TYPE cur_type IS REF CURSOR RETURN EmpName;
PROCEDURE open_emp_cur (
curs     IN OUT curtype,
dept_num IN     number);
END;

CREATE PACKAGE BODY demo_cur_pkg AS
CREATE PROCEDURE open_emp_cur (
curs     IN OUT curtype,
dept_num IN     number) IS
BEGIN
OPEN curs FOR
SELECT ename FROM emp
WHERE deptno = dept_num
ORDER BY ename ASC;
END;
END;

このパッケージが格納された後、まずPro*COBOLプログラムからopen_emp_curストアド・プロシージャをコールし、プログラム内のカーソル変数emp_cursorからFETCHを発行して、カーソルcursをオープンできます。次に例を示します。

WORKING-STORAGE SECTION.
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  emp_cursor     sql-cursor.
01  DEPT-NUM      PIC S9(4).
01  EMP-NAME      PIC X(10) VARYING.
EXEC SQL END DECLARE SECTION END-EXEC.
...

PROCEDURE DIVISION.
...
*    Allocate the cursor variable.
EXEC SQL
ALLOCATE :emp-cursor
END-EXEC.
...
MOVE 30 TO dept_num.
*    Open the cursor on the Oracle Server.
EXEC SQL EXECUTE
begin
demo_cur_pkg.open_emp_cur(:emp-cursor, :dept-num);
END;
END-EXEC.
EXEC SQL
WHENEVER NOT FOUND DO PERFORM SIGN-OFF
END-EXEC.
FETCH-LOOP.
EXEC SQL
FETCH :emp_cursor INTO :EMP-NAME
END-EXEC.
DISPLAY "Employee Name: ",:EMP-NAME.
GO TO FETCH-LOOP.
...
SIGN-OFF.
...

Pro*COBOLアプリケーションからの直接的なオープン

Pro*COBOLプログラム内で無名PL/SQLブロックを使用してカーソルをオープンするには、無名ブロックの中でカーソルを定義します。次の例を考えてみます。

PROCEDURE DIVISION.
...
EXEC SQL EXECUTE
begin
OPEN :emp_cursor FOR SELECT ename FROM emp
WHERE deptno = :DEPT-NUM;
end;
END-EXEC.
...

カーソル変数からのフェッチ

複数行の問合せ用にカーソル変数をオープンした後、FETCH文を使用して、静的カーソルの場合と同じように行を取り出します。構文は次のとおりです。

EXEC SQL FETCH cursor_variable_name
INTO {record_name | variable_name[, variable_name, ...]}
END-EXEC.

カーソル変数が戻す各列値は、データ型に互換性がある場合、INTO句内の対応するフィールドまたは変数に割り当てられます。

FETCH文はクライアント側で実行する必要があります。次の例では、EMP-RECの名前のホスト・レコードに行をフェッチします。

* -- exit loop when done fetching
EXEC SQL
WHENEVER NOT FOUND DO PERFORM NO-MORE
END-EXEC.
PERFORM
* -- fetch row into record
EXEC SQL FETCH :EMP-CUR INTO :EMP-REC END-EXEC
* -- test for transfer out of loop
...
* -- process the data
...
END-PERFORM.
...
NO-MORE.
...

埋込みSQLのFETCH ....INTO命令を使用して、カーソル変数をオープンしたときに選択した行を取得します。次に例を示します。

EXEC SQL
FETCH :emp_cursor INTO :EMP-INFO:EMP-INFO-IND
END-EXEC.

カーソル変数からFETCHするには、そのカーソル変数を初期化し、オープンしておく必要があります。オープンされていないカーソル変数からFETCHはできません。

カーソル変数のクローズ

カーソル変数をクローズするには、埋込みSQLのCLOSE文を使用します。その時点で、アクティブ・セットは未定義になります。構文は次のとおりです。

EXEC SQL CLOSE cursor_variable_name END-EXEC.

CLOSE文はクライアント側でもサーバー側でも実行できます。次の例では、最後の行が処理されたときにカーソル変数CUR-VARをクローズします。

WORKING-STORAGE SECTION.
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
*    Declare the cursor variable.
01  CUR-VAR       SQL-CURSOR.
...
EXEC SQL END DECLARE SECTION END-EXEC.

PROCEDURE DIVISION.
*    Allocate and open the cursor variable, then
*    Fetch one or more rows.
...
*    Close the cursor variable.
EXEC SQL
CLOSE :CUR-VAR
END-EXEC.

カーソル変数の解放

カーソル変数CUR-VARに割り当てられたメモリーを解放するには、CLOSEの後でFREE文を使用します。

*    Free the cursor variable memory.
EXEC SQL
FREE :CUR-VAR
END-EXEC.

カーソル変数の制限

カーソル変数の使用には、次の制限が適用されます。

- カーソル変数は、動的SQLではサポートされません。

- カーソル変数は、ALLOCATE、FETCH、FREEおよびCLOSEコマンドのみで使用できます。DECLARE CURSORコマンドは、カーソル変数には適用されません。

- ALLOCATEコマンドではAT句を使用できません。

サンプル・プログラム11: カーソル変数

次のサンプル・プログラム、SQLスクリプト(SAMPLE11.sql)およびPro*COBOLプログラム(SAMPLE11.pco)では、Pro*COBOLにおけるカーソル変数の使用方法を示します。

SAMPLE11.SQL

このサンプル・プログラムは、カーソル変数を宣言してオープンするパッケージを作成するためのPL/SQLソース・コードです。

CONNECT SCOTT/TIGER
CREATE OR REPLACE PACKAGE emp_demo_pkg AS
TYPE emp_cur_type IS REF CURSOR RETURN emp%ROWTYPE;
PROCEDURE open_cur (
cursor   IN OUT emp_cur_type,
dept_num IN     number);
END emp_demo_pkg;
/
CREATE OR REPLACE PACKAGE BODY emp_demo_pkg AS

PROCEDURE open_cur (
cursor   IN OUT emp_cur_type,
dept_num IN     number) IS
BEGIN
OPEN cursor FOR SELECT * FROM emp
WHERE deptno = dept_num
ORDER BY ename ASC;
END;
END emp_demo_pkg;
/

SAMPLE11.PCO

次に、前述のSAMPLE11.sqlで宣言したカーソル変数を使用して、EMP表から従業員名、給与および歩合給をフェッチするPro*COBOLサンプル・プログラムSAMPLE11.PCOを示します。

*****************************************************************
* Sample Program 11:  Cursor Variable Operations                *
*                                                               *
* This program logs on to ORACLE, allocates and opens a cursor  *
* variable fetches the names, salaries, and commissions of all  *
* salespeople, displays the results, then closes the cursor.    *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID. CURSOR-VARIABLES.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME          PIC X(15) VARYING.
01  PASSWD            PIC X(15) VARYING.
01  HOST              PIC X(15) VARYING.
01  EMP-CUR           SQL-CURSOR.
01  EMP-INFO.
05  EMP-NUM       PIC S9(4) COMP.
05  EMP-NAM       PIC X(10) VARYING.
05  EMP-JOB       PIC X(10) VARYING.
05  EMP-MGR       PIC S9(4) COMP.
05  EMP-DAT       PIC X(10) VARYING.
05  EMP-SAL       PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
05  EMP-COM       PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
05  EMP-DEP       PIC S9(4) COMP.
01  EMP-INFO-IND.
05  EMP-NUM-IND   PIC S9(4) COMP.
05  EMP-NAM-IND   PIC S9(4) COMP.
05  EMP-JOB-IND   PIC S9(4) COMP.
05  EMP-MGR-IND   PIC S9(4) COMP.
05  EMP-DAT-IND   PIC S9(4) COMP.
05  EMP-SAL-IND   PIC S9(4) COMP.
05  EMP-COM-IND   PIC S9(4) COMP.
05  EMP-DEP-IND   PIC S9(4) COMP.
EXEC SQL END DECLARE SECTION END-EXEC.

EXEC SQL INCLUDE SQLCA END-EXEC.

01  DISPLAY-VARIABLES.
05  D-DEP-NUM     PIC Z(3)9.
05  D-EMP-NAM     PIC X(10).
05  D-EMP-SAL     PIC Z(4)9.99.
05  D-EMP-COM     PIC Z(4)9.99.
05  D-EMP-DEP     PIC 9(2).

PROCEDURE DIVISION.

BEGIN-PGM.
EXEC SQL
WHENEVER SQLERROR DO PERFORM SQL-ERROR
END-EXEC.
PERFORM LOGON.
EXEC SQL
ALLOCATE :EMP-CUR
END-EXEC.
DISPLAY "Enter department number (0 to exit):  "
WITH NO ADVANCING.
ACCEPT D-EMP-DEP.
MOVE D-EMP-DEP TO EMP-DEP.
IF EMP-DEP <= 0
GO TO SIGN-OFF
END-IF.
MOVE EMP-DEP TO D-DEP-NUM.
EXEC SQL EXECUTE
BEGIN
emp_demo_pkg.open_cur(:EMP-CUR, :EMP-DEP);
END;
END-EXEC.
DISPLAY " ".
DISPLAY "For department ", D-DEP-NUM, ":".
DISPLAY " ".
DISPLAY "EMPLOYEE   SALARY     COMMISSION".
DISPLAY "---------- ---------- ----------".

FETCH-LOOP.
EXEC SQL
WHENEVER NOT FOUND GOTO CLOSE-UP
END-EXEC.
MOVE SPACES TO EMP-NAM-ARR.
EXEC SQL FETCH :EMP-CUR
INTO :EMP-NUM:EMP-NUM-IND,
:EMP-NAM:EMP-NAM-IND,
:EMP-JOB:EMP-JOB-IND,
:EMP-MGR:EMP-MGR-IND,
:EMP-DAT:EMP-DAT-IND,
:EMP-SAL:EMP-SAL-IND,
:EMP-COM:EMP-COM-IND,
:EMP-DEP:EMP-DEP-IND
END-EXEC.
MOVE EMP-SAL TO D-EMP-SAL.
IF EMP-COM-IND = 0
MOVE EMP-COM TO D-EMP-COM
DISPLAY EMP-NAM-ARR, "   ", D-EMP-SAL,
"   ", D-EMP-COM
ELSE
DISPLAY EMP-NAM-ARR, "   ", D-EMP-SAL,
"        N/A"
END-IF.
GO TO FETCH-LOOP.

LOGON.
MOVE "SCOTT" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "TIGER" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
MOVE "INST1_ALIAS" TO HOST-ARR.
MOVE 11 TO HOST-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE AS USER: ", USERNAME-ARR.

CLOSE-UP.
EXEC SQL
CLOSE :EMP-CUR
END-EXEC.
EXEC SQL
FREE :EMP-CUR
END-EXEC.
SIGN-OFF.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY.".
DISPLAY " ".
EXEC SQL
COMMIT WORK RELEASE
END-EXEC.
STOP RUN.

SQL-ERROR.
EXEC SQL
WHENEVER SQLERROR CONTINUE
END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL
ROLLBACK WORK RELEASE
END-EXEC.
STOP RUN.

7 ホスト表

この章では、ホスト表を使用してコーディングを単純化し、プログラムのパフォーマンスを向上させる方法を説明します。ここで紹介するのは、ホスト表を使用してOracleデータを操作する方法、単一のSQL文を使用してホスト表内のすべての要素を処理する方法、処理対象となる表の要素数を制限する方法、およびグループ項目の表の使用方法です。

内容は次のとおりです。

- ホスト表

- ホスト表の利点

- 表に対する選択

- 表に対する選択

- 表に対する挿入

- 表に対する更新

- 表に対する削除

- インジケータ表の使用方法

- FOR句

- WHERE句

- CURRENT OF句の疑似実行

- ホスト変数としてのグループ項目の表

- 配列INSERTおよび配列SELECT構文の追加

- 暗黙的なバッファ済INSERTの使用

ホスト表

ホスト表(配列とも呼ぶ)とは、関連するデータ項目(要素と呼ぶ)のセットを1つの変数名に関連付けたものです。標識変数を表として定義した場合、その標識変数をインジケータ表と呼びます。インジケータ表は、NULLABLEである任意のホスト表に関連付けできます。

ホスト表の利点

ホスト表列を使用することにより、プログラミングが容易になり、パフォーマンスが大幅に向上します。通常、アプリケーションの作成には、大量のデータの格納と操作の問題が発生します。ホスト表を使用すると、複数の戻り値へのアクセスが簡単になります。

ホスト表を使用すると、1つのSQL文で複数行を操作できます。このため、特にネットワーク化された環境では、通信オーバーヘッドが著しく低減されます。たとえば、およそ300人の従業員に関する情報をEMPという表に挿入する必要があるとします。ホスト表を使用しない場合は、プログラムでは従業員ごとに1回ずつ、合計300回INSERTを実行する必要があります。ホスト表を使用した場合は、INSERTを1回実行するだけです。

DML文の表

Pro*COBOLでは、DML文でホスト表を使用できます。ホスト表は、INSERT、UPDATEおよびDELETE文の入力変数として、また、SELECT文およびFETCH文のINTO句の出力変数として使用できます。

ホスト表に使用する構文は、通常のホスト変数に使用する構文とほとんど同じです。唯一の違いは、オプションのFOR句を使用して表の処理を制御できることです。また、ホスト表と通常のホスト変数を1つのSQL文で併用する場合にはいくつかの制限があります。

ホスト表の宣言

ホスト表の宣言およびディメンション指定はデータ部で行います。次の例では、3つのホスト表を宣言し、各表のディメンションは50要素に指定されます。

....
01  EMP-TABLES.
05  EMP-NUMBER  OCCURS 50 TIMES PIC S9(4) COMP.
05  EMP-NAME    OCCURS 50 TIMES PIC X(10.
05  SALARY      OCCURS 50 TIMES PIC S9(5)V99 COMP-3.
....

次の例に示すように、OCCURS句でINDEXED BY句を使用すると、索引を指定できます。

...
01  EMP-TABLES.
05  EMP-NUMBER  PIC X(10) OCCURS 50 TIMES
INDEXED BY EMP-INDX.
...
...

このINDEXED BY句によって、索引項目EMP-INDXが暗黙的に宣言されます。

制限

多次元のホスト表は作成できません。したがって、次の例で宣言されている、2次元のホスト表は無効です。

...
01  NATION.
05  STATE                OCCURS 50 TIMES.
10  STATE-NAME       PIC X(25).
10  COUNTY           OCCURS 25 TIMES.
15  COUNTY-NAME  PIX X(25).
...

また、可変長のホスト表も使用できません。たとえば、次に示すEMP-RECの宣言はホスト変数としては無効です。

...
01  EMP-FILE.
05  REC-COUNT  PIC S9(3) COMP.
05  EMP-REC    OCCURS 0 TO 250 TIMES
DEPENDING ON REC-COUNT.
...

1つのSQL文で、1回のフェッチ操作によってアクセスできるホスト表の要素の最大数は32000です(使用するプラットフォームと使用可能なメモリーによっては、32000以上になります)。最大数を超える数のホスト表要素にアクセスすると、パラメータが範囲外であることを示すランタイム・エラーが表示されます。文が無名PL/SQLブロックの場合、アクセス可能な要素の数は、32512をデータ型のサイズで割った数に制限されます。

ホスト表の参照

また、単一のSQL文で複数のホスト表を使用する場合は、各表のディメンションは同じであることが必要です。ただし、これはPro*COBOLでは常に最小のディメンションがSQL操作に使用されるためであり、必要条件ではありません。次の例では、挿入されるのは25行のみです。

WORKING-STORAGE SECTION.
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  EMP-TABLES.
05  EMP-NUMBER   PIC S9(4) COMP OCCURS 50 TIMES.
05  EMP-NAME     PIC X(10) OCCURS 50 TIMES.
05  DEPT-NUMBER  PIC S9(4) COMP OCCURS 25 TIMES.
EXEC SQL END DECLARE SECTION END-EXEC.
...
PROCEDURE DIVISION.
...
*    Populate host tables here.
...
EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO)
VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER)
END-EXEC.

SQL文ではホスト表に添字を付けることはできません。たとえば、次のINSERT文は無効です。

WORKING-STORAGE SECTION.
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  EMP-TABLES.
05  EMP-NUMBER   PIC S9(4) COMP OCCURS 50 TIMES.
05  EMP-NAME     PIC X(10) OCCURS 50 TIMES.
05  DEPT-NUMBER  PIC S9(4) COMP OCCURS 50 TIMES.
EXEC SQL END DECLARE SECTION END-EXEC.
...
PROCEDURE DIVISION.
...
PERFORM LOAD-EMP VARYING J FROM 1 BY 1 UNTIL J > 50.
...
LOAD-EMP.
EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO)
VALUES (:EMP-NUMBER(J), :EMP-NAME(J),
:DEPT-NUMBER(J))
END-EXEC.

PERFORM VARYING文でホスト表を処理する必要はありません。そのかわりに、SQL文では添字を付けずに表名を使用してください。Pro*COBOLでは、要素数nのホスト表を含むSQL文を、同じ文をn個の異なるホスト・スカラー変数でn回実行するのと同様に、しかしより効率的に扱います。

インジケータ表の使用方法

インジケータ表を使用すると、入力ホスト表の要素にNULLを割り当てたり、出力ホスト表のNULLまたは切り捨てられた値(キャラクタ列のみ)を検出できます。次の例は、インジケータ表を使用してINSERTを実行する方法を示したものです。

WORKING-STORAGE SECTION.
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  EMP-TABLES.
05  EMP-NUMBER   PIC S9(4) COMP OCCURS 50 TIMES.
05  DEPT-NUMBER  PIC S9(4) COMP OCCURS 50 TIMES.
05  COMMISSION   PIC S9(5)V99 COMP-3 OCCURS 50 TIMES.
05  COMM-IND     PIC S9(4) COMP OCCURS 50 TIMES.
EXEC SQL END DECLARE SECTION END-EXEC.
...
PROCEDURE DIVISION.
...
*    Populate the host and indicator tables.
*    Set indicator table to all zeros.
...
EXEC SQL INSERT INTO EMP (EMPNO, DEPTNO, COMM)
VALUES (:EMP-NUMBER, :DEPT-NUMBER,
:COMMISSION:COMM-IND)
END-EXEC.

インジケータ表のディメンションは、ホスト表のディメンションと同じか、それよりも大きくする必要があります。

ホスト表SELECTおよびFETCHを使用する場合は、標識変数を使用することをお薦めします。インジケータ配列を使用すると、対応する出力ホスト表にNULLがあるかどうかをテストできます。

関連付けられた標識変数のないホスト変数にNULLが選択またはフェッチされると、プログラムは処理を停止し、sqlca.sqlerrd(3)を処理した行数に設定して、エラーを戻します。

デフォルトではNULLが選択されますが、UNSAFE_NULL = YESオプションを使用して、これをオフにすることもできます。

DBMS=V7またはV8のときは、切捨てはエラーとみなされません。

表を含んでいるホスト・グループ項目

注意: 表を含むホスト・グループ項目の場合は、インジケータに対応する表のグループ項目を使用する必要があります。たとえば、次のようなグループ項目を考えます。

01  DEPARTURE.
05 HOUR    PIC X(2) OCCURS 3 TIMES.
05 MINUTE  PIC X(2) OCCURS 3 TIMES.

この場合、次の標識変数は使用できません。

01  DEPARTURE-IND PIC S9(4) COMP OCCURS 6 TIMES.

表のグループ項目に使用する標識変数は、次のように、それ自体が表のグループ項目であることが必要です。

01  DEPARTURE-IND.
05 HOUR-IND   PIC S9(4) COMP OCCURS 3 TIMES.
05 MINUTE-IND PIC S9(4) COMP OCCURS 3 TIMES.

Oracleでの制限

VALUES、SET、INTOまたはWHERE句では、スカラー・ホスト変数とホスト表を併用できません。ホスト変数のうちのどれか1つがホスト表の場合は、すべてのホスト変数がホスト表であることが必要です。

UPDATEまたはDELETE文のCURRENT OF句では、ホスト表は使用できません。

ANSIでの制限および要件

配列インタフェースは、ANSI/ISOの埋込みSQL規格に対するOracle拡張機能です。ただし、MODE=ANSIでプリコンパイルすると、配列のSELECTおよびFETCHは使用できます。必要であれば、FIPSフラガー・プリコンパイラ・オプションによって、配列を使用していることをフラグで示すことができます。

表に対する選択

ホスト表をSELECT文の出力変数として使用できます。選択で戻される行の最大数がわかっている場合は、それと同じ数の要素数でホスト表を定義してください。次の例では、選択結果を直接3つのホスト表に入れます。表は50行で定義されていますが、選択で戻されるのは50行以下です。

01  EMP-REC-TABLES.
05  EMP-NUMBER   OCCURS 50 TIMES PIC S9(4) COMP.
05  EMP-NAME     OCCURS 50 TIMES PIC X(10) VARYING.
05  SALARY       OCCURS 50 TIMES PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
...
EXEC SQL SELECT ENAME, EMPNO, SAL
INTO :EMP-NAME, :EMP-NUMBER, :SALARY
FROM EMP
WHERE SAL > 1000
END-EXEC.

この例ではSELECT文は50行までの行を戻します。選択される行数が49行以下の場合、または50行のみを取り出す場合はこの方法を使用します。ただし、選択される行数が51行以上の場合は、この方法ではすべての行を取り出せません。このSELECT文を再実行しても、他に選択対象の行があるとしても、最初の50行のみがまた戻されます。このような場合は、大きな表を定義するか、FETCH文に使用するカーソルを宣言する必要があります。

SELECT_ERROR=NOと指定していない場合に、定義した表サイズよりもSELECT INTO文で戻される行数が多いと、Oracleはエラー・メッセージを出力します。詳細は、「SELECT_ERROR」を参照してください。

バッチ・フェッチ

処理するデータのサイズが大きい(100行以上)場合や戻される行数が不明な場合は、バッチ・フェッチを使用してください。

選択によって戻される行の最大数が不明な場合は、カーソルを宣言およびオープンして、そこからバッチでフェッチできます。ループ内でバッチ・フェッチを実行すると、多数の行を簡単に取り出せます。フェッチを行うたびに、現行のアクティブ・セットから次のバッチの行が戻されます。次の例では、20行ずつまとめて行をフェッチします。

...
01  EMP-REC-TABLES.
05  EMP-NUMBER    OCCURS 20 TIMES PIC S9(4) COMP.
05  EMP-NAME      OCCURS 20 TIMES PIC X(10) VARYING.
05  SALARY        OCCURS 20 TIMES PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
...
EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT EMPNO, SAL FROM EMP
END-EXEC.
...
EXEC SQL OPEN EMPCURSOR END-EXEC.
...
EXEC SQL WHENEVER NOT FOUND DO PERFORM END-IT.
LOOP.
EXEC SQL FETCH EMPCURSOR INTO :EMP-NUMBER, :SALARY END-EXEC.
* --  process batch of rows
...
GO TO LOOP.
END-IT.
...

最後のフェッチで実際に戻された行数を必ずチェックし、その行を処理してください。詳細は、「サンプル・プログラム3: バッチでのフェッチ」を参照してください。

SQLERRD(3)の使用方法

INSERT、UPDATEおよびDELETE文では、処理された行数はSQLERRD(3)に格納されます。

SQLERRD(3)は、表の操作中にエラーが発生したときにも役に立ちます。処理はエラーを引き起こした行で停止するため、SQLERRD(3)を調べることによって正常に処理された行数がわかります。

フェッチされる行数

それぞれのフェッチで戻される行数は、最大でも表のエントリと同じ数です。次のような場合は最大行数より少ない行が戻ります。

- アクティブ・セットの最後に達したとき:「データが見つかりません。」という警告コードがSQLCAのSQLCODEに戻されます。たとえば、エントリ数が100の表に対してフェッチを行い20行しか戻らなかった場合です。

- 残っているフェッチ対象の行が、一括フェッチの全行数より少ないとき。たとえば、エントリ数が20の表に対して70行をフェッチした場合、3回目のフェッチの後ではフェッチ対象の行が10行しか残っていないため、このような状況が発生します。

- 行の処理中にエラーが検出されたとき。フェッチは失敗し、該当するエラー・コードがSQLCODEに戻されます。

戻された行の累計数は、SQLCA内のSQLERRDの3番目の要素(このマニュアルではSQLERRD(3)と呼びます)に格納されます。これはオープン状態のすべてのカーソルに適用されます。次の例では、カーソルの状態がそれぞれ更新されている様子がわかります。

EXEC SQL OPEN CURSOR1 END-EXEC.
EXEC SQL OPEN CURSOR2 END-EXEC.
EXEC SQL FETCH CURSOR1 INTO :TABLE-OF-20 END-EXEC.
* --  now running total in SQLERRD(3) is 20
EXEC SQL FETCH CURSOR2 INTO :TABLE-OF-30 END-EXEC.
* --  now running total in SQLERRD(3) is 30, not 50
EXEC SQL FETCH CURSOR1 INTO :TABLE-OF-20 END-EXEC.
* --  now running total in SQLERRD(3) is 40 (20 + 20)
EXEC SQL FETCH CURSOR2 INTO :TABLE-OF-30 END-EXEC.
* --  now running total in SQLERRD(3) is 60 (30 + 30)

ホスト表の使用制限

SELECT文のWHERE句では、副問合せ内でのみ表を使用できます。(例は、「WHERE句」を参照してください。)また、Pro*COBOLは常に最小の表サイズを取得します。1行のみが取得されるため、SELECT文またはFETCH文のINTO句では単純ホスト変数とホスト表を併用しないでください。ホスト変数のうちのどれか1つが表の場合は、すべてのホスト変数が表であることが必要です。

表7-1に、SELECT INTO文に有効なホスト表の使用方法を示します。

表7-1 SELECT INTO文に有効なホスト表

INTO句

WHERE句

有効/無効

表

表

無効

スカラー

スカラー

有効

表

スカラー

有効

スカラー

表

無効

NULLのフェッチ

UNSAFE_NULL=YESの場合は、インジケータ表のないホスト表に対してNULLを選択またはフェッチしてもエラーが生成されません。したがって、表の選択およびフェッチを行うときには、インジケータ表の使用をお薦めします。これにより、対応付けられた出力ホスト表のNULLが容易に検索できるようになります。(NULLおよび切り捨てられた値の検出方法は、「標識変数の使用方法」を参照してください。)

UNSAFE_NULL=NOの場合は、インジケータ表のないホスト表に対してNULLを選択またはフェッチすると、Oracleは処理を停止し、処理した行数をSQLERRD(3)に設定して、エラー・メッセージを出力します。

切り捨てられた値のフェッチ

インジケータ表のないホスト表に対して切り捨てられた列値を選択またはフェッチすると、OracleはSQLWARN(2)を設定します。

SQLERRD(3)を調べると、切捨てが行われるまでに処理された行数がわかります。処理済行数には切捨てエラーが発生した行も含まれます。

表の選択およびフェッチを行うときには、インジケータ表を使用できます。インジケータ表を使用すると、Oracleが1つ以上の切り捨てられた列値を出力ホスト表に割り当てた場合に、対応するインジケータ表を調べることによってその列値の元の長さを確認できます。

サンプル・プログラム3: バッチでのフェッチ

次のホスト表のサンプル・プログラムは、デモ・ディレクトリに入っています。

*****************************************************************
* Sample Program 3:  Host Tables                                *
*                                                               *
* This program logs on to ORACLE, declares and opens a cursor,  *
* fetches in batches using host tables, and prints the results. *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID. HOST-TABLES.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME          PIC X(15) VARYING.
01  PASSWD            PIC X(15) VARYING.
01  EMP-REC-TABLES.
05  EMP-NUMBER    OCCURS 5 TIMES PIC S9(4) COMP.
05  EMP-NAME      OCCURS 5 TIMES PIC X(10) VARYING.
05  SALARY        OCCURS 5 TIMES PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
EXEC SQL VAR SALARY IS DISPLAY(8,2) END-EXEC.
EXEC SQL END DECLARE SECTION END-EXEC.
EXEC SQL INCLUDE SQLCA END-EXEC.
01  NUM-RET           PIC S9(9) COMP VALUE ZERO.
01  PRINT-NUM         PIC S9(9) COMP VALUE ZERO.
01  COUNTER           PIC S9(9) COMP.
01  DISPLAY-VARIABLES.
05  D-EMP-NAME    PIC X(10).
05  D-EMP-NUMBER  PIC 9(4).
05  D-SALARY      PIC Z(4)9.99.

PROCEDURE DIVISION.

BEGIN-PGM.
EXEC SQL
WHENEVER SQLERROR DO PERFORM SQL-ERROR
END-EXEC.
PERFORM LOGON.
EXEC SQL
DECLARE C1 CURSOR FOR
SELECT EMPNO, SAL, ENAME
FROM EMP
END-EXEC.
EXEC SQL
OPEN C1
END-EXEC.

FETCH-LOOP.
EXEC SQL
WHENEVER NOT FOUND DO PERFORM SIGN-OFF
END-EXEC.
EXEC SQL
FETCH C1
INTO :EMP-NUMBER, :SALARY, :EMP-NAME
END-EXEC.
SUBTRACT NUM-RET FROM SQLERRD(3) GIVING PRINT-NUM.
PERFORM PRINT-IT.
MOVE SQLERRD(3) TO NUM-RET.
GO TO FETCH-LOOP.

LOGON.
MOVE "SCOTT" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "TIGER" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE AS USER:  ", USERNAME-ARR.

PRINT-IT.
DISPLAY " ".
DISPLAY "EMPLOYEE NUMBER  SALARY   EMPLOYEE NAME".
DISPLAY "---------------  -------  -------------".
PERFORM PRINT-ROWS
VARYING COUNTER FROM 1 BY 1
UNTIL COUNTER > PRINT-NUM.

PRINT-ROWS.
MOVE EMP-NUMBER(COUNTER) TO D-EMP-NUMBER.
MOVE SALARY(COUNTER) TO D-SALARY.
DISPLAY "           ", D-EMP-NUMBER, " ", D-SALARY, "  ",
EMP-NAME-ARR IN EMP-NAME(COUNTER).
MOVE SPACES TO EMP-NAME-ARR IN EMP-NAME(COUNTER).

SIGN-OFF.
SUBTRACT NUM-RET FROM SQLERRD(3) GIVING PRINT-NUM.
IF (PRINT-NUM > 0) PERFORM PRINT-IT.
EXEC SQL
CLOSE C1
END-EXEC.
EXEC SQL
COMMIT WORK RELEASE
END-EXEC.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY.".
DISPLAY " ".
STOP RUN.

SQL-ERROR.
EXEC SQL
WHENEVER SQLERROR CONTINUE
END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL
ROLLBACK WORK RELEASE
END-EXEC.
STOP RUN.

表に対する挿入

ホスト表は、INSERT文の入力変数として使用できます。その場合、INSERT文の実行前に表にデータが挿入されるようにプログラムを作成してください。表の中に不適切な要素がある場合は、FOR句を使用して挿入する行数を制御できます。「FOR句」を参照してください。

次に、ホスト表に対する挿入の例を示します。

01  EMP-REC-TABLES.
05  EMP-NUMBER    OCCURS 50 TIMES PIC S9(4) COMP.
05  EMP-NAME      OCCURS 50 TIMES PIC X(10) VARYING.
05  SALARY        OCCURS 50 TIMES PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
* -- populate the host tables
EXEC SQL INSERT INTO EMP (ENAME, EMPNO, SAL)
VALUES (:EMP-NAME, :EMP-NUMBER, :SALARY)
END-EXEC.

挿入された行数は、SQLERRD(3)を調べます。

SQL文ではホスト表に添字を付けることはできません。たとえば、次のINSERT文は無効です。

PERFORM VARYING I FROM 1 BY 1 UNTIL I = TABLE-DIMENSION.
EXEC SQL INSERT INTO EMP (ENAME, EMPNO, SAL)
VALUES (:EMP-NAME(I), :EMP-NUMBER(I), :SALARY(I))
END_EXEC
END-PERFORM.

ホスト表の使用制限

INSERT、UPDATEまたはDELETE文のVALUES句に単純ホスト変数とホスト表を併用すると、ホスト表の最初の要素のみ処理されます。Pro*COBOLは常に宣言された最小のディメンションを使用し、単純ホスト変数はディメンション1のホスト表として扱われるためです。この場合には警告が表示されます。

表に対する更新

次の例に示すように、UPDATE文の入力変数としてもホスト表を使用できます。

01  EMP-REC-TABLES.
05  EMP-NUMBER    OCCURS 50 TIMES PIC S9(4) COMP.
05  SALARY        OCCURS 50 TIMES PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
...
* --  populate the host tables
EXEC SQL
UPDATE EMP SET SAL = :SALARY WHERE EMPNO = :EMP-NUMBER
END-EXEC.

この文を発行して更新された行数は、SQLERRD(3)を調べます。更新された行数がホスト表の行数と同じとはかぎりません。その行数には、更新カスケード(後続の更新を実行させる)によって処理された行は含まれていません。

表の中に不適切な要素がある場合は、FOR句を使用することによって更新する行数を制限できます。

前述の例は、一意キー(EMP-NUMBER)を使用した典型的な更新を示しています。この例では、表の各要素によって更新されるのは1行のみです。次の例では、表の1つの要素によって複数行が削除されます。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
05  JOB-TITLE      OCCURS 10 TIMES PIC X(10) VARYING.
05  COMMISSION     OCCURS 50 TIMES PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
EXEC SQL END DECLARE SECTION END-EXEC.
* --  populate the host tables
EXEC SQL
UPDATE EMP SET COMM = :COMMISSION WHERE JOB = :JOB-TITLE
END-EXEC.

UPDATEでの制限

UPDATE文のCURRENT OF句ではホスト表は使用できません。他の方法は、「CURRENT OF句の擬似実行」を参照してください。

表7-2に、UPDATE文に有効なホスト表の使用方法を示します。

表7-2 UPDATE文に有効なホスト表

SET句

WHERE句

有効/無効

表

表

有効

スカラー

スカラー

有効

表

スカラー

無効

スカラー

表

無効

表に対する削除

ホスト表をDELETE文の入力変数としても使用できます。これは、WHERE句でそのホスト表の連続した要素を使用してDELETE文を繰返し実行するのと同様です。つまり1回の実行で表から0行、1行または複数行が削除されます。次に示すのは、ホスト表を使用した削除の例です。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
05  EMP-NUMBER    OCCURS 50 TIMES PIC S9(4) COMP.
EXEC SQL END DECLARE SECTION END-EXEC.
* --  populate the host table
EXEC SQL
DELETE FROM EMP WHERE EMPNO = :EMP-NUMBER
END-EXEC.

削除された行の累計数は、SQLERRD(3)を調べます。この累計数には、削除カスケードで処理された行は含まれません。

次に、一意キー(EMP-NUMBER)を使用した典型的な削除の例を示します。この例では、表の各要素によって削除されるのは1行のみです。次の例では、表の1つの要素によって複数行が削除されます。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
05  JOB-TITLE    OCCURS 10 TIMES PIC X(10) VARYING.
EXEC SQL END DECLARE SECTION END-EXEC.
* --  populate the host table
EXEC SQL
DELETE FROM EMP WHERE JOB = :JOB-TITLE
END-EXEC.

DELETEでの制限

DELETE文のCURRENT OF句ではホスト表は使用できません。他の方法は、「CURRENT OF句の擬似実行」を参照してください。

インジケータ表の使用方法

インジケータ表は、ホスト表にNULLを割り当てる場合や、出力ホスト表の中のNULLまたは切り捨てられた値の検出に使用します。次に、インジケータ表を使用した挿入方法の例を示します。

01  EMP-REC-VARS.
05  EMP-NUMBER  OCCURS 50 TIMES PIC S9(4) COMP.
05  DEPT-NUMBER OCCURS 50 TIMES PIC S9(4) COMP.
05  COMMISSION  OCCURS 50 TIMES  PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
* -- indicator table:
05  COMM-IND    OCCURS 50 TIMES  PIC S9(4) COMP.
* --  populate the host tables
* --  populate the indicator table; to insert a NULL into
* --  the COMM column, assign -1 to the appropriate element in
* --  the indicator table
EXEC SQL
INSERT INTO EMP (EMPNO, DEPTNO, COMM)
VALUES (:EMP_NUMBER, :DEPT-NUMBER, :COMMISSION:COMM-IND)
END-EXEC.

インジケータ表のエントリ数をホスト表のエントリ数より少なくすることはできません。

FOR句

オプションのFOR句を使用すると、次のSQL文で処理する表要素の数を設定できます。

- DELETE

- EXECUTE (Oracle動的SQLは第11章「Oracle動的SQL: 方法4」を参照)。

- FETCH

- INSERT

- OPEN

- UPDATE

特にUPDATE、INSERTおよびDELETE文内でFOR句を使用すると便利です。これらの文では、表全体を使用する必要がない場合があります。次の例に示すように、FOR句を使用すると、使用する要素数を任意の数に制限できます。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  EMP-REC-VARS.
05  EMP-NAME  OCCURS 1000 TIMES  PIC X(20) VARYING.
05  SALARY    OCCURS 100  TIMES  PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
01 ROWS-TO-INSERT PIC S9(4) COMP.
EXEC SQL END DECLARE SECTION END-EXEC.
* --  populate the host tables
MOVE 25 TO ROWS-TO-INSERT.
* -- set FOR-clause variable
* -- will process only 25 rows
EXEC SQL FOR :ROWS-TO-INSERT
INSERT INTO EMP (ENAME, SAL)
VALUES (:EMP-NAME, :SALARY)
END-EXEC.

FOR句では、表の要素数の指定には整数のホスト変数を使用する必要があります。たとえば、次の文は無効です。

* -- illegal
EXEC SQL FOR 25
INSERT INTO EMP (ENAME, EMPNO, SAL)
VALUES (:EMP-NAME, :EMP-NUMBER, :SALARY)
END-EXEC.

FOR句の変数によって、処理する表要素の数を指定します。その数は、表の最小ディメンションより大きくしないでください。内部では、値は符号なしの数量として扱われます。符号付きのホスト変数を使用して負の値を渡すと、予測不能な動作が発生する原因となります。

制限

FOR句のセマンティクスを明確にするための制限が2つあります。FOR句は、SELECT文での使用またはCURRENT OF句との併用はできません。

SELECT文での使用

SELECT文でFOR句を使用すると、エラー・メッセージが戻されます。

FOR句は意味があいまいなため、SELECT文中では使用できません。「このSELECT文をn回実行する」なのか、「このSELECT文を1回実行し、n行戻す」なのかはっきりしません。問題は、前者の場合、実行のたびに複数の行が戻される可能性があることです。後者の解釈では、次に示すように、カーソルを宣言してからFETCH文中でFOR句を使用することをお薦めします。

EXEC SQL FOR :LIMIT FETCH EMPCURSOR INTO ...

CURRENT OF句との併用

次の例に示すように、UPDATEまたはDELETE文でCURRENT OF句を使用すると、FETCH文によって戻される最後の行を参照できます。

EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT ENAME, SAL FROM EMP WHERE EMPNO = :EMP-NUMBER
END-EXEC.
...
EXEC SQL OPEN EMPCURSOR END-EXEC.
...
EXEC SQL FETCH emp_cursor INTO :EM-NAME, :SALARY END-EXEC.
...
EXEC SQL UPDATE EMP SET SAL = :NEW-SALARY
WHERE CURRENT OF EMPCURSOR
END-EXEC.

ただし、CURRENT OF句とFOR句は併用できません。次の文はLIMITの論理値が1に限定されている(カレント行の更新または削除は1回しかできない)ため無効です。

EXEC SQL FOR :LIMIT UPDA-CURSOR END-EXEC.
...
EXEC SQL FOR :LIMIT DELETE FROM EMP
WHERE CURRENT OF emp_cursor
END-EXEC.

WHERE句

Pro*COBOLでは、エントリ数nのホスト表を使用したSQL文は、n個の異なるスカラー変数(表の個々の要素)を使用してそのSQL文をn回実行した場合と同じように扱われます。文意が不明瞭なためにこのような処理ができない場合にのみ、プリコンパイラはエラー・メッセージを出力します。

たとえば、次の宣言を指定するとします。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
05  MGRP-NUMBER  OCCURS 50 TIMES  PIC S9(4) COMP.
05  JOB-TITLE    OCCURS 50 TIMES  PIC X(20) VARYING.
01  I PIC S9(4) COMP.
EXEC SQL END DECLARE SECTION END-EXEC.

この宣言部は、次の文を使用すると、不明瞭になる場合があります。

EXEC SQL SELECT MGR INTO :MGR-NUMBER FROM EMP
WHERE JOB = :JOB-TITLE
END-EXEC.

この文が、次の文と同様に処理された場合です。

PERFORM VARYING I FROM 1 BY 1 UNTIL I = 50
SELECT MGR INTO :MGR-NUMBER(I) FROM EMP
WHERE JOB = :JOB_TITLE(I)
END-EXEC
END-PERFORM.

WHERE句の検索条件を満たす複数行があっても、データの受取りに使用できる出力変数が1つしかないためです。したがって、エラー・メッセージが出力されます。

一方、次の文を使用すると、不明瞭にならない場合があります。

EXEC SQL
UPDATE EMP SET MGR = :MGR_NUMBER
WHERE EMPNO IN (SELECT EMPNO FROM EMP WHERE
JOB = :JOB-TITLE)
END-EXEC.

この文が、次の文と同様に処理された場合です。

PERFORM VARYING I FROM 1 BY 1 UNTIL I = 50
UPDATE EMP SET MGR = :MGR_NUMBER(I)
WHERE EMPNO IN
(SELECT EMPNO FROM EMP WHERE JOB = :JOB-TITLE(I))
END-EXEC
END-PERFORM.

これは、WHERE句の各JOB-TITLEに該当する複数行がある場合でも、JOB-TITLEに該当する行のそれぞれに対してSET句内にMGR-NUMBERが存在するためです。それぞれのJOB-TITLEに該当するすべての行を、同じMGR-NUMBERにSETできるため、エラー・メッセージは出力されません。

CURRENT OF句の疑似実行

CURRENT OF句を使用すると、カーソルの最新の行に対してUPDATEまたはDELETEを実行できます。CURRENT OF句を使用すると、FOR UPDATE句がカーソルに追加されます。この句を追加することは、カーソルで識別されたすべての行を排他モードでロックする効果があります。CURRENT OF句はホスト表には使用できません。かわりに、カーソルの定義にFOR UPDATEを追加し、ROWID列を明示的に選択して、その値を使用して更新または削除の実行時にカレント行を識別できます。次に、例を示します。

05  EMP-NAME    OCCURS 25 TIMES PIC X(20) VARYING.
05  JOB-TITLE   OCCURS 25 TIMES PIC X(15) VARYING.
05  OLD-TITLE   OCCURS 25 TIMES PIC X(15) VARYING.
05  ROW-ID      OCCURS 25 TIMES PIC X(18) VARYING.
...
EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT ENAME, JOB, ROWID FROM EMP
FOR UPDATE
END-EXEC.
...
EXEC SQL OPEN EMPCURSOR END-EXEC.
...
EXEC SQL WHENEVER NOT FOUND GOTO ...
...
PERFORM
EXEC SQL
FETCH EMPCURSOR
INTO :EMP-NAME, :JOB-TITLE, :ROW-ID
END-EXEC
...
EXEC SQL
DELETE FROM EMP
WHERE JOB = :OLD-TITLE AND ROWID = :ROW-ID
END-EXEC
EXEC SQL COMMIT WORK END-EXEC
END-PERFORM.

ホスト変数としてのグループ項目の表

Pro*COBOLでは、埋込みSQL文でグループ項目(レコードとも呼ばれます)の表を使用できます。グループ項目の表は、SELECTまたはFETCH文のINTO句、およびINSERT文のVALUESリストで参照できます。

次に例を示します。

01    TABLES.
05   EMP-TABLE           OCCURS 20 TIMES.
10    EMP-NUMBER    PIC S9(4) COMP.
10    EMP-NAME      PIC X(10).
10    DEPT-NUMBER   PIC S9(4) COMP.

このように宣言した場合、次の文は有効です。

EXEC SQL INSERT INTO EMP(EMPNO, ENAME, DEPTNO)
VALUES(:EMP-TABLE)
END-EXEC.

グループ項目にデータがすでに入っているとみなして、この文によって、従業員番号、従業員名および部門番号で構成された行が20行一括してEMP表に挿入されます。

グループ項目の順序がSQL文内での順序と同じであることを確認してください。

標識変数を使用するには、グループ項目の各変数の標識変数を含むグループ項目表を別に設定します。

01     TABLES-IND.
05   EMP-TABLE-IND  OCCURS 20 TIMES.
10   EMP-NUMBER-IND       PIC S9(4) COMP.
10   EMP-NAME-IND         PIC S9(4) COMP.
10   DEPT-NUMBER_IND      PIC S9(4) COMP.

グループ項目のホスト・インジケータ表は、次のように使用できます。

EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO)
VALUES (:EMP-TABLE:EMP-TABLE-IND)
END-EXEC.

データの特徴が正確にわかっている場合は、基本項目のインジケータをグループ項目に指定すると便利です。

05    EMP-TABLE-IND     PIC S9(4) COMP
OCCURS 20 TIMES.

グループ項目のホスト表には、表であるグループ項目を入れることはできません。次に例を示します。

01   TABLES.
05   EMP-TABLE               OCCURS 20 TIMES.
10  EMP-NUMBER          PIC S9(4) COMP OCCURS 10 TIMES.
10  EMP-NAME            PIC X(10).
10  DEPT-NUMBER         PIC S9(4) COMP.

EMP-NUMBERは表であるため、EMP-TABLEはホスト変数として使用できません。

ネストされたグループ項目のホスト表は使用できません。次に例を示します。

01   TABLES.
05   TEAM-TABLE                   OCCURS 20 TIMES
10   EMP-TABLE
15   EMP-NUMBER         PIC S9(4) COMP.
15   EMP-NAME           PIC X(10).
10   DEPT-TABLE.
15   DEPT-NUMBER        PIC S9(4) COMP.
15   DEPT-NAME          PIC X(10).

メンバー(EMP-TABLEおよびDEPT-TABLE)自体がグループ項目であるため、TEAM-TABLEはホスト変数として使用できません。

また、Pro*COBOLでホスト表に適用される制限は、グループ項目の表にも適用されます。

- 多次元のホスト表および可変長のホスト表は作成できません。

- 単一のSQL文で複数の表を使用する場合、各表のディメンションは同じであることが必要です。

- SQL文のホスト表には添字を付けないでください。

サンプル・プログラム14: グループ項目の表

このプログラムで、ログインし、カーソルを宣言およびオープンし、グループ項目の表を使用してバッチでフェッチを行います。詳細は、最初のコメントを参照してください。

*****************************************************************
* Sample Program 14:  Tables of group items                     *
*                                                               *
* This program logs on to ORACLE, declares and opens a cursor,  *
* fetches in batches using a table of group items , and prints  *
* the results.  This sample is identical to sample3 except that *
* instead of using three separate host tables of five elements  *
* each, it uses a five-element table of three group items.      *
* The output should be identical.                               *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID. TABLE-OF-GROUP-ITEMS.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME          PIC X(15) VARYING.
01  PASSWD            PIC X(15) VARYING.
01  EMP-REC-TABLE OCCURS 5 TIMES.
05  EMP-NUMBER    PIC S9(4) COMP.
05  SALARY        PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
05  EMP-NAME      PIC X(10) VARYING.
EXEC SQL VAR SALARY IS DISPLAY(8,2) END-EXEC.
EXEC SQL END DECLARE SECTION END-EXEC.
EXEC SQL INCLUDE SQLCA END-EXEC.
01  NUM-RET           PIC S9(9) COMP VALUE ZERO.
01  PRINT-NUM         PIC S9(9) COMP VALUE ZERO.
01  COUNTER           PIC S9(9) COMP.
01  DISPLAY-VARIABLES.
05  D-EMP-NAME    PIC X(10).
05  D-EMP-NUMBER  PIC 9(4).
05  D-SALARY      PIC Z(4)9.99.

PROCEDURE DIVISION.

BEGIN-PGM.
EXEC SQL
WHENEVER SQLERROR DO PERFORM SQL-ERROR
END-EXEC.
PERFORM LOGON.
EXEC SQL
DECLARE C1 CURSOR FOR
SELECT EMPNO, SAL, ENAME
FROM EMP
END-EXEC.
EXEC SQL
OPEN C1
END-EXEC.

FETCH-LOOP.
EXEC SQL
WHENEVER NOT FOUND DO PERFORM SIGN-OFF
END-EXEC.
EXEC SQL
FETCH C1
INTO :EMP-REC-TABLE
END-EXEC.
SUBTRACT NUM-RET FROM SQLERRD(3) GIVING PRINT-NUM.
PERFORM PRINT-IT.
MOVE SQLERRD(3) TO NUM-RET.
GO TO FETCH-LOOP.

LOGON.
MOVE "SCOTT" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "TIGER" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE AS USER:  ", USERNAME-ARR.

PRINT-IT.
DISPLAY " ".
DISPLAY "EMPLOYEE NUMBER  SALARY   EMPLOYEE NAME".
DISPLAY "---------------  -------  -------------".
PERFORM PRINT-ROWS
VARYING COUNTER FROM 1 BY 1
UNTIL COUNTER > PRINT-NUM.

PRINT-ROWS.
MOVE EMP-NUMBER(COUNTER) TO D-EMP-NUMBER.
MOVE SALARY(COUNTER) TO D-SALARY.
DISPLAY "           ", D-EMP-NUMBER, " ", D-SALARY, "  ",
EMP-NAME-ARR IN EMP-NAME(COUNTER).
MOVE SPACES TO EMP-NAME-ARR IN EMP-NAME(COUNTER).

SIGN-OFF.
SUBTRACT NUM-RET FROM SQLERRD(3) GIVING PRINT-NUM.
IF (PRINT-NUM > 0) PERFORM PRINT-IT.
EXEC SQL
CLOSE C1
END-EXEC.
EXEC SQL
COMMIT WORK RELEASE
END-EXEC.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY.".
DISPLAY " ".
STOP RUN.

SQL-ERROR.
EXEC SQL
WHENEVER SQLERROR CONTINUE
END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL
ROLLBACK WORK RELEASE
END-EXEC.
STOP RUN.

配列INSERTおよび配列SELECT構文の追加

Oracleプリコンパイラでは、ホスト表に対するDB2のINSERTおよびFETCH構文もサポートされています。次に、サポートされている追加の配列INSERTおよび配列FETCH構文をそれぞれ次の図で示します。

図7-1 追加のINSERT構文

図7-2 追加のFETCH構文

オプションでROWSET句とROWSET STARTING AT句がフェッチの方向(FIRST, PRIOR, NEXT, LAST, CURRENT, RELATIVEおよびABSOLUTE)で使用されます。次の例を考えてみます。

- FIRST ROWSET

- PRIOR ROWSET

- NEXT ROWSET

- LAST ROWSET

- CURRENT ROWSET

- ROWSET STARTING AT RELATIVEn

- ROWSET STARTING AT ABSOLUTEn

表7-3に、DB2の配列INSERT構文、配列FETCH構文の例と、対応するOracleプリコンパイラの構文との比較を示します。

表7-3 DB2の配列構文とOracleプリコンパイラの構文

DB2の配列構文

Oracleプリコンパイラの構文

EXEC SQL
INSERT INTO DSN8810.ACT
(ACTNO, ACTKWD, ACTDESC)
VALUES (:HVA1, :HVA2, :HVA3)
FOR :NUM_ROWS ROWS
END-EXEC.

EXEC SQL FOR :NUM_ROWS
INSERT INTO DSN8810.ACT
(ACTNO, ACTKWD, ACTDESC)
VALUES (:HVA1, :HVA2, :HVA3)
END-EXEC.

EXEC SQL
FETCH NEXT ROWSET FROM C1
FOR 20 ROWS
INTO :HVA_EMPNO, :HVA_LASTNAME,
:HVA_SALARY
END-EXEC.

EXEC SQL
FOR :TWENTY
FETCH c1
INTO :HVA_EMPNO, :HVA_LASTNAME,
:HVA_SALARY
END-EXEC.

DB2の構文では、行セットに位置付けられたカーソルは、データの行セットを取得する前に最初に宣言する必要があります。カーソルが行セットをフェッチできるようにするには、DECLARE CURSOR文で「WITH ROWSET POSITIONING」句を使用する必要があります。これは、次の表に示すように、Oracleプリコンパイラの構文では必要なく、関連もありません。

DB2の配列構文

Oracleプリコンパイラの構文

EXEC SQL
DECLARE C1 CURSOR
WITH ROWSET POSITIONING FOR
SELECT EMPNO, LASTNAME, SALARY
FROM DSN8810.EMP
END-EXEC.

EXEC SQL
DECLARE C1 CURSOR FOR
SELECT EMPNO, LASTNAME, SALARY
FROM DSN8810.EMP
END-EXEC.

この追加の配列構文のサポートは、プリコンパイラ・オプション「db2_array」を指定して有効にできます。デフォルトのオプションは「no」です。DB2配列構文のサポートは、Oracleプリコンパイラ構文と一緒に使用できません。一度にサポートされるのは、Oracleプリコンパイラ構文またはDB2構文のいずれか一方の構文のみです。

例7-1 DB2の配列構文を使用した行の挿入およびフェッチ

このプログラムでは、DB2の配列INSERT構文を使用して、EMP表にINSCNT行を挿入します。その後、DB2の配列FETCH構文を使用して、挿入された行をフェッチします。

*****************************************************************
* db2arrdemo:                                                   *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID.  db2arrdemo.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.

* EMBEDDED COBOL (file "DB2ARRDEMO.PCO")

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME          PIC X(10) VARYING.
01  PASSWD            PIC X(10) VARYING.
01  EMPINDATA.
02  EMPIN OCCURS 25 TIMES.
03  EMPNO PIC  9(4) COMP.
03  ENAME PIC  X(10).
03  JOB PIC  X(9).
03  MGR PIC 9(4).
03  HIREDATE PIC  X(9).
03  SAL PIC  X(6).
03  COMM PIC  X(6).
03  DEPTNO PIC  9(2).

01  EMPOUTDATA.
02  EMPOUT OCCURS 5 TIMES.
03  EMPNO1 PIC  9(4) COMP.
03  ENAME1 PIC  X(10).
03  JOB1 PIC  X(9).
03  MGR1 PIC 9(4).
03  HIREDATE1 PIC  X(9).
03  SAL1 PIC  X(6).
03  COMM1 PIC  X(6).
03  DEPTNO1 PIC  9(2).

EXEC SQL END DECLARE SECTION END-EXEC.

01  INSCNT PIC  9(3) COMP VALUE 25.
01  FETCHCNT PIC  9(3) COMP VALUE 5.
01  CNT PIC  9(4).
01  CNT2 PIC  9(2).

01  STRINGFIELDS.
02 STR PIC X(18) VARYING.

EXEC SQL INCLUDE SQLCA END-EXEC.

PROCEDURE DIVISION.
BEGIN-PGM.
EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC.

PERFORM LOGON.

* Fill the array elements to insert.
PERFORM FILL-DATA VARYING CNT FROM 1 BY 1
UNTIL CNT > INSCNT.

* Inserting data using DB2 array insert syntax.
DISPLAY "Inserting data using DB2 array insert syntax".
EXEC SQL INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE,
SAL, COMM, DEPTNO) VALUES (:EMPIN)
FOR :INSCNT ROWS
END-EXEC.

EXEC SQL SELECT COUNT(*) INTO :CNT FROM EMP
WHERE ENAME LIKE 'EMP_%'
END-EXEC.
DISPLAY "Number of rows successfully inserted into EMP "
"table:", CNT.

DISPLAY " ".
* Declares scrollable cursor to fetch data.
EXEC SQL DECLARE C1 SCROLL CURSOR FOR
SELECT EMPNO, ENAME, JOB, MGR, HIREDATE, SAL,
COMM, DEPTNO
FROM EMP
WHERE ENAME LIKE 'EMP_%'
ORDER BY EMPNO
END-EXEC.

EXEC SQL OPEN C1 END-EXEC.

DISPLAY "Fetching data using DB2 array fetch syntax ".
PERFORM FETCH-TAB.
ENDFETCH-TAB.

EXEC SQL CLOSE C1 END-EXEC.

EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

LOGON.
MOVE "scott" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "tiger" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.

* FILLS ARRAY TO INSERT INTO EMP TABLE
FILL-DATA.
MOVE CNT TO EMPNO(CNT).

MOVE " " TO STR.
STRING "EMP_", CNT INTO STR
END-STRING.
MOVE STR TO ENAME(CNT).

MOVE " " TO STR.
STRING "JOB_", CNT INTO STR
END-STRING.
MOVE STR TO JOB(CNT).

MOVE 100 TO MGR(CNT).

IF CNT > 30 THEN
COMPUTE CNT2 = 30
ELSE
MOVE CNT TO CNT2
END-IF

MOVE " " TO STR.
STRING CNT2, "-JAN-06" INTO STR
END-STRING.
MOVE STR TO HIREDATE(CNT).

MOVE " " TO STR.
STRING CNT2, "000" INTO STR
END-STRING.
MOVE STR TO SAL(CNT).

MOVE 1000 TO COMM(CNT).

MOVE 10 TO DEPTNO(CNT).

* FETCHES DATA FROM EMP TABLE
FETCH-TAB.
EXEC SQL WHENEVER NOT FOUND GOTO ENDFETCH-TAB END-EXEC.
DISPLAY "Fetch using FETCH FIRST ROWSET".
EXEC SQL FETCH FIRST ROWSET FROM C1 FOR :FETCHCNT ROWS
INTO :EMPOUT
END-EXEC.
PERFORM PRINTDATA.

DISPLAY " ".
DISPLAY "Fetch using FETCH NEXT ROWSET".
EXEC SQL FETCH NEXT ROWSET FROM C1 FOR 5 ROWS
INTO :EMPOUT END-EXEC.
PERFORM PRINTDATA.

DISPLAY " ".
DISPLAY "Fetch using FETCH CURRENT ROWSET".
EXEC SQL FETCH CURRENT ROWSET FROM C1 FOR :FETCHCNT ROWS
INTO :EMPOUT
END-EXEC.
PERFORM PRINTDATA.

DISPLAY " ".
DISPLAY "Fetch using FETCH LAST ROWSET".
EXEC SQL FETCH LAST ROWSET FROM C1 FOR :FETCHCNT ROWS
INTO :EMPOUT
END-EXEC.
PERFORM PRINTDATA.

DISPLAY " ".
DISPLAY "Fetch using FETCH ROWSET STARTING AT ABSOLUTE".
COMPUTE CNT = 4 * FETCHCNT.
EXEC SQL FETCH ROWSET STARTING AT ABSOLUTE :CNT FROM C1
FOR 5 ROWS INTO :EMPOUT
END-EXEC.
PERFORM PRINTDATA.

DISPLAY " ".
DISPLAY "Fetch using FETCH ROWSET STARTING AT RELATIVE".
EXEC SQL FETCH ROWSET STARTING AT RELATIVE -3 FROM C1
FOR :FETCHCNT ROWS INTO :EMPOUT
END-EXEC.
PERFORM PRINTDATA.

DISPLAY " ".
DISPLAY "Fetch using FETCH PRIOR ROWSET ".
EXEC SQL FETCH PRIOR ROWSET FROM C1 FOR :FETCHCNT ROWS
INTO :EMPOUT
END-EXEC.
PERFORM PRINTDATA.

* Prints fetched data
PRINTDATA.
PERFORM VARYING CNT FROM 1 BY 1 UNTIL CNT > FETCHCNT
DISPLAY "Empno=", EMPNO1(CNT), ", Ename=", ENAME1(CNT),
", Job=", JOB1(CNT), ", Mgr=", MGR1(CNT),
", Hiredate=", HIREDATE1(CNT)
DISPLAY "Sal=", SAL1(CNT), ", Comm=", COMM1(CNT),
", Deptno=", DEPTNO1(CNT)
END-PERFORM.

* HANDLES SQL ERROR CONDITIONS
SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

暗黙的なバッファ済INSERTの使用

Pro*Cobolアプリケーションの開発者は、埋込みSQL文のホスト配列を参照して、パフォーマンスを向上させることができます。これにより、データベースへの1回のラウンドトリップでSQL文の配列を実行できます。配列の実行によってパフォーマンスが大幅に向上するにもかかわらず、ANSI規格ではないため、この機能を使用しない開発者もいます。たとえば、Oracle製品で配列の実行を使用するように記述されたアプリケーションは、IBMのプリコンパイラを使用してプリコンパイルすることはできません。

対処方法として、バッファ済INSERT文を使用すると、ANSI規格の埋込みSQL構文を保持しながらパフォーマンスを向上させることができます。

コマンドライン・オプション「max_row_insert」は、INSERT文の実行前にバッファする行の数を制御します。このオプションのデフォルトは0で、機能は無効化されています。この機能を有効化するには、0よりも大きい任意の数を指定します。

挿入バッファを有効化すると、プリコンパイラのランタイムが対応するカーソルにフラグを付け、次を実行します。

- バインド変数を保持するための追加のメモリーを割当てまたは再割当てします(初回実行時のみ)。

- プログラムのホスト変数から内部ランタイム・バインド構造にバインド変数をコピーします。

- バッファ済の行カウントを増加させます。

- MAX_INSERT_ROWSだけバッファされている場合は、バッファ済のINSERT文をフラッシュします。

- MAX_INSERT_ROWSに達していない場合は、フラッシュせずに、内部バインド・バッファに値をコピーした後、戻ります。

バッファ済INSERT文をフラッシュする新しい埋込みSQL文を実行している場合は、次を実行します。

- バッファをフラッシュします。

- フラッシュを要求したコールを続行します。

標準のプリコンパイラのエラー・メカニズム(Pro*CobolのSQLCODE、SQLSTATEなど)を介してエラーがアプリケーションに通知されます。

「implicit_svpt」オプションは、新しくバッチ処理された挿入を開始する前に、暗黙的なセーブポイントを設定するかどうかを制御します。

- YESの場合は、新しい行のバッチを開始する前に、セーブポイントが設定されます。挿入時にエラーが発生すると、暗黙的な「セーブポイントへのロールバック」が実行されます。

- NOの場合は、暗黙的なセーブポイントが設定されません。バッファ済INSERTでエラーが発生すると、アプリケーションに通知されますが、ロールバックは実行されません。バッファ済INSERTのエラーは非同期に報告されます。アプリケーションでINSERT文が実行されると、挿入された行のエラーは報告されません。

- 挿入された行の一部のエラーは、INSERT以外の文が初めて実行されたときに後で報告されます。これには、DELETE、UPDATE、(別の表に対する)INSERT、COMMITおよびROLLBACKが含まれます。バッファ済INSERT文をクローズする文は、すべてエラーを報告します。この場合、エラーを報告する文は実行されません。エラーを処理した後で、バッファ済INSERTのエラーを報告した文を再実行する必要があります。それ以外の場合は、トランザクションをロールバックして再実行します。
たとえば、COMMIT文を使用して、バッファ済INSERTのループをクローズする方法について考えてみます。COMMITでは、以前のINSERTの重複キーが原因でエラーが発生します。この場合、COMMITは実行されません。エラーを処理した後で、COMMITを再実行する必要があります。それ以外の場合は、トランザクションをロールバックして再実行します。

- 挿入自体についてもいくつかエラーが報告され、以前に挿入された行のエラーが反映されている可能性があります。そのような場合、それ以上挿入は実行されません。以前挿入された行のエラーを処理し、現行の挿入を継続する必要がありますが、それには時間がかかります。かわりに、トランザクションをロールバックし、再実行してもかまいません。
たとえば、内部バッファの制限が10行で、アプリケーションがループで15行を挿入しているとします。8行目でエラーが発生したとします。エラーは、11行目が挿入されたときに報告され、これ以後にINSERTは実行されません。

バッファ済INSERT中に発生する可能性のあるエラーの一部を次に示します。

- ORA-00001: 索引キーが重複しています

- ORA-01400: 挿入時に必須列(NOT NULL)がないか、NULLになっています

- ORA-01401: 列に挿入した値が大きすぎます。

- ORA-01438: 指定した精度を超えた値が列に指定されています

例7-2 表へのバッファ済の行の挿入

このプログラムでは、EMP表に行のLOOPCNT数を挿入します。loop counter=5の場合、このプログラムは無効なempnoの挿入を試行します。max_row_insertオプションを使用しないと、プログラムでは無効な行を除くすべての行が挿入されます。max_row_insertオプションをLOOPCNTに設定すると、最初の4行のみが挿入されます。

max_row_insertオプションを使用すると、間違った文が削除されるときに、プログラムは配列INSERTプログラムと同様に動作します。

*****************************************************************
* bufinsdemo:                                                   *
*                                                               *
* This program inserts LOOPCNT number of rows into EMP table.   *
* At loop counter=5, this program attempts to insert an invalid *
* empno. Without max_row_insert option, this program inserts    *
* all rows except this invalid row. When max_row_insert option  *
* is set to LOOPCNT, only the first 4 rows are inserted.        *
*                                                               *
* With max_row_insert option, when this errorneous statement    *
* is removed, the performance of this program is similar to     *
* having an array insert in this program.                       *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID.  bufinsdemo.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.

* EMBEDDED COBOL (file "BUFINSDEMO.PCO")

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME          PIC X(10) VARYING.
01  PASSWD            PIC X(10) VARYING.

01  EMPIN.
02  EMPNO PIC  9(6) COMP.
02  ENAME PIC  X(10).
02 JOB PIC  X(9).
02  MGR PIC 9(4).
02  HIREDATE PIC  X(9).
02  SAL PIC  X(6).
02  COMM PIC  X(6).
02  DEPTNO PIC  9(2).

01  EMPOUT.
02  EMPNO1 PIC  9(4) COMP.
02  ENAME1 PIC  X(10).
02  JOB1 PIC  X(9).
02  MGR1 PIC 9(4).
02  HIREDATE1 PIC  X(9).
02  SAL1 PIC  X(6).
02  COMM1 PIC  X(6).
02  DEPTNO1 PIC  9(2).

EXEC SQL END DECLARE SECTION END-EXEC.

01  LOOPCNT PIC  9(4) COMP VALUE 100.
01  CNT PIC  9(4).
01  CNT2 PIC  9(2).

01  STRINGFIELDS.
02 STR PIC X(18) VARYING.

EXEC SQL INCLUDE SQLCA END-EXEC.

PROCEDURE DIVISION.
BEGIN-PGM.
EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC.

PERFORM LOGON.

* When max_row_insert option is set to LOOPCNT and when the errorneous
* statement is removed, all the rows will be inserted into the database
* in one stretch and hence maximum performance gain will be achieved.
DISPLAY "Inserting ", LOOPCNT, " rows into EMP table".
PERFORM INS-TAB VARYING CNT FROM 1 BY 1
UNTIL CNT > LOOPCNT.

EXEc SQL COMMIT END-EXEC.

EXEC SQL SELECT COUNT(*) INTO :CNT FROM EMP
WHERE ENAME LIKE 'EMP_%'
END-EXEC.
DISPLAY "Number of rows successfully inserted into EMP "
"table:", CNT.

DISPLAY " ".
EXEC SQL DECLARE C1 CURSOR FOR
SELECT EMPNO, ENAME, JOB, MGR, HIREDATE, SAL,
COMM, DEPTNO
FROM EMP
WHERE ENAME LIKE 'EMP_%'
ORDER BY EMPNO
END-EXEC.

EXEC SQL OPEN C1 END-EXEC.

DISPLAY "Fetching inserted rows from EMP table".
PERFORM FETCH-TAB.
ENDFETCH-TAB.

EXEC SQL CLOSE C1 END-EXEC.

EXEC SQL DELETE FROM EMP WHERE EMPNO < 1000 END-EXEC.

EXEC SQL COMMIT WORK RELEASE END-EXEC.
STOP RUN.

LOGON.
MOVE "scott" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "tiger" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.

* INSERTS DATA INTO EMP TABLE
INS-TAB.
IF CNT = 5 THEN
MOVE 10000 TO EMPNO
ELSE
MOVE CNT TO EMPNO
END-IF

MOVE " " TO STR.
STRING "EMP_", CNT INTO STR
END-STRING.
MOVE STR TO ENAME.

MOVE " " TO STR.
STRING "JOB_", CNT INTO STR
END-STRING.
MOVE STR TO JOB.

MOVE 100 TO MGR.

IF CNT > 30 THEN
COMPUTE CNT2 = 30
ELSE
MOVE CNT TO CNT2
END-IF

MOVE " " TO STR.
STRING CNT2, "-JAN-06" INTO STR
END-STRING.
MOVE STR TO HIREDATE.

MOVE " " TO STR.
STRING CNT2, "000" INTO STR
END-STRING.
MOVE STR TO SAL.

MOVE 1000 TO COMM.

MOVE 10 TO DEPTNO.

EXEC SQL INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE,
SAL, COMM, DEPTNO) VALUES (:EMPIN)
END-EXEC.

* FETCHES DATA FROM EMP TABLE
FETCH-TAB.
EXEC SQL WHENEVER NOT FOUND GOTO ENDFETCH-TAB END-EXEC.
EXEC SQL FETCH C1 INTO :EMPOUT END-EXEC.
DISPLAY "Empno=", EMPNO1, ", Ename=", ENAME1,
", Job=", JOB1, ", Mgr=", MGR1,
", Hiredate=", HIREDATE1.
DISPLAY "Sal=", SAL1, ", Comm=", COMM1, ", Deptno=", DEPTNO1.
GO TO FETCH-TAB.

* HANDLES SQL ERROR CONDITIONS
SQL-ERROR.
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY SQLERRMC.

8 エラー処理および診断

アプリケーション・プログラムでは、ランタイム・エラーを予測して、そのエラーをリカバリするように対処する必要があります。この章では、エラー・レポートおよびリカバリを詳しく説明します。具体的には、ANSI状態変数SQLCODEおよびSQLSTATE、またはOracle SQLCA (SQLコミュニケーション領域)構造を使用して警告およびエラーを処理する方法を説明します。また、WHENEVER文の使用方法と、Oracle ORACA (Oracle通信領域)構造を使用して問題を診断する方法も説明します。

内容は次のとおりです。

- エラー処理が必要な理由

- エラー処理の代替手段

- SQLコミュニケーション領域の使用

- Oracle通信領域の使用

- エラーとSQLSTATEコードの対応関係

エラー処理が必要な理由

どのようなアプリケーション・プログラムでも、その大部分をエラー処理に当てる必要があります。エラー処理の主な利点は、エラーが存在していてもプログラムの処理を続行できることです。エラーは設計ミス、コーディングの誤り、ハードウェア障害、誤ったユーザー入力をはじめ、様々な原因で発生します。

潜在的なエラーをすべて予測するのは無理ですが、プログラムにとって意味のある特定の種類のエラーについてアクションを考えることはできます。Pro*COBOLでは、エラー処理とはSQL文の実行エラーを検出してリカバリを図ることを意味します。処理を中断しないかぎり、プリコンパイラはエラーを無視して処理を続行するため、エラーは必ずトラップする必要があります。

値が切り捨てられたことを示す警告やデータの終わりなどの状態の変更も処理できます。表中の該当する行をすべて処理する前にINSERT、UPDATEまたはDELETE文が失敗する場合もあるため、各DML文の後にはエラーおよび警告の状態をチェックすることが非常に重要です。

エラー処理の代替手段

Pro*COBOLは次のような一般的なエラー処理方法をサポートしています。

- SQLCAおよびオプションのORACAを使用したOracle固有の方法。

- SQLSTATE状態変数を使用したSQL標準の方法。

プリコンパイラ・オプションMODEは、SQL標準に準拠するかどうかを制御します。MODE={ANSI | ANSI14}の場合、SQLSTATE状態変数をPIC X(5)として宣言します。また、ANSI SQL-89 SQLCODE状態変数も継続してサポートされていますが、これはSQL標準から除外されたため、新しいプログラムへの使用はお薦めしません。MODE={ORACLE | ANSI13}の場合は、EXEC SQL INCLUDE文を使用して必ずSQLCAを含める必要があります。1つのプログラムで2つの方法を使用することも可能ですが、通常その必要はありません。

方法の併用の詳細は、「状態変数の組合せ」を参照してください。

SQLCA

SQLCAは、Oracleの警告、エラー番号およびエラーの説明を含むレコードに似たホスト言語データ構造です。Oracleは、実行SQL文またはPL/SQL文を実行するたびにSQLCAを更新します。(宣言部の後では、SQLCAの値は未定義になります。)プログラムは、SQLCAに格納されたリターン・コードをチェックして、SQL文の結果を判別できます。SQLCAのチェックには、次の2つの方法があります。

- WHENEVER文による暗黙的なチェック

- SQLCA変数の明示的なチェック

WHENEVER文を使用してSQL文の状態を暗黙的にチェックすると、Pro*COBOLは各実行文の後に自動的にエラー・チェック・コードを挿入します。あるいは、ユーザーが明示的にコードを記述し、SQLCA構造のSQLCODEメンバーの値をテストすることもできます。埋込みSQL INCLUDE文を使用してSQLCAを含めるには、次のようにします。

EXEC SQL INCLUDE SQLCA END-EXEC.

ORACA

ランタイム・エラーについてSQLCAから得られる情報が十分でない場合、ORACAを使用できます。ORACAには、カーソル統計情報、SQL文のテキスト、特定のオプション設定およびシステム統計情報が格納されます。埋込みSQL INCLUDE文を使用してORACAを含めるには、次のようにします。

EXEC SQL INCLUDE ORACA END-EXEC.

ORACAはオプションであり、MODEの設定に関係なく宣言できます。ORACA状態変数の詳細は、「Oracle通信領域の使用」を参照してください。

ANSI SQLSTATE変数

MODE=ANSIの場合は、宣言部にANSI SQLSTATE変数を宣言して、明示的または暗黙的なエラー・チェックを実行できます。オプションDECLARE_SECTIONをNOに設定すると、宣言部の外でも宣言できます。

注意:
MODE=ANSIの場合は、実際のS9(9) COMPを使用してSQLCODE変数を宣言することも可能です。SQLSTATE変数のかわりに使用したり、SQLSTATE変数と併用できますが、新しいプログラムにはお薦めしません。SQLCAとSQLSTATE変数を併用することもできます。MODE=ANSI14の場合、SQLSTATEはサポートされていないため、SQLCODEを宣言するか、SQLCAを含める必要があります。設定モードに関係なく、SQLCODEおよびSQLCAの両方を宣言することはできません。

SQLSTATEの宣言

この項では、SQLSTATEの宣言方法を説明します。SQLSTATEは、次の例に示すように、5文字の英数文字列として宣言する必要があります。

*    Declare the SQLSTATE status variable.
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01 SQLSTATE PIC X(5).
...
EXEC SQL END DECLARE SECTION END-EXEC.

SQLSTATE値

SQLSTATEステータス・コードは、2文字のクラス・コードとそれに続く3文字のサブクラス・コードで構成されます。クラス・コード00は正常終了を示し、それ以外のクラス・コードは例外のカテゴリを示します。サブクラス・コード000は特定の例外を示しませんが、それ以外のサブクラス・コードはそのカテゴリの中の特定の例外を示します。たとえば、SQLSTATE値22012は、クラス・コード22 (データ例外)およびサブクラス・コード012 (ゼロによる除算)で構成されます。

SQLSTATE値の5文字は、それぞれ数字(0から9)または大文字の英文字(AからZ)で構成されます。0から4の範囲の数字、またはAからHの範囲の文字で始まるクラス・コードは、事前定義済の状態(SQL標準で定義されている)用に確保されています。他のすべてのクラス・コードは実装定義の状態用に確保されています。事前定義済のクラス内では、0から4の範囲の数字またはAからHの範囲の英文字で始まるサブクラス・コードは、事前定義済のサブコンディションを示すために確保されています。他のすべてのサブクラス・コードは実装定義のサブコンディション用に確保されています。図8-1に、コード体系を示します。

図8-1 SQLSTATEコード体系

表8-1に、SQL標準によって事前定義済のクラスを示します。

表8-1 事前定義済のクラス

CLASS

状態

00

正常終了

01

警告

02

データなし

07

動的SQLエラー

08

例外接続

09

トリガーされたアクションの例外

0A

サポートされていない機能

0A

サポートされていない機能

0D

ターゲット・タイプの指定が無効

0E

スキーマ名リストの指定が無効

0F

ロケータの例外

0L

無効な権限付与者

0M

SQLが呼び出したプロシージャ参照が無効

0P

役割の指定が無効

0S

変換グループ名の指定が無効

0T

ターゲット表がカーソル仕様と不一致

0U

更新可能でない列への割当て試行

0V

順序付け列への割当て試行

0W

トリガー実行中の禁止された文の発生

0Z

診断の例外

21

カーディナリティ違反

22

データの例外

23

整合性制約違反

24

カーソル状態が無効

25

トランザクション状態が無効

26

SQL文名が無効

27

トリガー・データの変更違反

28

認証の指定が無効

2A

直接SQL構文エラーまたはアクセス規則違反

2B

依存権限記述子がまだ存在しています。

2C

キャラクタ・セット名が無効

2D

トランザクションの終了が無効

2E

接続名が無効

2F

SQLルーチンの例外

2H

照合名が無効

30

SQL文識別子が無効

33

SQL記述子名が無効

34

カーソル名が無効

35

状態番号が無効

36

カーソルの秘密度の例外

37

動的SQL構文エラーまたはアクセス規則違反

38

外部ルーチンの例外

39

外部ルーチン呼出しの例外

3B

セーブポイントの例外

3C

あいまいなカーソル名

3D

カタログ名が無効

3F

スキーマ名が無効

40

トランザクション・ロールバック

42

構文エラーまたはアクセス規則違反

44

WITH_CHECK_OPTION指定違反

HZ

リモート・データベース・アクセス

注意:
クラス・コードHZは、国際標準規格ISO/IEC DIS 9579-2で定義された条件であるリモート・データベース・アクセス用に確保されています。

表8-4「SQLSTATEコード」に、エラーとSQLSTATEステータス・コードの対応関係を示します。1つのステータス・コードに複数のエラーが対応する場合もあります。また、ステータス・コードに対応するエラーがない場合もあります(この場合は、表の右端の列は空白になります)。60000から99999の範囲のステータス・コードは、実装定義です。

SQLコミュニケーション領域の使用

OracleはSQLコミュニケーション領域(SQLCA)を使用して、実行時にプログラムに渡されるステータス情報を保持します。SQLCAはレコードに似たCOBOLデータ構造で、各実行SQL文の後で更新されます。そのため、常に最新のSQLの動作の結果を反映しています。そのフィールドには、SQL文を実行するたびにOracleによって更新されるエラー、警告およびステータス情報が格納されます。結果を判断するため、SQLCA内の変数を独自のCOBOLコードで明示的にチェックするか、WHENEVER文で暗黙的にチェックすることができます。

MODE={ORACLE | ANSI13}のときはSQLCAは必須です(SQLCAが宣言されていないと、コンパイル時エラーが発生します)。MODE={ANSI | ANSI14}のときはSQLCAは必須ではありませんが、SQLCAを宣言しないとWHENEVER SQLWARNING文は使用できません。マルチバイトNCHARホスト変数を使用するときにもSQLCAを含める必要があります。

注意:
アプリケーションでOracle Net Servicesを使用してローカル・データベースおよびリモート・データベースの組合せに同時にアクセスする場合、すべてのデータベースは1つのSQLCAに書き込みます。つまり、データベースごとに異なるSQLCAがあるわけではありません。詳細は、「同時ログイン」を参照してください。

SQLCAの内容

SQLCAには、エラー・コード、警告フラグ、イベント情報、処理済行数または診断情報など、SQL文の実行に関する実行時情報が格納されます。

図8-2に、SQLCA内のすべての変数を示します。

図8-2 Pro*COBOLのSQLCA変数宣言

SQLCAの宣言

SQLCAを宣言するには、次に示すように、(EXEC SQL INCLUDE文を使用して) Pro*COBOLソース・ファイルの宣言部の外に組み込みます。

*    Include the SQL Communications Area (SQLCA).
EXEC SQL INCLUDE SQLCA END-EXEC.

SQLCAは宣言部の外で宣言する必要があります。

警告

SQLCAが宣言されている場合は、SQLCODEを宣言しないでください。同様に、SQLCODEが宣言されている場合は、SQLCAを宣言しないでください。SQLCA構造体によって宣言される状態変数もSQLCODEという名前なので、両方のエラー・レポート・メカニズムを使用するとエラーが発生します。

プログラムをプリコンパイルすると、INCLUDE SQLCA文はいくつかの変数宣言に置き換えられます。これらの変数宣言によって、Oracleとプログラムとの間の通信が可能になります。

エラー・レポートの基本コンポーネント

Pro*COBOLのエラー・レポートの基本的なコンポーネントは、SQLCA内のいくつかのフィールドを使用します。

ステータス・コード

実行SQL文はすべて、SQLCA変数SQLCODEにステータス・コードを戻します。戻されたステータス・コードは、WHENEVER SQLERRORを使用して暗黙的に、またはCOBOLコードを記述して明示的にチェックできます。

警告フラグ

警告フラグはSQLCA変数のSQLWARN0からSQLWARN7に戻されます。WHENEVER SQLWARNINGを使用して、またはCOBOLコードを記述してチェックできます。警告フラグは、エラーとみなされない実行時の状態を検出するのに便利です。

処理済行数

一番最後に実行されたSQL文で処理された行数が、SQLCA変数SQLERRD(3)に戻されます。OPENカーソルで繰り返されるFETCHについては、フェッチされた行数の実行合計がSQLERRD(3)に格納されます。

解析エラー・オフセット

SQL文は実行前に必ず解析され、構文規則に従っているか、有効なデータベース・オブジェクトを参照しているかが検証されます。エラーが検出されると、SQLCA変数のSQLERRD(5)にオフセットが格納され、これは明示的にチェックできます。このオフセットには、解析エラーの始まりを示すSQL文中の文字位置が示されています。先頭の文字位置は0 (ゼロ)です。たとえば、オフセットが9のとき、解析エラーは10番目の文字から始まっています。

SQL文に解析エラーがない場合、SQLERRD(5)は0 (ゼロ)に設定されます。解析エラーが先頭の文字(文字位置0 (ゼロ))から始まっている場合にも、SQLERRD(5)は0 (ゼロ)に設定されます。このため、SQLERRD(5)のチェックは、SQLCODEが負の値(エラーが発生したことを示す)の場合にのみ行ってください。

エラー・メッセージ・テキスト

エラー・コードおよびメッセージは、SQLCA変数SQLERRMCに格納されます。たとえば、エラー処理ルーチンに次の文を記述します。

*    Handle SQL execution errors.
MOVE SQLERRMC TO ERROR-MESSAGE.
DISPLAY ERROR-MESSAGE.

メッセージ・テキストの先頭から最大70文字分が格納されます。70文字を超えるメッセージについては、SQLGLMサブルーチンをコールする必要があります。SQLGLMサブルーチンの詳細は、「エラー・メッセージのテキスト全体の取得」を参照してください。

SQLCAの構造

この項では、SQLCAの構造、そのフィールドおよびフィールドに格納できる値を説明します。

SQLCAID

この文字列フィールドは、SQLコミュニケーション領域を示す「SQLCA」に初期化されます。

SQLCABC

この整数フィールドには、SQLCA構造の長さ(バイト数)が格納されます。

SQLCODE

この整数フィールドには、最後に実行されたSQL文のステータス・コードが入ります。SQLの動作の結果を示すステータス・コードは、次のいずれかの数値です。

ステータス・コード

説明

0

Oracleは文を実行し、エラーも例外も検出しませんでした。

> 0

Oracleは文を実行しましたが、例外を検出しました。この状態が発生するのは、WHERE句の検索条件を満たす行がない場合、あるいはSELECT INTOまたはFETCHで1行も戻されなかった場合です。

< 0

MODE={ANSI | ANSI14 | ANSI113}のときは、1行もINSERTされなかった場合にSQLCODEに+100が戻されます。副問合せで処理に行が戻されなかったときにこの状態が発生します。
データベース、システム、ネットワークまたはアプリケーションのいずれかにエラーが発生したため、Oracleは文を実行しませんでした。このようなエラーは致命的です。このようなエラーが発生すると、ほとんどの場合はカレント・トランザクションがロールバックされます。

負のリターン・コードは、『Oracle Databaseエラー・メッセージ』に記載されているエラー・コードに対応しています。

SQLERRM

このサブレコードには、次の2つのフィールドがあります。

フィールド

説明

SQLERRML

この整数フィールドには、SQLERRMCに格納されているメッセージ・テキストの長さが格納されます。

SQLERRMC

この文字列フィールドには、SQLCODEに格納されたエラー・コードのメッセージテキストが保持され、最大70文字を格納できます。70文字を超えるメッセージの全文を取得するには、SQLGLMファンクションを使用します。
SQLERRMCを参照するには、まずSQLCODEが負の値であることを確かめてください。SQLCODEが0 (ゼロ)の場合は、SQLERRMCを参照するとそれ以前のSQL文に関連するメッセージ・テキストが戻されます。

SQLERRP

この文字列フィールドは、将来の使用に備えて確保されています。

SQLERRD

この2進整数の表には6つの要素があります。SQLERRDの各フィールドを説明します。

フィールド

説明

SQLERRD(1)

このフィールドは、将来の使用に備えて確保されています。

SQLERRD(2)

このフィールドは、将来の使用に備えて確保されています。

SQLERRD(3)

このフィールドには、最後に実行したSQL文によって処理された行数が入ります。ただし、SQL文が失敗すると、1つの例外を除き、SQLERRD(3)の値は未定義となります。表の動作中にエラーが発生すると、エラーの原因となった行で処理が停止し、SQLERRD(3)は正常に処理された行数を示します。
処理済行数はOPEN文の後に0 (ゼロ)に設定され、FETCH文の後に増分されます。処理済行数は、EXECUTE文、INSERT文、UPDATE文、DELETE文およびSELECT INTO文について、正常に処理された行数を反映します。この数字にはUPDATEまたはDELETE CASCADEによって処理された行は含まれません。たとえばWHERE句の条件を満たす20行が削除された後で、列制約条件に違反する5行が削除されたときの処理済行数は、25ではなく20となります。

SQLERRD(4)

このフィールドは、将来の使用に備えて確保されています。

SQLERRD(5)

このフィールドには、一番最後に実行されたSQL文中の、解析エラーが始まる文字位置を示すオフセットが格納されます。先頭の文字位置は0 (ゼロ)です。

SQLERRD(6)

このフィールドは、将来の使用に備えて確保されています。

SQLWARN

この表は、それぞれ1文字からなる8つの要素で構成されています。これらの要素は警告フラグとして使用されます。Oracleでは、フラグに「W」(警告)文字値を割り当ててフラグを設定します。フラグは例外状態の発生を警告します。

たとえば、Oracleで切り捨てられた列値を出力ホスト文字変数に割り当てると、警告フラグが設定されます。

注意:
図8-2「Pro*COBOLのSQLCA変数宣言」は、SQLWARN0からSQLWARN7というPIC X基本項目を持つグループ項目としてのPro*COBOLでのSQLWARN実装を示します。

SQLWARNの各フィールドを説明します。

フィールド

説明

SQLWARN0

このフラグは別の警告フラグが設定されていることを示します。

SQLWARN1

このフラグは、切り捨てられた列値が出力ホスト変数に代入されたときに設定されます。これは文字データにのみ適用されます。Oracleが一部の数値データを切り捨てるときには、警告の設定も負のSQLCODE値の戻しもありません。
列値が切り捨てられたかどうか、またどれだけ切り捨てられたかを調べるには、出力ホスト変数に対応する標識変数をチェックします。標識変数によって戻された値が正の整数のときは、その値は列値の元の長さを示します。その値に応じてホスト変数の長さを増やすことができます。

SQLWARN2

AVG、COUNTまたはMAXなどのSQLグループ関数の評価で1つまたは複数のNULLが無視されたときに、このフラグが設定されます。COUNT(*)以外のすべてのグループ関数ではNULLが無視されるため、このような動作になります。必要であれば、SQL関数NVLを使用して、NULL列項目に一時的に値(0 (ゼロ)など)を割り当てることができます。

SQLWARN3

問合せの選択リスト内の列の数がSELECT文またはFETCH文のINTO句内のホスト変数の数と一致しないときに、このフラグが設定されます。戻される項目の数は両者のうち少ない方の数となります。

SQLWARN4

このフラグは現在使用されていません。

SQLWARN5

PL/SQLのコンパイル・エラーが原因でEXEC SQL CREATE {PROCEDURE | FUNCTION | PACKAGE | PACKAGE BODY}文が失敗したときに、このフラグが設定されます。

SQLWARN6

このフラグは現在使用されていません。

SQLWARN7

このフラグは現在使用されていません。

SQLEXT

この文字列フィールドは、将来の使用に備えて確保されています。

PL/SQLに関する考慮事項

埋込みPL/SQLブロックを実行するPro*COBOLプログラムの場合、SQLCAのフィールドがすべて設定されるわけではありません。たとえば、PL/SQLブロックで複数の行がフェッチされた場合、処理済行数SQLERRD(3)は、実際にフェッチされた行数ではなく、1に設定されます。したがって、PL/SQLブロックを実行した後は、信頼できるSQLCAのフィールドはSQLCODEフィールドおよびSQLERRMフィールドのみになります。

エラー・メッセージのテキスト全体の取得

SQLCODEを明示的に宣言し、SQLCAを含めていない場合、MODEの設定に関係なく、SQLGLMを使用してエラー・メッセージのテキスト全体を取得できます。SQLCAには70文字までのエラー・メッセージを格納できます。これより長い(またはネストした)エラー・メッセージを取得するには、SQLGLMサブ・ルーチンが必要です。

データベースに接続すると、次の構文を使用してSQLGLMをコールできます。

CALL "SQLGLM" USING MSG-TEXT, MAX-SIZE, MSG-LENGTH

パラメータは次のとおりです。

パラメータ

データ型

パラメータ定義

MSG-TEXT

PIC X(n)

エラー・メッセージを格納するフィールド(Oracleはこのフィールドの末尾までを空白文字で埋めます。)

MAX-SIZE

PIC S9(9) COMP

MSG-TEXTフィールドの最大サイズ(バイト数)を指定する整数。

MSG-LENGTH

PIC S9(9) COMP

エラー・メッセージの実際の長さを格納する整変数。

パラメータはすべて、参照によって渡す必要があります。通常、デフォルトでパラメータ引渡し規則は参照によって引渡されるため、特別な処置は必要ありません。

エラー・メッセージの長さは、エラー・コードおよびネストされたメッセージ、表や列の名前など、メッセージの挿入部分を入れて512文字以内です。SQLGLMによって戻されるエラー・メッセージの最大長は、MAX-SIZEに指定した値によって決まります。

次の例では、SQLGLMを使用して、エラー・メッセージの最大長を200文字に設定します。

...
*    Declare variables for the SQL-ERROR subroutine call.
01  MSG-TEXT    PIC X(200).
01  MAX-SIZE    PIC S9(9) COMP VALUE 200.
01  MSG-LENGTH  PIC S9(9) COMP.
...
PROCEDURE DIVISION.
MAIN.
EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC.
...
SQL-ERROR.
*    Clear the previous message text.
MOVE SPACES TO MSG-TEXT.
*    Get the full text of the error message.
CALL "SQLGLM" USING MSG-TEXT, MAX-SIZE, MSG-LENGTH.
DISPLAY MSG-TEXT.

この例では、SQLGLMはSQLエラーが発生したときのみにコールされます。SQLGLMをコールする前に、SQLCODEが負の値であることを必ず確認してください。SQLCODEが0 (ゼロ)のときにSQLGLMをコールすると、前のSQL文に対応するメッセージ・テキストが戻されます。

注意:
アプリケーションでSQLGLMをコールしてメッセージ・テキストを取得する場合は、メッセージの長さを渡す必要があります。SQLCA変数SQLERRMLは使用しないでください。SQLERRMLはPIC S9(4) COMP整数ですが、SQLGLMおよびSQLIEMではPIC S9(9) COMP整数が予測されています。かわりに、PIC S9(9) COMPとして宣言した別の変数を使用します。

DSNTIAR

DB2には、表示可能な形式のSQLCAを取得するための、DSNTIARというアセンブラ・ルーチンがあります。DB2からOracleへ移行するユーザーのために、Pro*COBOLにもDSNTIARが用意されています。DSNTIARは、ラップを行うSQLGLMとして実装されています。DSNTIARのインタフェースは次のようになります。

CALL 'DSNTIAR' USING SQLCA MESSAGE LRECL

MESSAGEはサイズ240以上のVARCHAR形式の出力メッセージ領域で、LRECLは出力メッセージの長さ(72から240)が格納されるフル・ワードです。MESSAGE引数の最初のハーフ・ワードには、残りの領域の長さが含まれます。DSNTIARが戻すエラー・コードを次の表に示します。

表8-2 DSNTIARエラー・コードおよび説明

エラー・コード

説明

0

正常に実行しました。

4

指定されたメッセージよりも大きな領域です。

8

論理レコード長(LRECL)が72から240の範囲外です。

12

メッセージ領域の大きさが十分ではありません(240よりも大きい)。

WHENEVERディレクティブ

デフォルトでは、Pro*COBOLは可能であればエラーおよび警告状態を無視して処理を続行します。自動状態チェックおよびエラー処理を実行するにはWHENEVER文が必要です。

WHENEVER文を使用すると、Oracleがエラー、警告状態または「見つかりません」という状態を検出した場合の処置を指定できます。指定できる処置としては、次の文からの処理の続行、段落のPERFORM、段落への分岐または停止などがあります。

状態

Oracleに自動的にSQLCAをチェックさせて、次の状態が存在しないかどうかを調べることができます。

SQLWARNING

Oracleから警告が戻されたか(同時にSQLWARN(1)からSQLWARN(7)の警告フラグのうちの1つが設定されます)、またはSQLCODEの値が+1403以外の正の値になっていたために、SQLWARN(0)が設定されている状態です。たとえば、切り捨てられた列値が出力ホスト変数に割り当てられると、SQLWARN(1)が設定されます。

MODE={ANSI | ANSI14}のときは、SQLCAの宣言はオプションです。ただし、WHENEVER SQLWARNINGを使用するには、必ずSQLCAを宣言してください。

注意:
このためにはSQLCAを含める必要があります。

SQLERROR

Oracleからエラーが戻された場合、SQLCODEが負の値に設定されます。

NOT FOUNDまたはNOTFOUND

フェッチの最後に達すると、SQLCODE値として+1403 (またはMODE={ANSI | ANSI14 | ANSI13}またはEND_OF_FETCH=100の場合は+100)が戻されます。これは、検索基準に適合するすべての行がフェッチされるか、検索基準に適合する行が1つもない場合に発生します。

END_OF_FETCHオプションを使用して、MODEマクロ・オプションで使用される値をオーバーライドできます。

END_OF_FETCH = 100 | 1403 (default 1403)

詳細は、「END_OF_FETCH」を参照してください。

アクション

WHENEVER文を使用して、次のアクションを指定できます。

CONTINUE

可能であれば、プログラムは次の文からの実行を継続します。これはデフォルトの動作で、WHENEVER文を使用しない場合と同じです。状態のチェックを「オフ」にするのに使用できます。

DO CALL

プログラムはネストされたサブプログラムをコールします。サブプログラムの最後に達すると、失敗したSQL文の後の文に制御が渡されます。

DO PERFORM

プログラムは制御をCOBOL節または段落に渡します。節の最後では、失敗したSQL文の後の文に制御が渡されます。

EXEC SQL
WHENEVER <condition> DO PERFORM <section_name>
END-EXEC.

GOTOまたはGO TO

プログラムは指定された段落または節に分岐します。

STOP

プログラムは実行を停止し、COMMITされていない作業がロールバックされます。

注意してください。STOPアクションでは、ログオフするまでメッセージは表示されません。

注意:
生成済のコードでは、EXEC SQL WHENEVER SQLERROR STOPがIF SQLCODE IN SQLCA IS EQUAL TO 1403 THEN STOP RUN END-IFに変換されますが、Oracleサーバーはコミットされていないデータのロールバックを処理します。

WHENEVER文のコーディング

WHENEVER文の構文は次のとおりです。

EXEC SQL
WHENEVER <condition> <action>
END-EXEC.

DO PERFORM

WHENEVER ... DO PERFORM文を使用するときには、段落または節に対してPERFORM文を実行する場合の通常の規則が適用されます。ただし、THRU句、TIMES句、UNTIL句またはVARYING句は使用できません。

たとえば、次のWHENEVER...DO文は無効です。

PROCEDURE DIVISION.
*    Invalid statement
EXEC SQL WHENEVER SQLERROR DO
PERFORM DISPLAY-ERROR THRU LOG-OFF
END-EXEC.
...
DISPLAY-ERROR.
...
LOG-OFF.
...

次に示すのは、WHENEVER SQLERROR DO PERFORM文を使用して特定のエラーを処理する例です。

PROCEDURE DIVISION.
MAIN SECTION.
MSTART.
...
EXEC SQL
WHENEVER SQLERROR DO PERFORM INS-ERROR
END-EXEC.
EXEC SQL
INSERT INTO EMP (EMPNO, ENAME, DEPTNO)
VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER)
END-EXEC.
EXEC SQL
WHENEVER SQLERROR DO PERFORM DEL-ERROR
END-EXEC.
EXEC SQL
DELETE FROM DEPT
WHERE DEPTNO = :DEPT-NUMBER
END-EXEC.
...
MEXIT.
STOP RUN.
INS-ERROR SECTION.
INSSTART.
*    Check for "duplicate key value" Oracle error
IF SQLCA.SQLCODE = -1
...
*    Check for "value too large" Oracle error
ELSE IF SQLCA.SQLCODE = -1401
...
ELSE
...
END-IF.
...
INSEXIT.
EXIT.
*
DEL-ERROR SECTION.
DSTART.
*    Check for the number of rows processed.
IF SQLCA.SQLERRD(3) = 0
...
ELSE
...
END-IF.
...
DEXIT.
EXIT.

各段落でどのようにSQLCA内の変数をチェックし、実行する処理を決定しているか注意してください。

DO CALL

この句はアクション・サブプログラムをコールします。句の構文を次に示します。

EXEC SQL
WHENEVER <condition> DO CALL <subprogram_name>
[USING <param1> ...]
END-EXEC.

次の制限または規則が適用されます。

- USING句では、RETURNING、ON_EXCEPTIONまたはOVER_FLOW句は使用できません。

- COBOLソース・コードのPROGRAM-ID文で、キーワードCOMMONの前にサブプログラム名を入力することが必要な場合があります。

- アクション・サブプログラムではWHENEVER CONTINUE文を使用する必要があります。

- WHENEVERディレクティブのDO CALL句では、アクション・サブプログラム名を二重引用符で囲むことが必要な場合があります。

次に示す例は、サブプログラムLOGONまたはMAINプログラムからエラー・サブプログラムSQL-ERRORをコールするプログラムの例です。DO PERFORM句を使用したときと同様、2つの位置でコードが繰り返されることはありません。

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN.
ENVIRONMENT DIVISION.
...
PROCEDURE DIVISION.
BEGIN-PGM.
EXEC SQL
WHENEVER SQLERROR DO CALL "SQL-ERROR"
END-EXEC.
CALL "LOGON".
...
IDENTIFICATION DIVISION.
PROGRAM-ID. LOGON.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  USERNAME          PIC X(15) VARYING.
01  PASSWD            PIC X(15) VARYING.
PROCEDURE DIVISION.
MOVE "SCOTT" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "TIGER" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE AS USER:  ", USERNAME-ARR.
END PROGRAM LOGON.
...
IDENTIFICATION DIVISION.
PROGRAM-ID. SQL-ERROR COMMON.
PROCEDURE DIVISION.
EXEC SQL
WHENEVER SQLERROR CONTINUE
END-EXEC.
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL
ROLLBACK WORK RELEASE
END-EXEC.
END PROGRAM SQL-ERROR.
END PROGRAM MAIN.

スコープ

WHENEVER文は宣言部のため、そのスコープは論理的なものではなく位置的なものになります。WHENEVER文がテストするのは、ソース・ファイルの中でそのWHENEVER文より後に記述されているすべての実行SQL文であり、プログラム・ロジックの流れの中でそのWHENEVER文より後にくる実行SQL文ではありません。したがってWHENEVER文は、テストする最初の実行SQL文の前に指定する必要があります。

WHENEVER文は、同じ条件をチェックする別のWHENEVER文に置き換えられるまで有効です。

提案: SQL文を含む各プログラム・ユニットの先頭にWHENEVER文を記述してください。このようにすると、あるプログラム・ユニット内のSQL文が別のプログラム・ユニット内のWHENEVERの処置を参照して、コンパイル時や実行時に発生するエラーを回避できます。

不注意な使用: 例

WHENEVER文を不注意に使用すると、問題が発生することがあります。たとえば、次のコードは、検索条件を満たす行がないため、DELETE文でNOT FOUND状態を設定すると無限ループに陥ります。

*    Improper use of WHENEVER.
EXEC SQL
WHENEVER NOT FOUND GOTO NO-MORE
END-EXEC.
PERFORM GET-ROWS UNTIL DONE = "YES".
...
GET-ROWS.
EXEC SQL
FETCH emp_cursor INTO :EMP-NAME, :SALARY
END-EXEC.
...
NO-MORE.
MOVE "YES" TO DONE.
EXEC SQL
DELETE FROM EMP WHERE EMPNO = :EMP-NUMBER
END-EXEC.
...

次の例では、GOTOのターゲットを設定しなおすことによってNOT FOUND状態を適切に処理しています。

*    Proper use of WHENEVER.
EXEC SQL WHENEVER NOT FOUND GOTO NO-MORE END-EXEC.
PERFORM GET-ROWS UNTIL DONE = "YES".
...
GET-ROWS.
EXEC SQL
FETCH emp_cursor INTO :EMP-NAME, :SALARY
END-EXEC.
...
NO-MORE.
MOVE "YES" TO DONE.
EXEC SQL WHENEVER NOT FOUND GOTO NONE-FOUND END-EXEC.
EXEC SQL
DELETE FROM EMP WHERE EMPNO = :EMP-NUMBER
END-EXEC.
...
NONE-FOUND.
...

SQL文のテキストの取得

多くのPro*COBOLアプリケーションでは、処理している文のテキスト、長さおよびその文に記述されているSQLコマンド(INSERTやSELECTなど)がわかると便利です。これは、動的SQLを使用するアプリケーションでは特に重要です。

ルーチンSQLGLSを使用すると、次の情報が戻されます(このルーチンはSQLLIBランタイム・ライブラリに入っています)。

- 最後に解析されたSQL文のテキスト

- その文の長さ

- 関数コード

SQLGLSは、静的SQL文の発行後にコールできます。動的SQL方法1では、SQL文の実行後にSQLGLSをコールできます。動的SQL方法2、3または4では、SQL文の作成後にSQLGLSをコールできます。

SQLGLSをコールするための構文は次のとおりです。

CALL "SQLGLS" USING SQLSTM STMLEN SQLFC.

表8-3に、SQLGLS引数リストのパラメータに使用可能なホスト言語のデータ型を示します。

表8-3 パラメータのデータ型

パラメータ

データ型

SQLSTM

PIC X(n)

STMLEN

PIC S9(9) COMP

SQLFC

PIC S9(9) COMP

パラメータはすべて、参照によって渡す必要があります。通常、デフォルトでパラメータ引渡し規則は参照によって引渡されるため、特別な処置は必要ありません。

パラメータSQLSTMは、SQL文の戻されたテキストを保持する空白埋め(ヌル文字で終了しない)文字バッファです。プログラムでは、このバッファを静的に宣言するか、このバッファに動的にメモリーを割り当てる必要があります。

長さパラメータSTMLENは4バイトの整数です。SQLGLSをコールする前に、このパラメータをSQLSTMバッファの実際のサイズ(単位はバイト)に設定します。SQLGLSが戻すときに、SQLSTMバッファには、SQL文のテキストにバッファの長さまで空白を足したものが含まれます。STMLENは戻された文テキストの実際のバイト数を戻します。足されている空白は数えません。ただし、エラーが発生した場合、STMLENはゼロを戻します。

発生する可能性のあるエラーは次のとおりです。

- SQL文が1つも解析されませんでした。

- 無効なパラメータを渡しました(たとえば、長さとして負の値を渡した場合)。

- SQLLIBで内部例外が発生しました。

パラメータSQLFCは、文中のSQLコマンドに対応するSQLファンクション・コードを戻す4バイトの整数です。SQLコマンドの関数コードの詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』の表を参照してください。

次の文には、対応するSQLファンクション・コードはありません。

- CONNECT

- COMMIT

- FETCH

- ROLLBACK

- RELEASE

Oracle通信領域の使用

SQLCAは、標準SQLの通信を対象としています。Oracle通信領域(ORACA)もSQLCAと同様の構造ですが、ORACAをプログラムに組み込むとOracle固有の通信を処理できるようになります。SQLCAで提供される情報よりも詳しい実行時情報が必要な場合に、ORACAを使用してください。

ORACAは、問題の診断に役立つのみでなく、SQL文エグゼキュータやカーソル・キャッシュ(カーソル管理のために確保されているメモリー領域)などのリソースをプログラムがどのように使用しているかを監視する場合にも使用できます。

ORACAの内容

ORACAにはオプション設定、システム統計および拡張診断機能が含まれています。図8-3に、ORACAのすべての変数を示します。

図8-3 Pro*COBOLのORACA変数宣言

ORACAの宣言

ORACAを宣言するには、次に示すように、(EXEC SQL INCLUDE文を使用して) Pro*COBOLソース・ファイルの宣言部の外に組み込みます。

*    Include the Oracle Communications Area (ORACA).
EXEC SQL INCLUDE ORACA END-EXEC.

ORACAを使用可能に設定

ORACAを使用可能にするには、ORACAプリコンパイラ・オプションをYESに設定する必要があります。これには、コマンドラインまたは構成ファイルに次のように入力します。

ORACA=YES

またはインラインで次のように指定します。

EXEC Oracle OPTION (ORACA=YES) END-EXEC.

その後、ORACA内のフラグを設定することによって、適切なランタイム・オプションを選択する必要があります。ORACAを使用可能にすると実行時のオーバーヘッドが増加することになるため、ORACAの使用はオプションになっています。デフォルトの設定はORACA=NOです。

ランタイム・オプションの選択

ORACAにはいくつかのオプション・フラグがあります。これらのフラグにゼロ以外の値を割り当てて設定すると、次のことが可能になります。

- SQL文のテキストの保存

- DEBUG処理の有効化

- カーソル・キャッシュの一貫性チェック(カーソル・キャッシュとは、カーソル管理に使用されるメモリーで継続的に更新される領域)

- ヒープの一貫性チェック(ヒープは、動的変数のために予約されるメモリー領域)

- カーソル統計情報の収集

次の説明はオプションを選択するときの参考になります。

ORACAの構造

この項では、ORACAの構造、そのフィールドおよびフィールドに格納できる値を説明します。

ORACAID

この文字列フィールドは、Oracle通信領域を示すORACAに初期化されます。

ORACABC

この整数フィールドには、ORACAデータ構造の長さ(バイト数)が格納されています。

ORACCHF

マスターDEBUGフラグ(ORADBGF)が設定されているときにこのフラグを設定すると、カーソル操作のたびにカーソル・キャッシュの一貫性をあらかじめチェックできます。

ランタイム・ライブラリでは一貫性チェックが行われ、エラー・メッセージが出力される場合もあります。エラー・メッセージのリストは、『Oracle Databaseエラー・メッセージ』を参照してください。

このフラグは次のいずれかを設定します。

設定

説明

0

キャッシュ一貫性チェックを使用禁止にします(デフォルト)。

1

キャッシュ一貫性チェックを使用可能にします。

ORADBGF

このマスター・フラグを使用すると、DEBUGオプションをすべて選択できます。このフラグには次のいずれかを設定します。

設定

説明

0

すべてのDEBUG処理を使用禁止にします(デフォルト)。

1

DEBUG操作を使用可能にします。

ORAHCHF

マスターDEBUGフラグ(ORADBGF)が設定されているときにこのフラグを設定すると、Pro*COBOLが動的にメモリーの割当てや解放を行うたびにランタイム・ライブラリを使用してヒープの一貫性をチェックできます。これはメモリー障害を起こすプログラムの不具合を検出するのに役立ちます。

このフラグはCONNECTコマンドを発行する前に設定する必要があります。また、このフラグは一度設定すると解除できなくなります。つまり、設定後にこのフラグの変更要求があっても無視されます。このフラグには次のいずれかを設定します。

設定

説明

0

ヒープの一貫性チェックを使用可能にします(デフォルト)。

1

ヒープの一貫性チェックを使用禁止にします。

ORASTXTF

このフラグを使用すると、現行のSQL文のテキストを保存するタイミングを指定できます。このフラグには次のいずれかを設定します。

設定

説明

0

SQL文のテキストを保存しません(デフォルト)。

1

SQLERRORのSQL文のテキストのみ保存します。

2

SQLERRORまたはSQLWARNINGのSQL文のテキストのみ保存します。

3

常にSQL文のテキストを保存します。

SQL文のテキストは、ORASTXTの名前のORACAサブレコードに保存されます。

診断情報

ORACAは高度な診断情報を提供します。次の変数によってエラーの位置をすばやく特定できます。

ORASTXT

このサブレコードは、問題のあるSQL文を見つけるのに役立ちます。Oracleで解析された最後のSQL文のテキストを保存できます。このサブレコードには、次の2つのフィールドがあります。

設定

説明

ORASTXTL

この整数フィールドには、現行のSQL文の長さが格納されます。

ORASTXTC

この文字列フィールドには、現行のSQL文のテキストが格納されます。先頭から最長70文字分のテキストが保存されます。

Pro*COBOLによって解析される文(CONNECT、FETCHまたはCOMMITなど)は、ORACAには保存されません。

ORASFNM

このサブレコードは、現行SQL文を含むファイルを識別し、1つのアプリケーションのために複数のファイルがプリコンパイルされるときのエラー検出に役立ちます。このサブレコードには、次の2つのフィールドがあります。

設定

説明

ORASFNML

この整数フィールドには、ORASFNMCに格納されているファイル名の長さが格納されます。

ORASFNMC

この文字列フィールドには、ファイル名が格納されます。先頭から最長70文字分が保存されます。

ORASLNR

この整数フィールドにより、現行のSQL文が記述されている行(またはその近くの行)を識別できます。

カーソル・キャッシュ統計情報

次に説明する一連の変数を使用して、カーソル・キャッシュ統計情報を収集できます。これらの変数は、プログラムがCOMMITまたはROLLBACK文を発行するたびに自動的に設定されます。内部的には、CONNECTされているデータベース別にこの変数のセットがあります。ORACAの現在の設定値は、最後にコミットまたはロールバックされたデータベースに関する値です。

ORAHOC

この整数フィールドには、プログラムの実行中にMAXOPENCURSORSに設定された最大の値が記録されます。

ORAMOC

この整数フィールドには、プログラムの要求によってオープンされたカーソルの最大数が記録されます。MAXOPENCURSORSに設定されている値が小さすぎて、その結果Pro*COBOLによってカーソル・キャッシュが拡張されると、この数はORAHOCより大きくなることがあります。

ORACOC

この整数フィールドには、プログラムの要求によって現在オープンしているカーソル数が記録されます。

ORANOR

この整数フィールドには、プログラムの要求によって再度割り当てられたカーソル・キャッシュの数が記録されます。この数値はカーソル・キャッシュのスラッシングの程度を示し、できるだけ低く抑える必要があります。

ORANPR

この整数フィールドには、プログラムの要求によって解析されたSQL文の数が記録されます。

ORANEX

この整数フィールドには、プログラムの要求によって実行されたSQL文の数が記録されます。この数値のORANPRの数値に対する割合は、できるかぎり高く保つ必要があります。つまり、不要な再解析は回避する必要があります。ヘルプについては、付録C「パフォーマンス・チューニング」を参照してください。

ORACAのサンプル・プログラム

次のプログラムは、部門番号の入力を要求し、その部門に所属している各従業員の名前と給与を2つの表のいずれかに挿入して、ORACAからの診断情報を表示します。

IDENTIFICATION DIVISION.
PROGRAM-ID. ORACAEX.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
EXEC SQL INCLUDE SQLCA END-EXEC.
EXEC SQL INCLUDE ORACA END-EXEC.

EXEC ORACLE OPTION (ORACA=YES) END-EXEC.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01 USERNAME       PIC X(20).
01 PASSWORD       PIC X(20).
01 EMP-NAME       PIC X(10) VARYING.
01 DEPT-NUMBER    PIC S9(4) COMP.
01 SALARY         PIC S9(6)V99
DISPLAY SIGN LEADING SEPARATE.
EXEC SQL END DECLARE SECTION END-EXEC.

PROCEDURE DIVISION.
DISPLAY "Username? " WITH NO ADVANCING.
ACCEPT USERNAME.
DISPLAY "Password? " WITH NO ADVANCING.
ACCEPT PASSWORD.
EXEC SQL
WHENEVER SQLERROR GOTO SQL-ERROR
END-EXEC.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWORD
END-EXEC.
DISPLAY "Connected to Oracle".

* -- set flags in the ORACA
* -- enable debug operations
MOVE 1 TO ORADBGF.
* -- enable cursor cache consistency check
MOVE 1 TO ORACCHF.
* -- always save the SQL statement
MOVE 3 TO ORASTXTF.
DISPLAY "Department number? " WITH NO ADVANCING.
ACCEPT DEPT-NUMBER.
EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT ENAME, SAL + NVL(COMM,0)
FROM EMP
WHERE DEPTNO = :DEPT-NUMBER
END-EXEC.
EXEC SQL OPEN EMPCURSOR END-EXEC.
EXEC SQL
WHENEVER NOT FOUND GOTO NO-MORE
END-EXEC.
LOOP.
EXEC SQL
FETCH EMPCURSOR INTO :EMP-NAME, :SALARY
END-EXEC.
IF SALARY < 2500
EXEC SQL
INSERT INTO PAY1 VALUES (:EMP-NAME, :SALARY)
END-EXEC
ELSE
EXEC SQL
INSERT INTO PAY2 VALUES (:EMP-NAME, :SALARY)
END-EXEC
END-IF.
GO TO LOOP.

NO-MORE.
EXEC SQL CLOSE EMPCURSOR END-EXEC.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL COMMIT WORK RELEASE END-EXEC.
DISPLAY "(NO-MORE.) Last SQL statement: ", ORASTXTC.
DISPLAY "... at or near line number:  ", ORASLNR.
DISPLAY  " ".
DISPLAY "          Cursor Cache Statistics".
DISPLAY "-------------------------------------------".
DISPLAY "Maximum value of MAXOPENCURSORS     ", ORAHOC.
DISPLAY "Maximum open cursors required:      ", ORAMOC.
DISPLAY "Current number of open cursors:     ", ORACOC.
DISPLAY "Number of cache reassignments:      ", ORANOR.
DISPLAY "Number of SQL statement parses:     ", ORANPR.
DISPLAY "Number of SQL statement executions: ", ORANEX.
STOP RUN.

SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
DISPLAY "(SQL-ERROR.) Last SQL statement: ", ORASTXTC.
DISPLAY "... at or near line number:  ", ORASLNR.
DISPLAY " ".
DISPLAY "          Cursor Cache Statistics".
DISPLAY "-------------------------------------------".
DISPLAY "MAXIMUM VALUE OF MAXOPENCURSORS     ", ORAHOC.
DISPLAY "Maximum open cursors required:      ", ORAMOC.
DISPLAY "Current number of open cursors:     ", ORACOC.
DISPLAY "Number of cache reassignments:      ", ORANOR.
DISPLAY "Number of SQL statement parses:     ", ORANPR.
DISPLAY "Number of SQL statement executions: ", ORANEX.
STOP RUN.

エラーとSQLSTATEコードの対応関係

SQLSTATEのコード、その意味および戻されるエラーを次の表に示します。

表8-4 SQLSTATEコード

コード

状態

Oracleエラー

00000

正常終了

ORA-00000

01000

警告

01001

カーソル操作の競合

01002

切断のエラー

01003

集合関数でのNULL値が排除

01004

文字列データの右側切捨て

01005

項目記述子領域が不十分

01006

権限が取り消されていません。

01007

権限が付与されていません。

01008

暗黙的ゼロビットの埋込み

01009

情報スキーマの検索条件が長すぎます。

0100A

情報スキーマの問合せ式が長すぎます。

02000

データなし

ORA-01095

ORA-01403

07000

動的SQLエラー

07001

USING句がパラメータ指定と一致しません。

07002

USING句が相手指定と一致しません。

07003

カーソル仕様を実行できません。

07004

動的パラメータにはUSING句が必要です。

07005

プリコンパイルされたSQL文がカーソル仕様ではありません。

07006

制限付きのデータ型属性違反

07007

結果フィールドにはUSING句が必要です。

07008

記述子の数が無効

SQL-02126

07009

記述子の索引が無効

08000

例外接続

08001

SQLのクライアントがSQL接続を確立できません。

08002

接続名の重複

08003

接続が存在しません。

SQL-02121

08004

SQLサーバーによるSQL接続の拒絶

08006

接続障害

08007

トランザクションの結果が不明

0A000

サポートされていない機能

ORA-03000から03099

0A001

複数のサーバー・トランザクション

21000

カーディナリティ違反

ORA-01427

SQL-02112

22000

データの例外

22001

文字列データの右側切捨て

ORA-01401

ORA-01406

22002

NULL値(インジケータ・パラメータなし)

ORA-01405

SQL-02124

22003

数値が範囲外

ORA-01426

ORA-01438

ORA-01455

ORA-01457

22005

割当てのエラー

22007

日時書式が無効

22008

日時フィールドのオーバーフロー

ORA-01800から01899

22009

タイム・ゾーンによる時差が無効

22011

副文字列のエラー

22012

0による除算

ORA-01476

22015

時間隔フィールドのオーバーフロー

22018

キャストの文字値が無効

22019

エスケープ文字が無効

ORA-00911

ORA-01425

22021

レパートリに文字がありません。

22022

インジケータのオーバーフロー

ORA-01411

22023

パラメータの値が正しくありません。

ORA-01025

ORA-01488

ORA-04000から04019

22024

C文字列が未終了

ORA-01479から01480

22025

エスケープ・シーケンスが無効

ORA-01424

22026

文字列データの長さ不一致

22027

切捨てエラー

23000

整合性制約違反

ORA-1400、ORA-00001

ORA-02290から02299

24000

カーソル状態が無効

ORA-01001から01003

ORA-01410

ORA-08006

SQL-02114

SQL-02117

SQL-02118

SQL-02122

25000

トランザクション状態が無効

26000

SQL文名が無効

27000

トリガー・データの変更違反

28000

認証の指定が無効

2A000

直接SQL構文エラーまたはアクセス規則違反

2B000

依存権限記述子がまだ存在しています。

2C000

キャラクタ・セット名が無効

2D000

トランザクションの終了が無効

2E000

接続名が無効

33000

SQL記述子名が無効

34000

カーソル名が無効

35000

状態番号が無効

37000

動的SQL構文エラーまたはアクセス規則違反

3C000

あいまいなカーソル名

3D000

カタログ名が無効

3F000

スキーマ名が無効

40000

トランザクション・ロールバック

ORA-02091から02092

40001

シリアライズ化の障害

40002

整合性制約違反

40003

文の完了が不明

42000

構文エラーまたはアクセス規則違反

ORA-00022

ORA-00251

ORA-00900から00999

ORA-01031

ORA-01490から01493

ORA-01700から01799

ORA-01900から02099

ORA-02140から02289

ORA-02420から02424

ORA-02450から02499

ORA-03276から03299

ORA-04040から04059

ORA-04070から04099

44000

WITH_CHECK_OPTION指定違反

ORA-01402

60000

システム・エラー

ORA-00370から00429

ORA-00600から00899

ORA-06430から06449

ORA-07200から07999

ORA-09700から09999

61000

リソース・エラー

ORA-00018から00035

ORA-00050から00068

ORA-02376から02399

ORA-04020から04039

62000

マルチスレッド・サーバーおよび分離プロセスのエラー

ORA-00100から00120

ORA-00440から00569

63000

Oracle XAおよび2タスク・インタフェースのエラー

ORA-00150から00159

SQL-02128

ORA-02700から02899

ORA-03100から03199

ORA-06200から06249 SQL-02128

64000

制御ファイル、データベース・ファイル、REDOファイルのエラー、および

アーカイブおよびメディア・リカバリのエラー

ORA-00200から00369

ORA-01100から01250

65000

PL/SQLのエラー

ORA-06500から06599

66000

Oracle Net Servicesドライバのエラー

ORA-06000から06149

ORA-06250から06429

ORA-06600から06999

ORA-12100から12299

ORA-12500から12599

67000

ライセンス許可エラー

ORA-00430から00439

69000

SQL*Connectのエラー

ORA-00570から00599

ORA-07000から07199

72000

SQL実行フェーズのエラー

ORA-01000から01099

ORA-01401から01489

ORA-01495から01499

ORA-01500から01699

ORA-02400から02419

ORA-02425から02449

ORA-04060から04069

ORA-08000から08190

ORA-12000から12019

ORA-12300から12499

ORA-12700から21999

82100

メモリー不足のためメモリーが割り当てられません。

SQL-02100

82101

無効なカーソル・キャッシュです。ユニット・カーソル/グローバル・カーソルが一致しません。

SQL-02101

82102

無効なカーソル・キャッシュです。グローバル・カーソル・エントリがありません。

SQL-02102

82103

無効なカーソル・キャッシュです。カーソル・キャッシュ参照の範囲を超えています。

SQL-02103

82104

無効なホスト・キャッシュです。使用可能なカーソル・キャッシュがありません。

SQL-02104

82105

無効なカーソル・キャッシュです。グローバル・カーソルがありません。

SQL-02105

82106

無効なカーソル・キャッシュです。カーソル番号が無効です。

SQL-02106

82107

ランタイム・ライブラリに対してプログラムが古すぎます。

SQL-02107

82108

ランタイム・ライブラリに無効な記述子が渡されました。

SQL-02108

82109

無効なホスト・キャッシュです。ホスト参照が範囲外です。

SQL-02109

82110

無効なホスト・キャッシュです。ホスト・キャッシュ・エントリの型が無効です。

SQL-02110

82111

ヒープの一貫性エラーが発生しました。

SQL-02111

82112

メッセージ・ファイルをオープンできません。

SQL-02113

82113

コード生成の内部整合性の障害

SQL-02115

82114

リエントラント・コード・ジェネレータが無効なコンテキストを与えました。

SQL-02116

82115

hstdef引数が無効です。

SQL-02119

82116

sqlrcnの第1引数および第2引数が両方ともNULLです。

SQL-02120

82117

データベースへの接続でのOPENまたはPREPAREが無効です。

SQL-02122

82118

アプリケーション・コンテキストが見つかりません。

SQL-02123

82119

接続エラーでメッセージを取り出せません。

SQL-02125

82120

プリコンパイラとSQLLIBのバージョンが一致しません。

SQL-02127

82121

FETCHされたバイト数が奇数です。

SQL-02129

82122

EXEC TOOLSインタフェースが使用できません。

SQL-02130

82123

ランタイム・コンテキストは使用中です。

SQL-02131

82124

ランタイム・コンテキストを割り当てできません。

SQL-02131

82125

スレッドで使用するプロセスを初期化できません。

SQL-02133

82126

ランタイムのコンテキストが無効です。

SQL-02134

90000

デバッグ・イベント

ORA-10000から10999

99999

すべて捕捉

その他すべて

HZ000

リモート・データベース・アクセス

状態変数の組合せ

MODE={ANSI | ANSI14}のときは、状態変数の動作は次の設定によって変わります。

- 宣言されている変数。

- 宣言の配置(宣言部の内部または外部)。

- ASSUME_SQLCODEの設定。

表8-5および表8-6に、ASSUME_SQLCODE=NOおよびASSUME_SQLCODE=YESのときの各状態変数の組合せの動作結果をそれぞれ示します。

両方の表には次のことが適用されます。DECLARE_SECTION=NOの場合は、状態変数の宣言はすべて(宣言部の)内部にあるものとして扱われます。

ASSUME_SQLCODE=YESは、DECLARE_SECTION=NOと併用しないでください。

表8-5 ASSUME_SQLCODE=NO、MODE=ANSI | ANSI1、DECLARE_SECTION=YESのときの状態変数の動作

宣言部

(IN/OUT/-

)

動作

SQLCODE

SQLSTATE

SQLCA

-

OUT

—

—

SQLCODEが宣言され、状態変数であるとみなされます。

OUT

—

OUT

この状態変数の構成はサポートされていません。

OUT

—

IN

この状態変数の構成はサポートされていません。

OUT

OUT

—

SQLCODEが宣言され、状態変数とみなされます。SQLSTATEは宣言されますが、状態変数とは認識されません。

OUT

OUT

OUT

この状態変数の構成はサポートされていません。

OUT

OUT

IN

この状態変数の構成はサポートされていません。

OUT

IN

—

SQLSTATEが状態変数として宣言されます。SQLCODEは宣言されますが、状態変数とは認識されません。

OUT

IN

OUT

この状態変数の構成はサポートされていません。

OUT

IN

IN

この状態変数の構成はサポートされていません。

IN

—

—

SQLCODEが状態変数として宣言されます。

IN

—

OUT

この状態変数の構成はサポートされていません。

IN

—

IN

この状態変数の構成はサポートされていません。

IN

OUT

—

SQLCODEが状態変数として宣言されます。SQLSTATEは宣言されますが、状態変数とは認識されません。

IN

OUT

OUT

この状態変数の構成はサポートされていません。

IN

OUT

IN

この状態変数の構成はサポートされていません。

IN

IN

—

SQLCODEおよびSQLSTATEが状態変数として宣言されます。

IN

IN

OUT

この状態変数の構成はサポートされていません。

IN

IN

IN

この状態変数の構成はサポートされていません。

—

—

—

この状態変数の構成はサポートされていません。

—

—

OUT

SQLCAが状態変数として宣言されます。

—

—

IN

SQLCAが状態ホスト変数として宣言されます。

—

OUT

—

この状態変数の構成はサポートされていません。

—

OUT

OUT

SQLCAが状態変数として宣言されます。SQLSTATEは宣言されますが、状態変数とは認識されません。

—

OUT

IN

SQLCAが状態ホスト変数として宣言されます。SQLSTATEは宣言されますが、状態変数とは認識されません。

—

IN

—

SQLSTATEが状態変数として宣言されます。

—

IN

OUT

SQLSTATEおよびSQLCAが状態変数として宣言されます。

—

IN

IN

SQLSTATEおよびSQLCAが状態ホスト変数として宣言されます。

表8-6 ASSUME_SQLCODE=YES、MODE=ANSI | ANSI14、DECLARE_SECTION=YESのときの状態変数の動作

宣言部(IN/OUT/ —)

動作

SQLCODE

SQLSTATE

SQLCA

OUT

—

—

SQLCODEが宣言され、状態変数であるとみなされます。

OUT

—

OUT

この状態変数の構成はサポートされていません。

OUT

—

IN

この状態変数の構成はサポートされていません。

OUT

OUT

—

SQLCODEが宣言され、状態変数とみなされます。SQLSTATEは宣言されますが、状態変数とは認識されません。

OUT

OUT

OUT

この状態変数の構成はサポートされていません。

OUT

OUT

IN

この状態変数の構成はサポートされていません。

OUT

IN

—

SQLSTATEが状態変数として宣言されます。SQLCODEは宣言されますが、状態変数とはみなされません。

OUT

IN

OUT

この状態変数の構成はサポートされていません。

OUT

IN

IN

この状態変数の構成はサポートされていません。

IN

—

—

SQLCODEが状態変数として宣言されます。

IN

—

OUT

この状態変数の構成はサポートされていません。

IN

—

IN

この状態変数の構成はサポートされていません。

IN

OUT

—

SQLCODEが状態変数として宣言されます。SQLSTATEは宣言されますが、状態変数とは認識されません。

IN

OUT

OUT

この状態変数の構成はサポートされていません。

IN

OUT

IN

この状態変数の構成はサポートされていません。

IN

IN

—

SQLCODEおよびSQLSTATEが状態変数として宣言されます。

IN

IN

OUT

この状態変数の構成はサポートされていません。

IN

IN

IN

この状態変数の構成はサポートされていません。

—

—

—

—

—

—

—

—

—

—

—

—

OUT

OUT

OUT

IN

IN

IN

—

OUT

IN

—

OUT

IN

—

OUT

IN

これらの状態変数の構成はサポートされていません。ASSUME_SQLCODE=YESのときは、SQLCODEを宣言する必要があります。

9 Oracle動的SQL

この章では、アプリケーションに柔軟性や機能性をもたらす高度なプログラミング技法である動的SQLの使用方法について説明します。動的SQLの長所と短所を比較した後、実行時にSQL文をその場で受け入れて処理するプログラムを記述する方法を、単純なものから複雑なものまで4つ紹介します。それぞれの方法の要件および制限事項、さらに実行するジョブに対する適切な方法の選択方法についても説明します。

内容は次のとおりです。

- 動的SQL

- 動的SQLの長所および短所

- 動的SQLを使用する場合

- 動的SQL文の要件

- 動的SQL文の処理

- 動的SQLの使用方法

- 方法1の使用方法

- サンプル・プログラム6: 動的SQL方法1

- 方法2の使用方法

- サンプル・プログラム7: 動的SQL方法2

- 方法3の使用方法

- サンプル・プログラム8: 動的SQL方法3

- 方法4の使用方法

- DECLARE STATEMENT文の使用方法

- ホスト表の使用方法

- PL/SQLの使用方法

- 動的SQL文のキャッシング

動的SQL

ほとんどのデータベース・アプリケーションでは、ある特定のジョブが実行されます。たとえば、ユーザーに従業員番号の入力を要求して、その後EMPおよびDEPTの表の行を更新するという単純なプログラムがあります。この場合は、プリコンパイル時にUPDATE文の構成がわかっています。つまり、変更する表、それぞれの表および列に定義されている制約、更新する列、それぞれの列のデータ型がわかっています。

しかし、アプリケーションによっては、様々なSQL文を実行時に受け入れ(または作成し)、処理する必要があります。たとえば汎用レポート・ライターでは、生成するレポートについてそれぞれ別のSELECT文を作成する必要があります。この場合、文の構成は実行時までわかりません。このような文は実行のたびに異なる可能性があります。このような文を動的SQL文と呼びます。

静的SQL文とは異なり、動的SQL文はソース・プログラム内には埋め込まれません。そのかわり、これらの文は実行時にプログラムに入力される(またはプログラムによって作成される)文字列に格納されます。動的SQL文は対話形式で入力できるのみでなく、ファイルから読み込むこともできます。

動的SQLの長所および短所

通常の埋込みSQLプログラムと比べると、動的に定義されたSQL文を受け入れて処理するホスト・プログラムの方が柔軟性は高くなります。動的SQL文は、SQLの知識がほとんどないユーザーでも対話形式で作成できます。

たとえば、SELECT文、UPDATE文またはDELETE文のWHERE句内で使用する検索条件の入力をユーザーに要求する単純なプログラムがあります。さらに複雑なプログラムでは、SQL処理、表およびビューの名前、列の名前などを表示されているメニューからユーザーが選択できるようになります。このように、動的SQLを使用すると柔軟性に富んだアプリケーションを記述できます。

ただし、動的問合せの中には複雑なコーディング、特殊なデータ構造体の使用および実行時の処理の増加が必要なものもあります。処理時間が増えることは支障がない場合もありますが、動的SQLの概念および方法を完全に理解するまではコーディングが難しく感じられることもあります。

動的SQLを使用する場合

実際は静的SQLによって、プログラミング要件のほとんどを満たすことができます。動的SQLは、その高度な柔軟性が必要とされる場合にのみ使用してください。動的SQLの使用が望ましいのは、次の項目の中に、プリコンパイル時に不明なものが1つ以上ある場合です。

- SQL文のテキスト(コマンドまたは句など)

- ホスト変数の数

- ホスト変数のデータ型

- データベース・オブジェクトの参照(列、索引、順序、表、ユーザー名またはビューなど)

動的SQL文の要件

動的SQL文を表す文字列は、有効なDML SQL文またはDDL SQL文のテキストを含む必要がありますが、EXEC SQL句、ホスト言語のデリミタまたは文の終了記号は含みません。

ほとんどの場合、この文字列にはダミーのホスト変数が含まれます。これらはSQL文内に実際のホスト変数のための場所を確保します。ダミーのホスト変数は単なるプレースホルダ(場所を確保するもの)であるため、宣言する必要はなく、任意の名前を付けられます(ハイフンは使用できません)。たとえば、Oracleでは次の2つの文字列は区別されません。

'DELETE FROM EMP WHERE MGR = :MGRNUMBER AND JOB = :JOBTITLE'
'DELETE FROM EMP WHERE MGR = :M AND JOB = :J'

動的SQL文の処理

一般にアプリケーション・プログラムでは、SQL文のテキストおよびその文で使用するホスト変数の値をユーザーが入力する必要があります。SQL文はOracleによって解析されます。解析では、SQL文が構文規則に従っているか、有効なデータベース・オブジェクトを参照しているかについて調べられます。また、データベース・アクセス権限のチェック、必要なリソースの確保および最適なアクセス・パスの検索も行われます。

次に、Oracleはホスト変数をSQL文にバインドします。これにより、Oracleはホスト変数のアドレスを取得し、その値の読取りまたは書込みを実行できます。

文が問合せの場合、SELECT変数を定義すると、OracleによってFETCHが実行され、すべての行が取り出されます。カーソルがクローズします。

この後、OracleでSQL文が実行されます。つまり、そのSQL文の要求(表からの行の削除など)をOracleが実行します。

これらのホスト変数に別の値を指定すると、このSQL文を繰り返し実行できます。

動的SQLの使用方法

この項では、動的SQL文の定義に使用できる4つの方法を紹介します。まずそれぞれの方法の機能および制限事項を簡単に説明した後、適切な方法を選択するためのガイドラインを示します。詳細な使用方法は、以降の項を参照してください。

この4つの方法は番号が大きくなるに従って対象が広がるようになっています。つまり方法2は方法1を包含し、方法3は方法1と方法2を包含するというようになります。ただし、表9-1に示すように、それぞれの方法は特定の種類のSQL文を処理する場合に最も役立ちます。

表9-1 適切な使用方法

方法

SQL文の種類

1

入力ホスト変数のない非問合せ。

2

入力ホスト変数の数がわかっている非問合せ。

3

選択リスト項目の数および入力ホスト変数の数がわかっている問合せ。

4

選択リスト項目の数または入力ホスト変数の数が不明な問合せ。

選択リスト項目には、列名や式を使用します。

方法1

この方法では、動的SQL文を受け入れるかまたは作成し、EXECUTE IMMEDIATEコマンドを使用してその文をすぐに実行できます。このSQL文では、問合せ(SELECT文)の使用や、入力ホスト変数に対するプレースホルダの組込みはできません。たとえば、次のホスト文字列は有効です。

'DELETE FROM EMP WHERE DEPTNO = 20'

'GRANT SELECT ON EMP TO SCOTT'

方法1では、SQL文は実行のたびに解析されます(HOLD_CURSOR=YESと指定した場合でも関係ありません)。

方法2

この方法では、動的SQL文を受け入れるかまたは作成し、PREPAREおよびEXECUTEコマンドを使用してその文を処理できます。SQL文は問合せであってはなりません。入力ホスト変数のプレースホルダの数と入力ホスト変数のデータ型はプリコンパイル時にわかっている必要があります。たとえば次のホスト文字列はこのカテゴリに該当します。

'INSERT INTO EMP (ENAME, JOB) VALUES (:EMPNAME, :JOBTITLE)'
'DELETE FROM EMP WHERE EMPNO = :EMPNUMBER'

方法2では、PREPAREを1回コールすることによりSQL文の解析を1回行うことができます。ホスト変数に異なる値を指定して、このSQL文を複数回実行できます。RELEASE_CURSOR=YESと指定されている場合は、複数回実行することはできません。実行のたびに文を準備しなおす必要があるためです。

注意:
CREATEなどのSQLデータ定義文は、PREPAREの完了時に1回実行されます。

方法3

この方法では、動的問合せを受け入れるか、または作成し、DECLARE、OPEN、FETCHおよびCLOSEカーソル・コマンドとともにPREPAREコマンドを使用してその問合せを処理できます。選択リスト項目の数、入力ホスト変数に対するプレースホルダの数、および入力ホスト変数のデータ型は、プリコンパイル時にわかっている必要があります。たとえば、次のホスト文字列は有効です。

'SELECT DEPTNO, MIN(SAL), MAX(SAL) FROM EMP GROUP BY DEPTNO'
'SELECT ENAME, EMPNO FROM EMP WHERE DEPTNO = :DEPTNUMBER'

方法4

この方法では、動的SQL文を受け入れるかまたは作成し、記述子(「方法4の使用方法」を参照)を使用してその文を処理できます。選択リスト項目の数、入力ホスト変数に対するプレースホルダの数、および入力ホスト変数のデータ型は、実行時まで不明でもかまいません。たとえば次のホスト文字列はこのカテゴリに該当します。

'INSERT INTO EMP (unknown) VALUES (unknown)'

'SELECT unknown FROM EMP WHERE DEPTNO = 20'

方法4は、選択リスト項目の数または入力ホスト変数の数が不明な動的SQL文を実行するときに必要です。

ガイドライン

4つの方法はどれも、動的SQL文を文字列に格納する必要があり、この文字列は、ホスト変数または引用符で囲んだリテラルであることが必要です。SQL文を文字列に格納する場合は、キーワードEXEC SQLおよび文の終了記号は省略してください。

方法2および方法3では、プリコンパイル時に入力ホスト変数に対するプレースホルダの数および入力ホスト変数のデータ型がわかっている必要があります。

方法の番号が大きくなるほどアプリケーションへの制約は少なくなりますが、コードの記述が難しくなります。通常は、最も簡単な方法を使用してください。ただし、動的SQL文を繰返し実行する場合、方法1では実行のたびに再解析されるので、これを避けるために方法2を使用してください。

方法4は最も柔軟性に富んでいますが、複雑なコード記述方法および動的SQLの概念の完全な理解が求められます。通常、方法4を使用するのは、方法1、2または3を使用できない場合のみです。

図9-1「正しい方法の選択」を参考にして、適切な方法を選択してください。

一般的なエラーの回避

動的SQL文を文字配列に格納する場合は、その配列に空白を埋め込んでからSQL文を格納してください。こうして余分な文字を消去します。別のSQL文を格納するために配列を再利用するときに、この処理が重要となります。原則として、SQL文を格納する前に必ずホスト文字列を初期化(または再初期化)してください。

ホスト文字列にはヌル終端文字を使用しないでください。Oracleでは、ヌル終端文字は文字列の終了マーカーとはみなされません。SQL文の一部として扱われます。

動的SQL文をVARCHAR変数に格納する場合は、VARCHAR変数の長さを正しく設定(または再設定)してからPREPARE文およびEXECUTE IMMEDIATE文を実行してください。

EXECUTEを実行すると、SQLCAのSQLWARN警告フラグはリセットされます。したがって、無条件の更新(これはWHERE句を指定しなかった場合に発生します)などの誤りを検出するには、PREPARE文を実行してからEXECUTE文を実行するまでの間にSQLWARNフラグをチェックする必要があります。

図9-1に、正しい方法を選択する方法を示します。

図9-1 正しい方法の選択

方法1の使用方法

最も単純な動的SQL文では、結果が成功か失敗のどちらかで、ホスト変数は使用されません。次に、いくつかの例を示します。

'DELETE FROM table_name WHERE column_name = constant'
'CREATE TABLE table_name ...'
'DROP INDEX index_name'
'UPDATE table_name SET column_name = constant'
'GRANT SELECT ON table_name TO username'

EXECUTE IMMEDIATE文

方法1では、SQL文を解析すると、EXECUTE IMMEDIATEコマンドを使用してすぐに実行します。コマンドの後には、実行するSQL文を含む文字列(ホスト変数またはリテラル)が続きますが、この文は問合せにしないでください。

EXECUTE IMMEDIATE文の構文は次のとおりです。

EXEC SQL EXECUTE IMMEDIATE { :HOST-STRING | STRING-LITERAL }END-EXEC.

次の例では、ユーザーが入力するSQL文をホスト変数SQL-STMTに格納しています。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01   SQL-STMT  PIC X(120);
EXEC SQL END DECLARE SECTION END-EXEC.
...
LOOP.
DISPLAY 'Enter SQL statement: ' WITH NO ADVANCING.
ACCEPT SQL-STMT END-EXEC.
* --  sql_stmt now contains the text of a SQL statement
EXEC SQL EXECUTE IMMEDIATE :SQL-STMT END-EXEC.
NEXT.
...

EXECUTE IMMEDIATEは入力されているSQL文を実行するたびに解析するため、方法1は1回しか実行しない文に最も適しています。通常、データ定義文は、このカテゴリに入ります。

例

次のプログラムは、UPDATE文のWHERE句で使用する検索条件の入力をユーザーに求め、方法1を使用してUPDATE文を実行します。

...
*    THE RELEASE_CURSOR=YES OPTION INSTRUCTS PRO*COBOL TO
*    RELEASE IMPLICIT CURSORS ASSOCIATED WITH EMBEDDED SQL
*    STATEMENTS.  THIS ENSURES THAT Oracle DOES NOT KEEP PARSE
*    LOCKS ON TABLES, SO THAT SUBSEQUENT DATA MANIPULATION
*    OPERATIONS ON THOSE TABLES DO NOT RESULT IN PARSE-LOCK
*    ERRORS.

EXEC ORACLE OPTION (RELEASE_CURSOR=YES) END-EXEC.

*
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME  PIC X(10) VALUE "SCOTT".
01  PASSWD    PIC X(10) VALUE "TIGER".
01  DYNSTMT   PIC X(80).
EXEC SQL END DECLARE SECTION END-EXEC.
01  UPDATESTMT PIC X(40).
01  SEARCH-COND PIC X(40).
...
DISPLAY "ENTER A SEARCH CONDITION FOR STATEMENT:".
MOVE "UPDATE EMP SET COMM = 500 WHERE " TO UPDATESTMT.
DISPLAY UPDATESTMT.
ACCEPT SEARCH-COND.
*    Concatenate SEARCH-COND to UPDATESTMT and store result
*    in DYNSTMT.
STRING UPDATESTMT DELIMITED BY SIZE
SEARCH-COND DELIMITED BY SIZE INTO DYNSTMT.
EXEC SQL EXECUTE IMMEDIATE :DYNSTMT END-EXEC.

サンプル・プログラム6: 動的SQL方法1

このプログラムは、動的SQL方法1を使用して、表の作成、行の挿入、挿入のコミットおよび表の削除を行います。

*****************************************************************
* Sample Program 6:  Dynamic SQL Method 1                       *
*                                                               *
* This program uses dynamic SQL Method 1 to create a table,     *
* insert a row, commit the insert, then drop the table.         *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID.  DYNSQL1.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

*    INCLUDE THE ORACLE COMMUNICATIONS AREA, A STRUCTURE
*    THROUGH WHICH ORACLE MAKES ADDITIONAL RUNTIME STATUS
*    INFORMATION AVAILABLE TO THE PROGRAM.

EXEC SQL INCLUDE SQLCA END-EXEC.

*    INCLUDE THE ORACLE COMMUNICATIONS AREA, A STRUCTURE
*    THROUGH WHICH ORACLE MAKES ADDITIONAL RUNTIME STATUS
*    INFORMATION AVAILABLE TO THE PROGRAM.

EXEC SQL INCLUDE ORACA END-EXEC.

*    THE OPTION ORACA=YES MUST BE SPECIFIED TO ENABLE USE OF
*    THE ORACA.

EXEC ORACLE OPTION (ORACA=YES) END-EXEC.

*    THE RELEASE_CURSOR=YES OPTION INSTRUCTS PRO*COBOL TO
*    RELEASE IMPLICIT CURSORS ASSOCIATED WITH EMBEDDED SQL
*    STATEMENTS.  THIS ENSURES THAT ORACLE DOES NOT KEEP PARSE
*    LOCKS ON TABLES, SO THAT SUBSEQUENT DATA MANIPULATION
*    OPERATIONS ON THOSE TABLES DO NOT RESULT IN PARSE-LOCK
*    ERRORS.

EXEC ORACLE OPTION (RELEASE_CURSOR=YES) END-EXEC.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME  PIC X(10) VALUE "SCOTT".
01  PASSWD    PIC X(10) VALUE "TIGER".
01  DYNSTMT   PIC X(80) VARYING.
EXEC SQL END DECLARE SECTION END-EXEC.

*    DECLARE VARIABLES NEEDED TO DISPLAY COMPUTATIONALS.
01  ORASLNRD  PIC 9(9).

PROCEDURE DIVISION.

MAIN.

*    BRANCH TO PARAGRAPH SQLERROR IF AN ORACLE ERROR OCCURS.
EXEC SQL WHENEVER SQLERROR GOTO SQLERROR END-EXEC.

*    SAVE TEXT OF CURRENT SQL STATEMENT IN THE ORACA IF AN ERROR
*    OCCURS.
MOVE 1 TO ORASTXTF.

*    CONNECT TO ORACLE.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE AS USER:  " WITH NO ADVANCING.
DISPLAY USERNAME.
DISPLAY " ".

*    EXECUTE A STRING LITERAL TO CREATE THE TABLE.  HERE, YOU
*    GENERALLY USE A STRING VARIABLE INSTEAD OF A LITERAL, AS IS
*    DONE LATER IN THIS PROGRAM.  BUT, YOU CAN USE A LITERAL IF
*    YOU WISH.
DISPLAY "CREATE TABLE DYN1 (COL1 CHAR(4))".
DISPLAY " ".
EXEC SQL EXECUTE IMMEDIATE
"CREATE TABLE DYN1 (COL1 CHAR(4))"
END-EXEC.

*    ASSIGN A SQL STATEMENT TO THE VARYING STRING DYNSTMT.
*    SET THE -LEN PART TO THE LENGTH OF THE -ARR PART.
MOVE "INSERT INTO DYN1 VALUES ('TEST')" TO DYNSTMT-ARR.
MOVE 36 TO DYNSTMT-LEN.
DISPLAY DYNSTMT-ARR.
DISPLAY " ".

*    EXECUTE DYNSTMT TO INSERT A ROW.  THE SQL STATEMENT IS A
*    STRING VARIABLE WHOSE CONTENTS THE PROGRAM MAY DETERMINE
*    AT RUN TIME.
EXEC SQL EXECUTE IMMEDIATE :DYNSTMT END-EXEC.

*    COMMIT THE INSERT.
EXEC SQL COMMIT WORK END-EXEC.

*    CHANGE DYNSTMT AND EXECUTE IT TO DROP THE TABLE.
MOVE "DROP TABLE DYN1" TO DYNSTMT-ARR.
MOVE 19 TO DYNSTMT-LEN.
DISPLAY DYNSTMT-ARR.
DISPLAY " ".
EXEC SQL EXECUTE IMMEDIATE :DYNSTMT END-EXEC.

*    COMMIT ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
EXEC SQL COMMIT RELEASE END-EXEC.
DISPLAY "HAVE A GOOD DAY!".
DISPLAY " ".
STOP RUN.

SQLERROR.

*    ORACLE ERROR HANDLER.  PRINT DIAGNOSTIC TEXT CONTAINING
*    ERROR MESSAGE, CURRENT SQL STATEMENT, AND LOCATION OF ERROR.
DISPLAY SQLERRMC.
DISPLAY "IN ", ORASTXTC.
MOVE ORASLNR TO ORASLNRD.
DISPLAY "ON LINE ", ORASLNRD, " OF ", ORASFNMC.

*    DISABLE ORACLE ERROR CHECKING TO AVOID AN INFINITE LOOP
*    SHOULD ANOTHER ERROR OCCUR WITHIN THIS PARAGRAPH.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.

*    ROLL BACK ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
EXEC SQL ROLLBACK RELEASE END-EXEC.
STOP RUN.

方法2の使用方法

方法1では1ステップで実行し、方法2では2ステップに分けて実行します。動的SQL文(問合せは不可)は、まず準備(名前の指定および解析)され、次に実行されます。

方法2では、SQL文の中にホスト変数および標識変数のプレースホルダを使用できます。このSQL文は一度PREPAREすると、ホスト変数に別の値を指定して繰り返しEXECUTEできます。また、MODE=ANSIと指定しなかった場合も、COMMITまたはROLLBACKの後でSQL文を再度PREPAREする必要はありません(ログオフして再接続する場合は除きます)。

PREPARE文の構文は次のとおりです。

EXEC SQL PREPARE STATEMENT-NAME
FROM { :HOST-STRING | STRING-LITERAL }
END-EXEC.

PREPAREは、このSQL文を解析して名前を指定します。

STATEMENT-NAMEは、ホスト変数やプログラム変数ではなく、プリコンパイラが使用する識別子であるため、COBOL文では定義しないでください。これはEXECUTEの対象としてプリコンパイルされたSQL文を示しています。

EXECUTE文の構文は次のとおりです。

EXEC SQL
EXECUTE STATEMENT-NAME [USING HOST-VARIABLE-LIST]
END-EXEC.

HOST-VARIABLE-LISTの構文を次に示します。

:HOST-VAR1[:INDICATOR1] [, HOST-VAR2[:INDICATOR2], ...]

解析したSQL文は、それぞれの入力ホスト変数に指定済の値を使用してEXECUTEによって実行されます。次の例では、入力SQL文にプレースホルダnが組み込まれています。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01  EMP-NUMBER   PIC S9(4) COMP VALUE ZERO.
...
01  DELETE-STMT   PIC X(120) VALUE SPACES.
...
EXEC SQL END DECLARE SECTION END-EXEC.
01  WHERE-STMT    PIC X(40).
01  SEARCH-COND   PIC X(40).
...
MOVE 'DELETE FROM EMP WHERE EMPNO = :N AND ' TO WHERE-STMT.
DISPLAY 'Complete this statement's search condition:'.
DISPLAY WHERE-STMT.
ACCEPT SEARCH-COND.
*    Concatenate SEARCH-COND to WHERE-STMT and store in DELETE-STMT
STRING WHERE-STMT DELIMITED BY SIZE
SEARCH-COND DELIMITED BY SIZE INTO
DELETE-STMT.
EXEC SQL PREPARE SQLSTMT FROM :DELETE-STMT END-EXEC.
LOOP.
DISPLAY 'Enter employee number: ' WITH NO ADVANCING.
ACCEPT EMP-NUMBER.
IF EMP-NUMBER = 0
GO TO NEXT.
EXEC SQL EXECUTE SQLSTMT USING :EMP-NUMBER END-EXEC.
NEXT.

方法2では、プリコンパイル時に入力ホスト変数のデータ型がわかっている必要があります。最後の例では、EMP-NUMBERがPIC S9(4) COMP型で宣言されています。Oracleでは、内部NUMBERデータ型へのデータ型変換がすべてサポートされているので、入力ホスト変数をPIC X(4)型またはCOMP-1型で宣言することもできます。

USING句

SQL文EXECUTEが完了すると、USING句の入力ホスト変数が、対応するプリコンパイルされた動的SQL文中のプレースホルダに置き換えられます。

PREPAREの後の動的SQL文中のプレースホルダはすべて、USING句のホスト変数に対応している必要があります。このため、PREPAREの後の文で同じプレースホルダが複数回使用されている場合は、それぞれがUSING句の中のホスト変数に対応している必要があります。USING句のホスト変数のうち1つでも配列がある場合は、すべてのホスト変数が配列であることが必要です。それ以外の場合は、レコードが1つだけ処理されます。

プレースホルダの名前とホスト変数の名前が一致している必要はありません。ただし、PREPAREの後の動的SQL文中のプレースホルダの順序は、USING句の対応するホスト変数の順序と一致している必要があります。

NULLを指定するために、標識変数をUSING句のホスト変数と対応付けることができます。詳細は、「標識変数の使用」を参照してください。

サンプル・プログラム7: 動的SQL方法2

このプログラムは、動的SQL方法2を使用して、EMP表に2行挿入し、挿入した行を削除します。

*****************************************************************
* Sample Program 7:  Dynamic SQL Method 2                       *
*                                                               *
* This program uses dynamic SQL Method 2 to insert two rows     *
* into the EMP table, then delete them.                         *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID.  DYNSQL2.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

*    INCLUDE THE SQL COMMUNICATIONS AREA, A STRUCTURE THROUGH
*    WHICH ORACLE MAKES RUNTIME STATUS INFORMATION (SUCH AS ERROR
*    CODES, WARNING FLAGS, AND DIAGNOSTIC TEXT) AVAILABLE TO THE
*    PROGRAM.
EXEC SQL INCLUDE SQLCA END-EXEC.

*    INCLUDE THE ORACLE COMMUNICATIONS AREA, A STRUCTURE THROUGH
*    WHICH ORACLE MAKES ADDITIONAL RUNTIME STATUS INFORMATION
*    AVAILABLE TO THE PROGRAM.
EXEC SQL INCLUDE ORACA END-EXEC.

*    THE OPTION ORACA=YES MUST BE SPECIFIED TO ENABLE USE OF
*    THE ORACA.
EXEC ORACLE OPTION (ORACA=YES) END-EXEC.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME  PIC X(10) VALUE "SCOTT".
01  PASSWD    PIC X(10) VALUE "TIGER".
01  DYNSTMT   PIC X(80) VARYING.
01  EMPNO     PIC S9(4) COMPUTATIONAL VALUE 1234.
01  DEPTNO1   PIC S9(4) COMPUTATIONAL VALUE 10.
01  DEPTNO2   PIC S9(4) COMPUTATIONAL VALUE 20.
EXEC SQL END DECLARE SECTION END-EXEC.

*    DECLARE VARIABLES NEEDED TO DISPLAY COMPUTATIONALS.
01  EMPNOD    PIC 9(4).
01  DEPTNO1D  PIC 9(2).
01  DEPTNO2D  PIC 9(2).
01  ORASLNRD  PIC 9(9).

PROCEDURE DIVISION.
MAIN.

*    BRANCH TO PARAGRAPH SQLERROR IF AN ORACLE ERROR OCCURS.
EXEC SQL WHENEVER SQLERROR GOTO SQLERROR END-EXEC.

*    SAVE TEXT OF CURRENT SQL STATEMENT IN THE ORACA IF AN ERROR
*    OCCURS.
MOVE 1 TO ORASTXTF.

*    CONNECT TO ORACLE.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE.".
DISPLAY " ".

*    ASSIGN A SQL STATEMENT TO THE VARYING STRING DYNSTMT.  BOTH
*    THE ARRAY AND THE LENGTH PARTS MUST BE SET PROPERLY.  NOTE
*    THAT THE STATEMENT CONTAINS TWO HOST VARIABLE PLACEHOLDERS,
*    V1 AND V2, FOR WHICH ACTUAL INPUT HOST VARIABLES MUST BE
*    SUPPLIED AT EXECUTE TIME.
MOVE "INSERT INTO EMP (EMPNO, DEPTNO) VALUES (:V1, :V2)"
TO DYNSTMT-ARR.
MOVE 49 TO DYNSTMT-LEN.

*    DISPLAY THE SQL STATEMENT AND ITS CURRENT INPUT HOST
*    VARIABLES.
DISPLAY DYNSTMT-ARR.
MOVE EMPNO TO EMPNOD.
MOVE DEPTNO1 TO DEPTNO1D.
DISPLAY "    V1 = ", EMPNOD, "    V2 = ", DEPTNO1D.

*    THE PREPARE STATEMENT ASSOCIATES A STATEMENT NAME WITH A
*    STRING CONTAINING A SQL STATEMENT.  THE STATEMENT NAME IS
*    A SQL IDENTIFIER, NOT A HOST VARIABLE, AND THEREFORE DOES
*    NOT APPEAR IN THE DECLARE SECTION.

*    A SINGLE STATEMENT NAME MAY BE PREPARED MORE THAN ONCE,
*    OPTIONALLY FROM A DIFFERENT STRING VARIABLE.
EXEC SQL PREPARE S FROM :DYNSTMT END-EXEC.

*    THE EXECUTE STATEMENT EXECUTES A PREPARED SQL STATEMENT
*    USING THE SPECIFIED INPUT HOST VARIABLES, WHICH ARE
*    SUBSTITUTED POSITIONALLY FOR PLACEHOLDERS IN THE PREPARED
*    STATEMENT.  FOR EACH OCCURRENCE OF A PLACEHOLDER IN THE
*    STATEMENT THERE MUST BE A VARIABLE IN THE USING CLAUSE.
*    THAT IS, IF A PLACEHOLDER OCCURS MULTIPLE TIMES IN THE
*    STATEMENT, THE CORRESPONDING VARIABLE MUST APPEAR
*    MULTIPLE TIMES IN THE USING CLAUSE.  THE USING CLAUSE MAY
*    BE OMITTED ONLY IF THE STATEMENT CONTAINS NO PLACEHOLDERS.
*    A SINGLE PREPARED STATEMENT MAY BE EXECUTED MORE THAN ONCE,
*    OPTIONALLY USING DIFFERENT INPUT HOST VARIABLES.
EXEC SQL EXECUTE S USING :EMPNO, :DEPTNO1 END-EXEC.

*    INCREMENT EMPNO AND DISPLAY NEW INPUT HOST VARIABLES.
ADD 1 TO EMPNO.
MOVE EMPNO TO EMPNOD.
MOVE DEPTNO2 TO DEPTNO2D.
DISPLAY "    V1 = ", EMPNOD, "    V2 = ", DEPTNO2D.

*    REEXECUTE S TO INSERT THE NEW VALUE OF EMPNO AND A
*    DIFFERENT INPUT HOST VARIABLE, DEPTNO2.  A REPREPARE IS NOT
*    NECESSARY.
EXEC SQL EXECUTE S USING :EMPNO, :DEPTNO2 END-EXEC.

*    ASSIGN A NEW VALUE TO DYNSTMT.
MOVE "DELETE FROM EMP WHERE DEPTNO = :V1 OR DEPTNO = :V2"
TO DYNSTMT-ARR.
MOVE 50 TO DYNSTMT-LEN.

*    DISPLAY THE NEW SQL STATEMENT AND ITS CURRENT INPUT HOST
*    VARIABLES.
DISPLAY DYNSTMT-ARR.
DISPLAY "    V1 = ", DEPTNO1D, "      V2 = ", DEPTNO2D.

*    REPREPARE S FROM THE NEW DYNSTMT.
EXEC SQL PREPARE S FROM :DYNSTMT END-EXEC.

*    EXECUTE THE NEW S TO DELETE THE TWO ROWS PREVIOUSLY
*    INSERTED.
EXEC SQL EXECUTE S USING :DEPTNO1, :DEPTNO2 END-EXEC.

*    ROLLBACK ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
EXEC SQL ROLLBACK RELEASE END-EXEC.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY!".
DISPLAY " ".
STOP RUN.

SQLERROR.
*    ORACLE ERROR HANDLER.  PRINT DIAGNOSTIC TEXT CONTAINING
*    ERROR MESSAGE, CURRENT SQL STATEMENT, AND LOCATION OF ERROR.
DISPLAY SQLERRMC.
DISPLAY "IN ", ORASTXTC.
MOVE ORASLNR TO ORASLNRD.
DISPLAY "ON LINE ", ORASLNRD, " OF ", ORASFNMC.

*    DISABLE ORACLE ERROR CHECKING TO AVOID AN INFINITE LOOP
*    SHOULD ANOTHER ERROR OCCUR WITHIN THIS PARAGRAPH.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.

*    ROLL BACK ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
EXEC SQL ROLLBACK RELEASE END-EXEC.
STOP RUN.

方法3の使用方法

方法3は方法2に似ていますが、PREPARE文をカーソルの定義および処理に必要な文と結合する点で異なります。これによって、プログラムで問合せを受け入れて処理できます。動的SQL文が問合せである場合は、方法3または方法4を必ず使用してください。

方法3では、プリコンパイル時に問合せ選択リスト内の列の数および入力ホスト変数に対するプレースホルダの数がわかっている必要があります。ただし、表や列などのデータベース・オブジェクトの名前は、実行時に指定できます(ホスト変数と重複する名前は無効です)。問合せ結果を限定、分類およびソートする句(WHERE、GROUP BY、ORDER BYなど)も実行時に指定できます。

方法3では、埋込みSQL文を次のような順序で使用します。

EXEC SQL
PREPARE STATEMENTNAME FROM { :HOST-STRING | STRING-LITERAL }
END-EXEC.
EXEC SQL DECLARE CURSORNAME CURSOR FOR STATEMENTNAME END-EXEC.
EXEC SQL OPEN CURSORNAME [USING HOST-VARIABLE-LIST] END-EXEC.
EXEC SQL FETCH CURSORNAME INTO HOST-VARIABLE-LIST END-EXEC.
EXEC SQL CLOSE CURSORNAME END-EXEC.

次に、それぞれの文の実行内容を説明します。

PREPARE

PREPARE文は動的SQL文を解析し、名前を指定します。次の例では、PREPAREにより文字列SELECT-STMTに格納された問合せを解析し、その問合せにSQLSTMTの名前を付けます。

MOVE 'SELECT MGR, JOB FROM EMP WHERE SAL < :SALARY'
TO SELECT-STMT.
EXEC SQL PREPARE SQLSTMT FROM :SELECT-STMT END-EXEC.

一般的には、この問合せのWHERE句は実行時に端末から入力するか、またはアプリケーションによって生成されます。

識別子SQLSTMTはホスト変数でもプログラム変数でもありませんが、一意であることが必要です。sql_stmtは特定の動的SQL文を指定します。

次の文も有効です。

EXEC SQL
PREPARE SQLSTMT FROM 'SELECT MGR, JOB FROM EMP WHERE SAL < :SALARY'
END-EXEC.

%のワイルド・カードを使用した次のPREPARE文も有効です。

MOVE "SELECT ENAME FROM TEST WHERE ENAME LIKE 'SMIT%'" TO MY-STMT.
EXEC SQL
PREPARE S FROM MY-STMT
END-EXEC.

DECLARE

DECLARE文は、カーソルに名前を指定し、これを特定の問合せに対応付けてカーソルを定義します。カーソルの宣言は、そのプリコンパイル・ユニット内でのみ有効です。前述の例では、次に示すように、DECLAREによりEMPCURSORの名前のカーソルを定義し、それをSQLSTMTに対応付けます。

EXEC SQL DECLARE EMPCURSOR CURSOR FOR SQLSTMT END-EXEC.

識別子SQLSTMTおよびEMPCURSORはホスト変数でもプログラム変数でもありませんが、一意であることが必要です。同じ文名を使用して2つのカーソルを宣言すると、Pro*COBOLはその2つのカーソル名を同義とみなします。たとえば次の文を実行したとします。

EXEC SQL PREPARE SQLSTMT FROM :SELECT-STMT END-EXEC.
EXEC SQL DECLARE EMPCURSOR FOR SQLSTMT END-EXEC.
EXEC SQL PREPARE SQLSTMT FROM :DELETE-STMT END-EXEC.
EXEC SQL DECLARE DEPCURSOR FOR SQLSTMT END-EXEC.

この場合、EMPCURSORをOPENしたときに処理対象となるのはDELETE-STMTに格納されている動的SQL文であって、SELECT-STMTに格納されている動的SQL文ではありません。

OPEN

OPEN文により、カーソルの割当て、入力ホスト変数のバインド、問合せの実行およびアクティブ・セットの識別を行います。さらにOPENにより、アクティブ・セットの最初の行にカーソルを位置付け、SQLCA内のSQLERRDの3番目の要素に保存される処理済行数を0 (ゼロ)に設定します。PREPAREされた動的SQL文中のプレースホルダは、USING句の対応する入力ホスト変数に置き換えられます。

前述の例では、次に示すようにOPENによってEMPCURSORを割り当て、ホスト変数SALARYをWHERE句に割り当てます。

EXEC SQL OPEN EMPCURSOR USING :SALARY END-EXEC.

FETCH

FETCH文は、アクティブ・セットから行を戻し、選択リスト内の列値をINTO句の対応するホスト変数に割り当てた後、カーソルを次の行に進めます。行がなくなると、FETCHは「データが見つかりません」というエラー・コードをSQLCA内のSQLCODEに戻します。

前述の例では、次に示すようにFETCHによってアクティブ・セットから1行を戻し、列MGRおよびJOBの値をホスト変数MGR-NUMBERおよびJOB-TITLEに代入します。

EXEC SQL FETCH EMPCURSOR INTO :MGR-NUMBER,:JOB-TITLE END-EXEC.

ホスト表は方法3で使用できます。

CLOSE

CLOSE文はカーソルを使用禁止にします。一度カーソルをCLOSEすると、それ以降はFETCHできなくなります。前述の例では、次に示すように、CLOSE文によってEMPCURSORが無効になります。

EXEC SQL CLOSE EMPCURSOR END-EXEC.

サンプル・プログラム8: 動的SQL方法3

このプログラムは、動的SQL方法3を使用して、指定された部門の全従業員の名前をEMP表から取り出します。

*****************************************************************
* Sample Program 8:  Dynamic SQL Method 3                       *
*                                                               *
* This program uses dynamic SQL Method 3 to retrieve the names  *
* of all employees in a given department from the EMP table.    *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID.  DYNSQL3.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

*    INCLUDE THE SQL COMMUNICATIONS AREA, A STRUCTURE THROUGH
*    WHICH ORACLE MAKES RUNTIME STATUS INFORMATION (SUCH AS ERROR
*    CODES, WARNING FLAGS, AND DIAGNOSTIC TEXT) AVAILABLE TO THE
*    PROGRAM.
EXEC SQL INCLUDE SQLCA END-EXEC.

*    INCLUDE THE ORACLE COMMUNICATIONS AREA, A STRUCTURE THROUGH
*    WHICH ORACLE MAKES ADDITIONAL RUNTIME STATUS INFORMATION
*    AVAILABLE TO THE PROGRAM.
EXEC SQL INCLUDE ORACA END-EXEC.

*    THE ORACA=YES OPTION MUST BE SPECIFIED TO ENABLE USE OF
*    THE ORACA.
EXEC ORACLE OPTION (ORACA=YES) END-EXEC.

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME  PIC X(10) VALUE "SCOTT".
01  PASSWD    PIC X(10) VALUE "TIGER".
01  DYNSTMT   PIC X(80) VARYING.
01  ENAME     PIC X(10).
01  DEPTNO    PIC S9999 COMPUTATIONAL VALUE 10.
EXEC SQL END DECLARE SECTION END-EXEC.

*    DECLARE VARIABLES NEEDED TO DISPLAY COMPUTATIONALS.
01  DEPTNOD   PIC 9(2).
01  ENAMED    PIC X(10).
01  SQLERRD3  PIC 9(2).
01  ORASLNRD  PIC 9(4).

PROCEDURE DIVISION.
MAIN.

*    BRANCH TO PARAGRAPH SQLERROR IF AN ORACLE ERROR OCCURS.
EXEC SQL WHENEVER SQLERROR GO TO SQLERROR END-EXEC.

*    SAVE TEXT OF CURRENT SQL STATEMENT IN THE ORACA IF AN ERROR
*    OCCURS.
MOVE 1 TO ORASTXTF.

*    CONNECT TO ORACLE.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "CONNECTED TO ORACLE.".
DISPLAY " ".

*    ASSIGN A SQL QUERY TO THE VARYING STRING DYNSTMT.  BOTH THE
*    ARRAY AND THE LENGTH PARTS MUST BE SET PROPERLY.  NOTE THAT
*    THE STATEMENT CONTAINS ONE HOST VARIABLE PLACEHOLDER, V1,
*    FOR WHICH AN ACTUAL INPUT HOST VARIABLE MUST BE SUPPLIED
*    AT OPEN TIME.
MOVE "SELECT ENAME FROM EMP WHERE DEPTNO = :V1"
TO DYNSTMT-ARR.
MOVE 40 TO DYNSTMT-LEN.

*    DISPLAY THE SQL STATEMENT AND ITS CURRENT INPUT HOST
*    VARIABLE.
DISPLAY DYNSTMT-ARR.
MOVE DEPTNO TO DEPTNOD.
DISPLAY "    V1 = ", DEPTNOD.
DISPLAY " ".
DISPLAY "EMPLOYEE".
DISPLAY "--------".

*    THE PREPARE STATEMENT ASSOCIATES A STATEMENT NAME WITH A
*    STRING CONTAINING A SELECT STATEMENT.  THE STATEMENT NAME,
*    WHICH MUST BE UNIQUE, IS A SQL IDENTIFIER, NOT A HOST
*    VARIABLE, AND SO DOES NOT APPEAR IN THE DECLARE SECTION.
EXEC SQL PREPARE S FROM :DYNSTMT END-EXEC.

*    THE DECLARE STATEMENT ASSOCIATES A CURSOR WITH A PREPARED
*    STATEMENT.  THE CURSOR NAME, LIKE THE STATEMENT NAME, DOES
*    NOT APPEAR IN THE DECLARE SECTION.
EXEC SQL DECLARE C CURSOR FOR S END-EXEC.

*    THE OPEN STATEMENT EVALUATES THE ACTIVE SET OF THE PREPARED
*    QUERY USING THE SPECIFIED INPUT HOST VARIABLES, WHICH ARE
*    SUBSTITUTED POSITIONALLY FOR PLACEHOLDERS IN THE PREPARED
*    QUERY.  FOR EACH OCCURRENCE OF A PLACEHOLDER IN THE
*    STATEMENT THERE MUST BE A VARIABLE IN THE USING CLAUSE.
*    THAT IS, IF A PLACEHOLDER OCCURS MULTIPLE TIMES IN THE
*    STATEMENT, THE CORRESPONDING VARIABLE MUST APPEAR MULTIPLE
*    TIMES IN THE USING CLAUSE.  THE USING CLAUSE MAY BE
*    OMITTED ONLY IF THE STATEMENT CONTAINS NO PLACEHOLDERS.
*    OPEN PLACES THE CURSOR AT THE FIRST ROW OF THE ACTIVE SET
*    IN PREPARATION FOR A FETCH.

*    A SINGLE DECLARED CURSOR MAY BE OPENED MORE THAN ONCE,
*    OPTIONALLY USING DIFFERENT INPUT HOST VARIABLES.
EXEC SQL OPEN C USING :DEPTNO END-EXEC.

*    BRANCH TO PARAGRAPH NOTFOUND WHEN ALL ROWS HAVE BEEN
*    RETRIEVED.
EXEC SQL WHENEVER NOT FOUND GO TO NOTFOUND END-EXEC.

GETROWS.

*    THE FETCH STATEMENT PLACES THE SELECT LIST OF THE CURRENT
*    ROW INTO THE VARIABLES SPECIFIED BY THE INTO CLAUSE, THEN
*    ADVANCES THE CURSOR TO THE NEXT ROW.  IF THERE ARE MORE
*    SELECT-LIST FIELDS THAN OUTPUT HOST VARIABLES, THE EXTRA
*    FIELDS ARE NOT RETURNED.  SPECIFYING MORE OUTPUT HOST
*    VARIABLES THAN SELECT-LIST FIELDS RESULTS IN AN ORACLE ERROR.
EXEC SQL FETCH C INTO :ENAME END-EXEC.
MOVE ENAME TO ENAMED.
DISPLAY ENAMED.

*    LOOP UNTIL NOT FOUND CONDITION IS DETECTED.
GO TO GETROWS.

NOTFOUND.
MOVE SQLERRD(3) TO SQLERRD3.
DISPLAY " ".
DISPLAY "QUERY RETURNED ", SQLERRD3, " ROW(S).".

*    THE CLOSE STATEMENT RELEASES RESOURCES ASSOCIATED WITH THE
*    CURSOR.
EXEC SQL CLOSE C END-EXEC.

*    COMMIT ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
EXEC SQL COMMIT RELEASE END-EXEC.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY!".
DISPLAY " ".
STOP RUN.

SQLERROR.

*    ORACLE ERROR HANDLER.  PRINT DIAGNOSTIC TEXT CONTAINING
*    ERROR MESSAGE, CURRENT SQL STATEMENT, AND LOCATION OF ERROR.
DISPLAY SQLERRMC.
DISPLAY "IN ", ORASTXTC.
MOVE ORASLNR TO ORASLNRD.
DISPLAY "ON LINE ", ORASLNRD, " OF ", ORASFNMC.

*    DISABLE ORACLE ERROR CHECKING TO AVOID AN INFINITE LOOP
*    SHOULD ANOTHER ERROR OCCUR WITHIN THIS PARAGRAPH.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.

*    RELEASE RESOURCES ASSOCIATED WITH THE CURSOR.
EXEC SQL CLOSE C END-EXEC.

*    ROLL BACK ANY PENDING CHANGES AND DISCONNECT FROM ORACLE.
EXEC SQL ROLLBACK RELEASE END-EXEC.
STOP RUN.

方法4の使用方法

この項では、概要のみ説明します。詳細は、第11章「Oracle動的SQL: 方法4」を参照してください。

方法4では、LOBはサポートされません。LOBアプリケーションおよび他の新規アプリケーションにはすべてANSI動的SQLを使用してください。

方法3を使用したプログラムでも処理できない種類の動的SQL文があります。選択リスト項目の数や、入力ホスト変数のプレースホルダの数が実行時まで不明な場合、プログラムでは記述子を使用する必要があります。記述子とは、動的SQL文で変数の完全な記述を保持するためにプログラムおよびOracleが使用するメモリー領域です。

複数行を戻す問合せでは、選択された列値は宣言されている出力ホスト変数のリストに繰り返しFETCH INTOされます。この選択リストがわからないときは、プリコンパイル時にINTO句でホスト変数リストを作成できません。たとえば、次の問合せでは2つの列値が戻されます。

EXEC SQL
SELECT ENAME, EMPNO FROM EMP WHERE DEPTNO = :DEPT-NUMBER
END-EXEC.

ただし、この選択リストをユーザーに定義させると、その問合せによって戻される列の数はわからなくなります。

SQLDAの必要性

このような種類の動的問合せを処理するには、プログラムでDESCRIBE SELECT LISTコマンドを発行するとともに、SQL記述子領域(SQLDA)というデータ構造体を宣言する必要があります。この構造体は、問合せ選択リストの列の記述を保持しているため、選択記述子とも呼ばれます。

同様に、動的SQL文に記述されている入力ホスト変数のプレースホルダの数が不明な場合には、プリコンパイル時にUSING句によるホスト変数リストの設定はできません。

このような動的SQL文を処理するには、プログラムはDESCRIBE BIND VARIABLESコマンドを発行し、入力ホスト変数に対するプレースホルダの記述を格納するためにバインド記述子という別の種類のSQLDAを宣言する必要があります。(入力ホスト変数はバインド変数とも呼ばれます。)

プログラム内にアクティブなSQL文が複数ある(たとえば、プログラムが複数のカーソルにOPENを使用している)ときは、それぞれの文に専用のSQLDA文が必要になります。ただし、非並行のカーソルではSQLDAを再利用できます。なお、1つのプログラム内のSQLDAの数に制限はありません。

DESCRIBE文

DESCRIBEは、選択リスト項目または入力ホスト変数の記述を保持するために記述子を初期化します。

選択記述子を指定すると、準備した動的問合せのそれぞれの選択リスト項目がDESCRIBE SELECT LIST文によってチェックされます。これによって、選択リスト項目の名前、データ型、制約、長さ、位取りおよび精度が決定されます。その後、この情報は選択記述子に格納されます。

バインド記述子を指定すると、DESCRIBE BIND VARIABLES文によって準備した動的SQL文内の各プレースホルダを調べ、その名前および長さ、対応する入力ホスト変数のデータ型を確認します。続いて、この情報がそのバインド記述子に格納されます。たとえば、プレースホルダ名を使用して、入力ホスト変数値の入力をユーザーに要求できます。

SQLDAの内容

SQLDAはホスト・プログラムのデータ構造体です。この構造体は選択リスト項目または入力ホスト変数の記述を保持します。

SQLDAはホスト言語によって異なりますが、一般的な選択SQLDAには、問合せ選択リストに関する次の情報が格納されます。

- DESCRIBEできる列の最大数

- DESCRIBEによって検出された列の実際の数

- 列値を格納するバッファのアドレス

- 列値の長さ

- 列値のデータ型

- 標識変数の値のアドレス

- 列名を格納するバッファのアドレス

- 列名を格納するバッファのサイズ

- 列名の現行の長さ

一般的なバインドSQLDAには、SQL文内の入力ホスト変数に関する次の情報が格納されています。

- DESCRIBEできるプレースホルダの最大数

- DESCRIBEによって検出されたプレースホルダの実際の数

- 入力ホスト変数のアドレス

- 入力ホスト変数の長さ

- 入力ホスト変数のデータ型

- 標識変数のアドレス

- プレースホルダ名を格納するバッファのアドレス

- プレースホルダ名を格納するバッファのサイズ

- プレースホルダ名の現行の長さ

- 標識変数名を格納するバッファのアドレス

- 標識変数名を格納するバッファのサイズ

- 標識変数名の現行の長さ

方法4の実行

方法4では、一般に次の順序で埋込みSQL文を使用します。

EXEC SQL
PREPARE STATEMENT-NAME
FROM { :HOST-STRING | STRING-LITERAL }
END-EXE
EXEC SQL
DECLARE CURSOR-NAME CURSOR FOR STATEMENT-NAME
END-EXEC.
EXEC SQL
DESCRIBE BIND VARIABLES FOR STATEMENT-NAME
INTO BIND-DESCRIPTOR-NAME
END-EXEC.
EXEC SQL
OPEN CURSOR-NAME
[USING DESCRIPTOR BIND-DESCRIPTOR-NAME]
END-EXEC.
EXEC SQL
DESCRIBE [SELECT LIST FOR] STATEMENT-NAME
INTO SELECT-DESCRIPTOR-NAME
END-EXEC.
EXEC SQL
FETCH CURSOR-NAME
USING DESCRIPTOR SELECT-DESCRIPTOR-NAME
END-EXEC.
EXEC SQL CLOSE CURSOR-NAME END-EXEC.

選択記述子およびバインド記述子の両方を使用する必要はありません。問合せ選択リストの列の数がわかっていて、入力ホスト変数のプレースホルダの数がわからない場合は、方法4のOPEN文と次に示す方法3のFETCH文を併用できます。

EXEC SQL FETCH EMPCURSOR INTO :HOST-VARIABLE-LIST END-EXEC.

逆に、入力ホスト変数のプレースホルダの数がわかっていて、選択リストの列の数がわからない場合は、次に示す方法3のOPEN文と方法4のFETCH文を併用できます。

EXEC SQL OPEN CURSORNAME [USING HOST-VARIABLE-LIST] END-EXEC.

方法4では、問合せ以外のSQL文に対してEXECUTEを使用できるので注意してください。

DECLARE STATEMENT文の使用方法

方法2、3および4では、次の文を使用することが必要な場合があります。

EXEC SQL [AT dbname] DECLARE statementname STATEMENT END-EXEC.

dbnameおよびstatementnameはPro*COBOLが使用する識別子で、ホスト変数でもプログラム変数でもありません。

DECLARE STATEMENTによって動的SQL文の名前が宣言されます。すると、この動的SQL文はPREPARE、EXECUTE、DECLARE CURSORおよびDESCRIBEで参照できます。デフォルト以外のデータベースで動的SQL文を実行するときに、この文が必要になります。方法2での使用例を次に示します。

EXEC SQL AT remotedb DECLARE sqlstmt STATEMENT END-EXEC.
EXEC SQL PREPARE sqltmt FROM :sqlstring END-EXEC.
EXEC SQL EXECUTE sqlstmt END-EXEC.

この例では、remotedbによって、SQL文をどこでEXECUTEするかをOracleに指示します。

方法3および方法4では、次の例に示すようにDECLARE CURSOR文がPREPARE文の前にある場合にもDECLARE STATEMENTが必要です。

EXEC SQL DECLARE sqlstmt STATEMENT END-EXEC.
EXEC SQL DECLARE empcursor CURSOR FOR sqlstmt END-EXEC.
EXEC SQL PREPARE sqlstmt FROM :sqlstring END-EXEC.

一般的な文の順序は次のとおりです。

EXEC SQL PREPARE sqlstmt FROM :sqlstring END-EXEC.
EXEC SQL DECLARE empcursor CURSOR FOR sqlstmt END-EXEC.

ホスト表の使用方法

ホスト表の使用方法は、静的SQLでも動的SQLでも同じです。たとえば、動的SQL方法2で入力ホスト表を使用する場合は、次の構文を使用します。

EXEC SQL EXECUTE statementname USING :HOST-TABLE-LIST END-EXEC.

HOST-TABLE-LISTは1つ以上のホスト表で構成されています。方法3の場合は、次の構文を使用します。

OPEN cursorname USING :HOST-TABLE-LIST END-EXEC.

方法3で出力ホスト表を使用する場合は、次の構文を使用します。

FETCH cursorname INTO :HOST-TABLE-LIST END-EXEC.

方法4では、オプションのFOR句を使用して、入力ホスト表または出力ホスト表のサイズをOracleに認識させる必要があります。この方法は、ホスト言語の補足を参照してください。

PL/SQLの使用方法

Pro*COBOLは、PL/SQLブロックを単一のSQL文として扱います。したがってSQL文と同様に、PL/SQLブロックを文字列のホスト変数またはリテラルに格納できます。PL/SQLブロックを文字列に格納するときは、キーワードEXEC SQL EXECUTE、キーワードEND-EXECおよび文の終了記号は省略してください。

ただし、Pro*COBOLによるSQLおよびPL/SQLの処理方法には、次の2つの相違点があります。

- PL/SQLホスト変数は、入力ホスト変数または出力ホスト変数のいずれ(あるいはその両方)であっても、すべて入力ホスト変数の場合と同様に扱う必要があります。

- PL/SQLブロックに格納できるSQL文の数には制限がないため、PL/SQLブロックからはFETCHできません。ただし、カーソル変数を使用して同様の機能を実装できます。

方法1の場合

PL/SQLブロックにホスト変数が含まれていなければ、方法1で通常どおりPL/SQL文字列をEXECUTEできます。

方法2の場合

PL/SQLブロック内の入力ホスト変数および出力ホスト変数の数がわかっていれば、方法2で通常どおりPL/SQL文字列をPREPAREおよびEXECUTEできます。

USING句にはすべてのホスト変数を指定する必要があります。このPL/SQL文字列のEXECUTEが完了すると、USING句内のホスト変数はPREPARE後の文字列内の対応するプレースホルダに置き換わります。Pro*COBOLでPL/SQLホスト変数がすべて入力ホスト変数として扱われても、値は正しく割り当てられます。入力(プログラム)値は入力ホスト変数に割り当てられ、出力(列)値は出力ホスト変数に割り当てられます。

PREPAREの後のPL/SQL文字列内のプレースホルダはすべて、USING句内のホスト変数に対応している必要があります。このため、PREPAREされた文字列で同じプレースホルダが複数回使用されている場合は、それぞれがUSING句内のホスト変数に対応している必要があります。

方法3の場合

方法3は、FETCHの完了が可能であることを除けば方法2と同じです。PL/SQLブロックからFETCHを行うことはできないので、方法2を使用してください。

方法4の場合

PL/SQLブロックに数の不明な入力ホスト変数または出力ホスト変数が含まれている場合は、方法4を必ず使用します。

方法4を使用するには、すべての入力ホスト変数および出力ホスト変数について1つのバインド記述子を設定します。DESCRIBE BIND VARIABLESを実行すると、入力ホスト変数および出力ホスト変数に関する情報がそのバインド記述子に保存されます。PL/SQLホスト変数はすべて入力ホスト変数に対応付けられた方法で参照するため、DESCRIBE SELECT LISTを実行しても効果はありません。

方法4でのバインド記述子の詳細は、ホスト言語補足を参照してください。

動的SQL方法4では、タイプが「table」のパラメータを指定してホスト配列をPL/SQLプロシージャにバインドできません。

注意

動的に処理されるPL/SQLブロックでは、行終了文字が無視されるので、ANSI形式のコメント(- -...)は使用しないでください。ANSIで記述すると、行の終わりではなくブロックの終わりまでコメントは続きます。ANSI形式のコメントではなく、C言語形式のコメント(/*... */)を使用してください。

動的SQL文のキャッシング

文キャッシュは、セッションごとの文のキャッシュを提供および管理する機能です。文キャッシュによって、サーバーではカーソルが使用できる状態になり、文を再解析する必要はありません。文のキャッシングは、プリコンパイラ・アプリケーションで有効にでき、動的SQL文に依存するすべてのアプリケーションのパフォーマンス向上に役立ちます。パフォーマンスの向上は、動的文を再利用する際の解析のオーバーヘッドをなくすことで達成されます。プリコンパイラ・アプリケーションのユーザーは、新しいコマンドライン・オプションstmt_cache(文のキャッシュ・サイズ用)を使用することで、パフォーマンスの向上を実現できます。このオプションにより、動的文の文のキャッシュが有効になります。この新しいオプションを有効にすると、セッション作成時に文のキャッシュが作成されます。キャッシングは動的文に対してのみ適用され、静的文用のカーソル・キャッシュとこの新しい機能は共存します。

コマンドライン・オプションstmt_cacheには、0から65535の範囲で任意の値を指定できます。デフォルト(値0)で、文キャッシングは無効化されています。stmt_cacheオプションでは、アプリケーションにそれぞれの動的SQL文の予測数を保持するように設定できます。

例9-1 stmt_cacheオプションの使用

次の例は、stmt_cacheオプションの使用方法を示しています。このプログラムでは、表に行を挿入し、挿入した行をループ内のカーソルを使用して選択します。このプログラムのプリコンパイルにstmt_cacheオプションを使用すると、通常のプリコンパイルよりもパフォーマンスが向上します。

*****************************************************************
* stmtcache:                                                    *
*                                                               *
* NOTE:                                                         *
* When this program is used to measure the performance with and *
* without stmt_cache option, do the following changes in the    *
* program,                                                      *
* 1. Increase ROWSCNT to high value, say 10000.                 *
* 2. Remove all the DISPLAY statements, usually which comsumes  *
* significant portion of the total program execution time.      *
*****************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID.  stmtcache.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.

* EMBEDDED COBOL (file "STMTCACHE.PCO")

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME          PIC X(10) VARYING.
01  PASSWD            PIC X(10) VARYING.
01  DYNSTMT   PIC X(100) VARYING.
01  DYNSTMT2   PIC X(100) VARYING.

01  ENAME PIC X(10).
01  COMM PIC X(9).

EXEC SQL END DECLARE SECTION END-EXEC.

01  ROWSCNT  PIC 9(4) COMP VALUE 10.
01  LOOPNO PIC  9(4).

01  STRINGFIELDS.
02 STR PIC X(18) VARYING.

EXEC SQL INCLUDE SQLCA END-EXEC.

PROCEDURE DIVISION.
BEGIN-PGM.
EXEC SQL WHENEVER SQLERROR DO PERFORM SQL-ERROR END-EXEC.

PERFORM LOGON.

MOVE "INSERT INTO BONUS (ENAME, COMM) VALUES (:A,:B)"
TO DYNSTMT-ARR.
MOVE 53 TO DYNSTMT-LEN.

DISPLAY "Inserts ", ROWSCNT, " rows into BONUS table.".
PERFORM INSDATA VARYING LOOPNO FROM 1 BY 1
UNTIL LOOPNO > ROWSCNT.

DISPLAY " ".

DISPLAY "Fetches the inserted rows from BONUS.".
DISPLAY "  ENAME COMM".

MOVE "SELECT ENAME, COMM FROM BONUS WHERE COMM=:A"
TO DYNSTMT2-ARR.
MOVE 43 TO DYNSTMT2-LEN.

MOVE 1 TO LOOPNO.

* Loops for preparing and fetching ROWSCNT number of times
FETCHDATA.
* Do the prepare in the loop so that the advantage of
* stmt_caching is visible
EXEC SQL PREPARE S2 FROM :DYNSTMT2 END-EXEC.

EXEC SQL DECLARE C1 CURSOR FOR S2
END-EXEC.

EXEC SQL OPEN C1 USING :LOOPNO END-EXEC.

EXEC SQL WHENEVER NOT FOUND GO TO NOTFOUND END-EXEC.

GETROWS.
* Close the cursor so that the reparsing is not required for
* stmt_cache
EXEC SQL FETCH C1 INTO :ENAME, :COMM
END-EXEC.
DISPLAY ENAME, COMM.
GO TO GETROWS.

NOTFOUND.
EXEC SQL CLOSE C1 END-EXEC.
COMPUTE LOOPNO = LOOPNO + 1.

IF LOOPNO <= ROWSCNT THEN
GO TO FETCHDATA
END-IF.

EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

LOGON.
MOVE "scott" TO USERNAME-ARR.
MOVE 5 TO USERNAME-LEN.
MOVE "tiger" TO PASSWD-ARR.
MOVE 5 TO PASSWD-LEN.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.

* Populates the host variable and insert into the table
INSDATA.
EXEC SQL PREPARE S1 FROM :DYNSTMT END-EXEC.
MOVE " " TO STR.
STRING "EMP_", LOOPNO INTO STR
END-STRING.
MOVE STR TO ENAME.
MOVE LOOPNO TO COMM.

EXEC SQL EXECUTE S1 USING :ENAME, :COMM END-EXEC.

* HANDLES SQL ERROR CONDITIONS
SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

第II部

アプリケーション

第II部は、次の章で構成されています。

- ANSI動的SQL

- Oracle動的SQL: 方法4

- マルチスレッド・アプリケーション

- ラージ・オブジェクト(LOB)

- プリコンパイラのオプション

- オペレーティング・システムの依存性

- 予約語、キーワードおよびネームスペース

- パフォーマンス・チューニング

- 構文および意味検査

- 埋込みSQL文およびプリコンパイラ・ディレクティブ

- Pro*COBOL for Windows

10 ANSI動的SQL

この章では、新しい方法4アプリケーションに使用するANSI動的SQL (SQL標準の指定どおりの動的SQL)のOracleでの実装を説明します。実装は、第11章「Oracle動的SQL: 方法4」で説明する従来のOracle動的SQL方法4に拡張機能を加えたものです。Oracle方法4ではカーソル変数、グループ項目の表、DML RETURNING句およびLOBはサポートされませんが、ANSI方法4ではOracleの型がすべてサポートされます。

従来のOracle動的SQL方法4では記述子はユーザーのPro*COBOLプログラムで定義されますが、ANSI動的SQLでは記述子はOracle内部で管理されます。どちらの場合でも、方法4では、Pro*COBOLプログラムが様々な数のホスト変数を含むSQL文の受け入れまたは作成を行います。

この章の内容は、次のとおりです。

- ANSI動的SQLの基礎

- ANSI SQL文の概要

- Oracle拡張機能

- ANSI動的SQLのプリコンパイラ・オプション

- 動的SQL文の構文

- サンプル・プログラム: SAMPLE12.PCO

ANSI動的SQLの基礎

次のSQL文について考えます。

SELECT ename, empno FROM emp WHERE deptno = :deptno_data

ANSI動的SQLを使用する手順は、次のとおりです。

- 実行する文を格納する文字列などの変数を宣言します。

- 入力変数および出力変数に記述子を割り当てます。

- 文を準備します。

- 入力記述子の入力を記述します。

- 入力記述子を設定します(この例では1つの入力ホスト・バインド変数deptno_data)。

- 動的カーソルを宣言およびオープンします。

- 出力記述子を設定します(この例では出力ホスト変数enameとempno)。

- enameおよびempnoデータ・フィールドを各行から取り出すために、GET DESCRIPTORを使用してデータを繰り返しフェッチします。

- 取り出したデータを処理します(出力など)。

- 動的カーソルを閉じ、入力記述子および出力記述子への割当てを解除します。

プリコンパイラのオプション

通常、ANSI動的SQLを使用する場合はプリコンパイラのANSI規格に従ってコードを記述するため、マクロ・コマンドライン・オプションMODE=ANSIを使用します。MODE=ANSIを使用せずにこの方法を使用する場合は、マイクロ・コマンドライン・オプションDYNAMIC=ANSIによって機能を制御します。

マイクロ・プリコンパイラ・オプションDYNAMICをANSIに設定するか、マクロ・オプションMODEをANSIに設定します。これによって、DYNAMICのデフォルト値がANSIに設定されます。DYNAMICのもう1つの設定はORACLEです。マイクロ・オプションの詳細は、「マクロ・オプションおよびマイクロ・オプション」および「DYNAMIC」を参照してください。

ANSI型コードを使用するには、TYPE_CODEプリコンパイラ・マイクロ・オプションをANSIに設定するか、MODEマクロ・オプションをANSIに設定します。これによって、TYPE_CODEのデフォルト設定がANSIになります。TYPE_CODEをANSIに設定するには、DYNAMICもANSIに設定する必要があります。

ANSI SQL型のリストは、表10-1を参照してください。データベース・プラットフォーム間での移植性があり、可能なかぎりANSIに準拠したアプリケーションを作成する場合は、プリコンパイラ・オプションTYPE_CODEをANSIに設定してANSI型を使用してください。

詳細は、「MODE」および「TYPE_CODE」を参照してください。

ANSI SQL文の概要

動的SQL文では、記述子領域は使用する前に割り当てます。

ALLOCATE DESCRIPTOR文の構文は次のとおりです。

EXEC SQL ALLOCATE DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
[WITH MAX {:occurrences | numeric_literal}]
END-EXEC.

グローバル記述子は、プログラム内の任意のモジュールで使用できます。ローカル記述子は、その記述子を割り当てたファイル内でのみアクセス可能です。デフォルトはローカルです。

記述子名desc_namは、ホスト変数です。かわりに文字列リテラルを使用することもできます。

occurrencesは、記述子に格納できるバインド変数または列の最大数です。デフォルトは100です。

記述子が必要なくなった場合は、割当てを解除してメモリーを節約します。

割当て解除文は次のとおりです。

EXEC SQL DEALLOCATE DESCRIPTOR [GLOBAL | LOCAL]
{:desc_nam | string_literal}
END-EXEC.

準備済のSQL文に関する情報を取得するには、DESCRIBE文を使用します。DESCRIBE INPUTでは、準備済の動的文のバインド変数が記述されます。DESCRIBE OUTPUT (デフォルト)では、出力列の番号、型および長さが記述されます。単純化した構文は次のとおりです。

EXEC SQL DESCRIBE [INPUT | OUTPUT] sql_statement
USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
END-EXEC.

SQL文に入力値および出力値がある場合は、入力値および出力値に1つずつ記述子を割り当てる必要があります。入力値がない次の例のような場合があります。

SELECT ename, empno FROM emp

この場合、入力記述子は必要ありません。

SELECT文のINSERTS、UPDATES、DELETESおよびWHERE句の入力値を指定するには、SET DESCRIPTOR文を使用します。入力記述子にDESCRIBEを行っていないときは、SET DESCRIPTORを使用して(COUNTに格納する)入力バインド変数の数を設定します。

EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
COUNT = {:kount | numeric_literal}
END-EXEC.

kountには、ホスト変数または数値リテラル(5など)を指定できます。SET DESCRIPTOR文を各ホスト変数に使用して、少なくとも変数のデータ値は割り当てる必要があります。

EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
VALUE item_number DATA = :hv3
END-EXEC.

また、次のように入力ホスト変数の型および長さを設定することもできます。

注意: 型および長さの設定をSET DESCRIPTOR文で明示的に、またはDESCRIBE OUTPUTを実行して暗黙的に行わなかった場合、TYPE_CODE=ORACLEの場合は、ホスト変数自体から導出された型および長さの値がプリコンパイラで使用されます。TYPE_CODE=ANSIの場合は、表10-1「ANSI SQLデータ型」に示す値を使用して型を設定する必要があります。また、ANSIのデフォルトの長さがホスト変数のデフォルトの長さと一致しない場合があるので、長さも設定してください。

EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
VALUE item_number TYPE = :hv1, LENGTH = :hv2, DATA = :hv3
END-EXEC.

hv1、hv2およびhv3などの識別子は、ホスト変数から値を供給する必要があることをユーザーが忘れないようにするために使用します。item_numberは、入力変数のSQL文内での位置を表します。ホスト変数であることも、整数であることもあります。

TYPE_CODEをANSIに設定した場合は、次の表の型コードからTYPEを選択します。

表10-1 ANSI SQLデータ型

データ型

型コード

CHARACTER

1

CHARACTER VARYING

12

DATE

9

DECIMAL

3

DOUBLE PRECISION

8

FLOAT

6

INTEGER

4

NUMERIC

2

REAL

7

SMALLINT

5

Oracle型コードは、表11-2「Oracleの外部データ型および関連するCOBOLデータ型」を参照してください。ANSIデータ型が表になく、TYPE_CODE = ANSIである場合は、Oracleコードの負の値を使用してください。

DATAは、入力されるホスト変数値です。

インジケータ、精度、位取りなど、その他の入力値を設定することもできます。詳細は、「SET DESCRIPTOR」の使用できる記述子項目名のリストを参照してください。

SET DESCRIPTOR文の数値は、PIC S9(9) COMPまたはPIC S9(4) COMPのいずれかで宣言する必要があります。ただし、インジケータおよび戻される長さの値は、PIC S9(4) COMPとして宣言する必要があります。

次の例では、empnoを取得する場合、empnoは動的SQL文の2番目の出力ホスト変数であるため、値をVALUE = 2に設定します。ホスト変数EMPNO-TYPは、3(Oracleタイプの整数値)に設定します。ホスト整数の長さを表すEMPNO-LENは、4に設定します。この値はホスト変数のサイズです。DATAはホスト変数EMPNO-DATAと等しくなります。この変数は値をデータベース表から受け取ります。コード例は、次のようになります。

...
01  DYN-STATEMENT PIC X(58)
VALUE "SELECT ename, empno FROM emp WHERE deptno =:deptno_number".
01  EMPNO-DATA PIC S9(9) COMP.
01  EMPNO-TYP  PIC S9(9) COMP   VALUE 3.
01  EMPNO-LEN  PIC S9(9) COMP   VALUE 4.
...
EXEC SQL SET DESCRIPTOR 'out' VALUE 2  TYPE=:EMPNO-TYP, LENGTH=:EMPNO-LEN,
DATA=:EMPNO-DATA END-EXEC.

入力値を設定後に、入力記述子を使用して文を実行またはオープンします。文中に出力値がある場合、FETCHを行う前に出力値を設定してください。DESCRIBE OUTPUTを実行した場合、ホスト変数の実際の型および長さをリセットしなければならないことがあります。DESCRIBEの実行により、ホスト変数の外部型および長さとは異なる内部型および長さが生成されるためです。

出力記述子をFETCHした後、戻されたデータにアクセスするには、GET DESCRIPTORを使用します。簡略化された構文は次のとおりです。構文の詳細は、この章の後半部分を参照してください。

EXEC SQL GET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}
VALUE item_number
:hv1 = DATA, :hv2 = INDICATOR, :hv3 = RETURNED_LENGTH
END-EXEC.

desc_namおよびitem_numberには、リテラルまたはホスト変数を指定できます。記述子名には、リテラル(outなど)を指定できます。項目番号には、数値リテラル(2など)を指定できます。

hv1、hv2およびhv3は、それぞれホスト変数です。ここにはホスト変数を指定する必要があり、リテラルは指定できません。例では、戻されるデータを3つのみ示しています。戻されるデータとして取得できる項目は、表10-4「記述子項目名の定義」を参照してください。

数値には、プラットフォーム依存の上限がnであるPIC S9(n) COMPを使用するか、またはPIC S9(9) COMPかPIC S9(4) COMPを使用します。ただし、標識変数および戻される長さの変数はPIC S9(4) COMPであることが必要です。

サンプル・コード

次の例は、ANSI動的SQLの使用方法を示しています。ここでは入力記述子inおよび出力記述子outを割り当ててSELECT文を実行します。入力値はSET DESCRIPTOR文を介して設定します。カーソルはオープンおよびフェッチされ、結果の出力値はGET DESCRIPTOR文を介して取得されます。

...
01  DYN-STATEMENT PIC X(58)
VALUE "SELECT ENAME, EMPNO FROM EMP WHERE DEPTNO =:DEPTNO-DAT".
01  EMPNO-DAT  PIC S9(9) COMP.
01  EMPNO-TYP  PIC S9(9) COMP   VALUE 3.
01  EMPNO-LEN  PIC S9(9) COMP   VALUE 4.
01  DEPTNO-TYP PIC S9(9) COMP   VALUE 3.
01  DEPTNO-LEN PIC S9(9) COMP   VALUE 4.
01  DEPTNO-DAT PIC S9(9) COMP   VALUE 10.
01  ENAME-TYP  PIC S9(9) COMP   VALUE 3.
01  ENAME-LEN  PIC S9(9) COMP   VALUE 30.
01  ENAME-DAT  PIC X(30).
01  SQLCODE PIC S9(9)    COMP   VALUE 0.
...
* Place preliminary code, including connection, here
...
EXEC SQL ALLOCATE DESCRIPTOR 'in' END-EXEC.
EXEC SQL ALLOCATE DESCRIPTOR 'out' END-EXEC.
EXEC SQL PREPARE s FROM :DYN-STATEMENT END-EXEC.
EXEC SQL DESCRIBE INPUT s USING DESCRIPTOR 'in' END-EXEC.
EXEC SQL SET DESCRIPTOR 'in' VALUE 1 TYPE=:DEPTNO-TYP,
LENGTH=:DEPTNO-LEN, DATA=:DEPTNO-DAT END-EXEC.
EXEC SQL DECLARE c CURSOR FOR s END-EXEC.
EXEC SQL OPEN c USING DESCRIPTOR 'in' END-EXEC.
EXEC SQL DESCRIBE OUTPUT s USING DESCRIPTOR 'out' END-EXEC.
EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE=:ENAME-TYP,
LENGTH=:ENAME-LEN, DATA=:ENAME-DAT END-EXEC.
EXEC SQL SET DESCRIPTOR 'out' VALUE 2 TYPE=:EMPNO-TYP,
LENGTH=:EMPNO-LEN, DATA=:EMPNO-DAT END-EXEC.

EXEC SQL WHENEVER NOT FOUND GOTO BREAK END-EXEC.
LOOP.
IF SQLCODE NOT = 0
GOTO BREAK.
EXEC SQL FETCH c INTO DESCRIPTOR 'out' END-EXEC.
EXEC SQL GET DESCRIPTOR 'OUT' VALUE 1 :ENAME-DAT = DATA END-EXEC.
EXEC SQL GET DESCRIPTOR 'OUT' VALUE 2 :EMPNO-DAT = DATA END-EXEC.
DISPLAY "ENAME = " WITH NO ADVANCING
DISPLAY ENAME-DAT  WITH NO ADVANCING
DISPLAY "EMPNO = " WITH NO ADVANCING
DISPLAY EMPNO-DAT.
GOTO LOOP.
BREAK:
EXEC SQL CLOSE c END-EXEC.
EXEC SQL DEALLOCATE DESCRIPTOR 'in' END-EXEC.
EXEC SQL DEALLOCATE DESCRIPTOR 'out' END-EXEC.

Oracle拡張機能

この項では、次の拡張機能を説明します。

- SET文のデータ項目の参照セマンティクス。

- バルク操作のための配列。

- オブジェクト型、NCHAR列およびLOBのサポート。

参照セマンティクス

ANSI規格では、値構文が指定されています。パフォーマンス向上のために、Oracleではこの規格を拡張して参照セマンティクスを導入しています。

値構文では、ホスト変数データのコピーを作成します。参照セマンティクスでは、ホスト変数のアドレスを使用し、コピーは行いません。そのため、参照セマンティクスを使用すると、大量データ処理のパフォーマンスが向上します。

フェッチの速度向上には、データ句の前にREFキーワードを使用します。

EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE=:ENAME-TYP,
LENGTH=:ENAME-LEN, REF DATA=:ENAME-DAT END-EXEC.
EXEC SQL DESCRIPTOR 'out' VALUE 2 TYPE=:EMPNO-TYP,
LENGTH=:EMPNO-LEN, REF DATA=:EMPNO-DAT END-EXEC.

これにより、取り出された結果がホスト変数に渡されます。GET文は必要ありません。FETCHが実行されるたびに、取り出されたデータは、ename_dataおよびempno_dataに直接書き込まれます。

次のコード例に示すように、REFキーワードが使用できるのは、DATA、INDICATORおよびRETURNED_LENGTH項目(フェッチする行によって変わる可能性があります)の前に限られます。

01   INDI       PIC S9(4) COMP.
01   RETRN-LEN  PIC S9(9) COMP.
...
EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE=:ENAME-TYP,
LENGTH=:ENAME-LEN, REF DATA=:ENAME-DAT,
REF INDICATOR=:INDI, REF RETURNED_LENGTH =:RETRN-LEN END-EXEC.

フェッチするたびに、enameフィールドの実際に取り出された長さがRETRN-LENに送られます。これは、CHARまたはVARCHAR2データの場合に便利です。

ENAME-LENには取り出された長さは渡されません。これは、FETCH文によって変更されません。データの行をフェッチする前に列の最大幅を調べるには、GET文の前にDESCRIBEを使用します。

REFキーワードは、SELECT以外のSQL文の処理速度向上のためにも使用します。参照セマンティクスでは、記述子領域にコピーされた値ではなくホスト変数が使用されることに注意してください。SQL文を実行する時点でのホスト変数データが使用されるのであって、SETの時点でのデータではありません。次に例を示します。

...
MOVE 1 to VAL.
...
EXEC SQL SET DESCRIPTOR 'value' VALUE 1 DATA = :VAL END-EXEC.
EXEC SQL SET DESCRIPTOR 'reference' VALUE 1 REF DATA = :VAL END-EXEC.
MOVE 2 to VAL.
* Will use  VAL = 1
EXEC SQL EXECUTE s USING  DESCRIPTOR 'value' END-EXEC.
*Will use VAL = 2
EXEC SQL EXECUTE s USING DESCRIPTOR 'reference' END-EXEC.

この処理の違いの詳細は、「SET DESCRIPTOR」を参照してください。

バルク操作での表の使用方法

OracleでのANSI動的SQLの実装では、SQL標準の動的SQLを拡張したバルク操作を提供しています。バルク操作を行うには、処理する入力データ量または行数を指定するために、FOR句で配列サイズを指定します。

FOR句は、ALLOCATE文で最大データ量または最大行数の指定に使用します。最大配列サイズ100を指定するには、次のように記述します。

EXEC SQL FOR 100 ALLOCATE DESCRIPTOR 'out' END-EXEC.

または

MOVE 100 TO INT-ARR-SIZE.
EXEC SQL FOR :INT-ARR-SIZE ALLOCATE DESCRIPTOR 'out' END-EXEC.

次に、記述子にアクセスする文でFOR句を使用します。次に示すように、出力記述子では、ALLOCATE文で指定した配列サイズと等しいか、それよりも小さい配列サイズをFETCH文に割り当てる必要があります。

EXEC SQL FOR 20 FETCH c1 USING DESCRIPTOR 'out' END-EXEC.

後続の、同じ記述子のDATA、INDICATORまたはRETURNED_LENGTH値を取得するGET文では、FETCH文と同じ配列サイズを指定する必要があります。

01  VAL-DATA   OCCURS 20 TIMES  PIC S9(9) COMP.
01  VAL-INDI   OCCURS 20 TIMES  PIC S9(4) COMP.
...
EXEC SQL FOR 20 GET DESCRIPTOR 'out' VALUE 1 :VAL-DATA = DATA,
:VAL-INDI = INDICATOR
END-EXEC.

ただし、LENGTH、TYPE、COUNTなど、行によって変化しない項目を参照するGET文では、FOR句は使用しないでください。

01  CNT  PIC S9(9) COMP.
01  LEN  PIC S9(9) COMP.
...
EXEC SQL GET DESCRIPTOR 'out'   :CNT = COUNT END-EXEC.
EXEC SQL GET DESCRIPTOR 'out' VALUE 1 :LEN = LENGTH END-EXEC.

これは、参照セマンティクスを使用したSET文でも同じです。FETCHの前にあり、DATA、INDICATORまたはRETURNED_LENGTHに対する参照セマンティクスを使用したSET文には、FETCHと同じ配列サイズを指定する必要があります。

...
01  REF-DATA   OCCURS 20 TIMES  PIC S9(9) COMP.
01  REF-INDI   OCCURS 20 TIMES  PIC S9(4) COMP.
...
EXEC SQL FOR 20 SET DESCRIPTOR 'out' VALUE 1 REF DATA = :REF-DATA,
REF INDICATOR = :REF-INDI END-EXEC.

同様に、行のバッチの挿入など、入力に使用する記述子でも、ALLOCATE文で使用した配列サイズと等しいか、それよりも小さいサイズの配列サイズをEXECUTEまたはOPEN文に使用する必要があります。値および参照セマンティクスのどちらも、DATA、INDICATORまたはRETURNED_LENGTHにアクセスするSET文では、EXECUTE文と同じ配列サイズを使用する必要があります。

FOR句は、DEALLOCATEまたはPREPARE文では使用しません。

次のコード・サンプルに、出力記述子のないバルク操作の例を示します(出力はなく、表empに挿入する入力のみあります)。CNTの値は2です(INSERT文にENAMEおよびEMPNOの2つのホスト変数があることを示します)。データ表ENAME-TABLEには、Tom、DickおよびHarryの順で3つの文字列が保持されています。彼らの雇用者番号を表EMPNO-TABLEに格納します。インジケータ表ENAME-INDには2つ目の要素に-1の値を設定しているため、DickではなくNULLが挿入されます。

01  DYN-STATEMENT  PIC X(240) value
"INSERT INTO EMP(ENAME, EMPNO) VALUES (:ENAME,:EMPNO)".
01  ARRAY-SIZE PIC S9(9) COMP   VALUE 3.
01  ENAME-VALUES.
05 FILLER PIC X(6)   VALUE "Tom   ".
05 FILLER PIC X(6)   VALUE "Dick  ".
05 FILLER PIC X(6)   VALUE "Harry ".
01  ENAME-TABLE REDEFINES ENAME-VALUES.
05 ENAME  PIC X(6)OCCURS 3 TIMES.
01  ENAME-IND  PIC S9(4) COMPOCCURS 3 TIMES.
01  ENAME-LEN  PIC S9(9) COMP   VALUE   6.
01  ENAME-TYP  PIC S9(9) COMP   VALUE  96.
01  EMPNO-VALUES.
05 FILLER PIC S9(9) COMP   VALUE 8001.
05 FILLER PIC S9(9) COMP   VALUE 8002.
05 FILLER PIC S9(9) COMP   VALUE 8003.
01  EMPNO-TABLE REDEFINES EMPNO-VALUES.
05 EMPNO  PIC S9(9) DISPLAY SIGN LEADING  OCCURS 3 TIMES.
01  EMPNO-LEN  PIC S9(9) COMP   VALUE   4.
01  EMPNO-TYP  PIC S9(9) COMP   VALUE   3.
01  CNT        PIC S9(9) COMP   VALUE   2.
........
EXEC SQL FOR :ARRAY-SIZE ALLOCATE DESCRIPTOR 'in' END-EXEC.
EXEC SQL PREPARE S FROM :DYN-STATEMENT  END-EXEC.
MOVE 0 TO ENAME-IND(1).
MOVE -1 TO ENAME-IND(2).
MOVE 0 TO ENAME-IND(3).
EXEC SQL SET DESCRIPTOR 'in' COUNT = :CNT END-EXEC.
EXEC SQL SET DESCRIPTOR 'in' VALUE 1
TYPE = :ENAME-TYP, LENGTH =:ENAME-LEN
END-EXEC.
EXEC SQL FOR :ARRAY-SIZE  SET DESCRIPTOR 'in' VALUE 1
DATA = :ENAME, INDICATOR = :ENAME-IND
END-EXEC.
EXEC SQL SET DESCRIPTOR 'in' VALUE 2
TYPE = :EMPNO-TYP, LENGTH =:EMPNO-LEN
END-EXEC.
EXEC SQL FOR :ARRAY-SIZE  SET DESCRIPTOR 'in' VALUE 2
DATA = :EMPNO
END-EXEC.
EXEC SQL FOR :ARRAY-SIZE EXECUTE S
USING DESCRIPTOR 'in' END-EXEC.
...

この例のコードによって、次の値が表に挿入されます。

EMPNO   ENAME
8001    Tom
8002
8003    Harry

制限および注意の詳細は、「FOR句」を参照してください。

ANSI動的SQLのプリコンパイラ・オプション

マクロ・オプションMODE (「MODE」を参照)では、ANSI互換特性を設定し、いくつかの機能を制御します。値にはANSIまたはORACLEを設定できます。個々の機能には、MODE設定に優先するマイクロ・オプションがあります。

プリコンパイラ・マイクロ・オプションDYNAMICでは、動的SQLの記述子の動作を指定します。プリコンパイラ・マイクロ・オプションTYPE_CODEでは、ANSIとOracleのどちらのデータ型コードを使用するかを指定します。

マクロ・オプションMODEをANSIに設定すると、マイクロ・オプションDYNAMICは自動的にANSIになります。MODEをORACLEに設定すると、DYNAMICはORACLEになります。

DYNAMICおよびTYPE_CODEはインラインでは使用できません。

次の表に、DYNAMIC設定による様々な機能への影響を示します。

表10-2 DYNAMICオプションの設定

機能

DYNAMIC=ANSI

DYNAMIC=ORACLE

記述子の作成。

ALLOCATE文を使用する必要があります。

Oracle形式の記述子を使用する必要があります。

記述子の破損。

DEALLOCATE文を使用できます。

使用不可。

データの取出し。

FETCH文およびGET文のどちらも使用できます。

FETCH文のみ使用できます。

入力データの設定。

DESCRIBE INPUT文を使用できます。SET文を使用する必要があります。

コードに記述子値を設定する必要があります。DESCRIBE BIND VARIABLES文を使用する必要があります。

記述子の表現。

引用符付きのリテラル、または記述子名を含むホスト識別子。

ホスト変数、SQLDAを指すポインタ。

利用可能なデータ型。

BITを除くすべてのANSI型、およびすべてのOracle型。

オブジェクト、LOBおよびカーソル変数を除くOracle型。

マイクロ・オプションTYPE_CODEは、プリコンパイラによってマクロ・オプションMODEと同じ値に設定されます。DYNAMICがANSIの場合、TYPE_CODEはANSI以外には設定できません。

TYPE_CODEの設定に対応する機能を次の表に示します。

表10-3 TYPE_CODEオプションの設定

機能

TYPE_CODE=ANSI

TYPE_CODE=ORACLE

動的SQLからの入出力に使用するデータ型コード番号。

ANSI型があるときはANSIコード番号を使用します。ない場合はOracleコード番号の負の値を使用します。

DYNAMIC=ANSIのときのみ有効です。

Oracleコード番号を使用します。

DYNAMICの設定に関係なく使用できます。

動的SQL文の構文

次の文の詳細は、付録E「埋込みSQL文およびプリコンパイラ・ディレクティブ」のアルファベット順のリストを参照してください。

ALLOCATE DESCRIPTOR

この文はANSI動的SQLでのみ使用できます。

用途

この文は、SQL記述子領域を割り当てるために使用します。記述子、記述子のホスト・バインド項目の出現の最大数および配列サイズを指定します。

構文

EXEC SQL [FOR [:]array_size] ALLOCATE DESCRIPTOR [GLOBAL | LOCAL]
{:desc_nam | string_literal} [WITH MAX occurrences]
END-EXEC.

変数

ALLOCATE記述子では様々な変数が使用できます。ALLOCATE記述子が使用できる変数にはarray_size、desc_nam、occurrencesなどがあります。

array_size

オプションのarray_size句(Oracle拡張機能)では表の処理をサポートしています。表の処理に記述子を使用できることをプリコンパイラに示します。

GLOBAL | LOCAL

デフォルトでは、オプション句のスコープはLOCALに設定されています。ローカル記述子は、その記述子を割り当てたファイル内でのみアクセス可能です。グローバル記述子は、コンパイル・ユニット内のどのモジュールでも使用できます。

desc_nam

desc_nam変数は、モジュールで一意である必要があるローカル記述子を定義します。前回の割当てを解除せずに記述子を割り当てた場合は、ランタイム・エラーが生成されます。グローバル記述子は、アプリケーション全体で一意にしてください。そうでない場合はランタイム・エラーが発生します。

occurrences

オプションのoccurrences句は、記述子で使用可能なホスト変数の最大数です。occurrences変数は0から64Kの整定数である必要があります。それ以外の場合はエラーが戻されます。デフォルトは100です。これらの規則に違反するとプリコンパイラ・エラーが戻されます。

例

EXEC SQL ALLOCATE DESCRIPTOR 'SELDES' WITH MAX 50 END-EXEC.

EXEC SQL FOR :BATCH ALLOCATE DESCRIPTOR GLOBAL :BINDDES WITH MAX 25
END-EXEC.

DEALLOCATE DESCRIPTOR

用途

メモリーを解放するには、割当て解除文を使用します。この文は、事前に割り当てたSQL記述子領域を解除します。

構文

EXEC SQL DEALLOCATE DESCRIPTOR [GLOBAL | LOCAL]
{:desc_nam | string_literal}
END-EXEC.

変数

desc_nam

割当て解除記述子が使用できる唯一の変数がdesc_nam (記述子名)です。同じ名前およびスコープの記述子が割り当てられていない場合、または割り当てられ、すでに解除されている場合は、ランタイム・エラーが発生します。

例

EXEC SQL DEALLOCATE DESCRIPTOR GLOBAL 'SELDES' END-EXEC.

EXEC SQL DEALLOCATE DESCRIPTOR :BINDDES END-EXEC.

GET DESCRIPTOR

用途

この文は、SQL記述子領域からの情報の取得に使用します。

構文

EXEC SQL [FOR [:]array_size] GET DESCRIPTOR [GLOBAL | LOCAL]
{:desc_nam | string_literal}
{:hv0  = COUNT | VALUE item_number :hv1 = item_name1
[{, :hvN = item_nameN }]}
END-EXEC.

変数

array_size

FOR array_size変数は、オプションのOracle拡張機能です。FOR array_sizeは、FETCH文のarray_sizeフィールドと等しいことが必要です。

desc_nam

記述子名。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

COUNT

バインド変数の合計数。

VALUE item_number

SQL文内での項目の位置。item_numberには変数または定数を指定できます。item_numberの値がCOUNTより大きい場合、「データが見つかりません。」という条件が戻されます。item_numberには0より大きい値を指定する必要があります。

hv1 .. hvN

値の転送先のホスト変数。

item_name1 .. item_nameN

ホスト変数に対応付けられた記述子項目名。使用できるANSI記述子項目名を次の表に示します。

表10-4 記述子項目名の定義

記述子項目名

意味

TYPE

ANSI型コードは表10-1を参照してください。Oracle型コードは表11-2を参照してください。ANSIデータ型が表になく、TYPE_CODE = ANSIである場合は、Oracleコードの負の値を使用してください。

LENGTH

列内のデータの長さ。NCHARは文字単位、それ以外はバイト単位です。DESCRIBE OUTPUTによって設定されます。

OCTET_LENGTH

バイト単位でのデータの長さ。

RETURNED_LENGTH

FETCH後の実際のデータ長。固定長キャラクタ・タイプについては未定義になります。

RETURNED_OCTET_LENGTH

戻されたデータのバイト単位での長さ。

PRECISION

桁数。

SCALE

真数値型での小数点の右側の桁数。

NULLABLE

1のときは、列にNULL値を使用できます。0のときは、列にNULL値は使用できません。

INDICATOR

対応付けられたインジケータ値。

DATA

データ値。

NAME

列名。

CHARACTER_SET_NAME

列のキャラクタ・セット。

次の表に、記述子項目名のOracle拡張機能を示します。

表10-5 記述子項目名の定義のOracle拡張機能

記述子項目名

意味

NATIONAL_CHARACTER

2はNCHARまたはNVARCHAR2を示します。1は文字を示します。0は文字以外を示します。

INTERNAL_LENGTH

内部でのバイト単位の長さ。

使用上の注意

FOR句は、DATA、INDICATORおよびRETURNED_LENGTH項目のみを含むGET DESCRIPTOR文で使用してください。

内部型は、DESCRIBE OUTPUT文によって設定されます。入力および出力のどちらでも、ホスト変数の外部型に使用する型を設定する必要があります。TYPEは、OracleコードまたはANSIコード(表10-1)です。ANSI型が表にはない場合は、Oracle型の負の値が戻されます。

LENGTHには、列の長さが格納され、固定幅の各国語キャラクタ・セットが設定されたフィールドでは文字単位になります。それ以外のキャラクタ列ではバイト単位になります。LENGTHはDESCRIBE OUTPUTによって設定されます。

RETURNED_LENGTHは、FETCH文によって設定される実際のデータ長です。LENGTHと同様にバイト単位または文字単位になります。フィールドOCTET_LENGTHおよびRETURNED_OCTET_LENGTHは、バイト単位の長さです。

NULLABLE = 1は、列にNULLを使用できることを示します。NULLABLE = 0は、列にNULLを使用できないことを示します。

CHARACTER_SET_NAMEは、キャラクタ列の場合にのみ意味があります。他の型では未定義になります。DESCRIBE OUTPUT文によって値が設定されます。

DATAおよびINDICATORは、その列のデータ値およびインジケータ・ステータスです。データがNULLでインジケータが要求されなかった場合は、実行時にエラーが発生します(DATA EXCEPTION, NULL VALUE, NO INDICATOR PARAMETER)。

Oracle固有の記述子項目名

列がNCHARまたはNVARCHAR2列の場合は、NATIONAL_CHARACTER = 2になります。列がキャラクタ(ただし、各国語キャラクタではない)列の場合、項目は1に設定されます。キャラクタ以外の列の場合、DESCRIBE OUTPUTの実行後にこの項目は0に設定されます。

INTERNAL_LENGTHは、Oracle動的方法4との互換性があるため、Oracle記述子領域の長さメンバーと同じ値に設定されます。この項目にはOracle記述子領域の長さメンバーと同じ値が設定されています。「Oracle動的SQL: 方法4」を参照してください。

例

EXEC SQL GET DESCRIPTOR :BINDDES :COUNT = COUNT END-EXEC.

EXEC SQL GET DESCRIPTOR 'SELDES' VALUE 1 :TYP = TYPE, :LEN = LENGTH
END-EXEC.

EXEC SQL FOR :BATCH GET DESCRIPTOR LOCAL 'SELDES'
VALUE :SEL-ITEM-NO :IND = INDICATOR, :DAT = DATA END-EXEC.

SET DESCRIPTOR

用途

この文は、ホスト変数からの記述子領域の情報を設定するために使用します。SET DESCRIPTOR文では、項目名のホスト変数のみサポートされます。

構文

EXEC SQL [FOR [:]array_size] SET DESCRIPTOR [GLOBAL | LOCAL]
{:desc_nam | string_literal}
{COUNT = :hv0 | VALUE item_number
[REF] item_name1 = :hv1
[{, [REF] item_nameN = :hvN}]}
END-EXEC.

変数

array_size

このOracleオプション句で配列を使用できるのは、記述子項目DATA、INDICATORおよびRETURNED_LENGTHの設定時のみです。FOR句を含むSET DESCRIPTORでは他の項目を使用できません。ホスト変数表サイズはすべて一致している必要があります。FETCH文で使用するのと同じ配列サイズをSET文で使用してください。

desc_nam

記述子名。ALLOCATE DESCRIPTORでの規則が適用されます。

COUNT

バインド(入力)変数または定義(出力)変数の数。

VALUE item_number

動的SQL文でのホスト変数の位置。

hv1 .. hvN

設定するホスト変数(定数ではありません)。

item_name1 .. item_nameN

GET DESCRIPTOR構文(「GET DESCRIPTOR」を参照)と同様に、item_nameに次の値を指定できます。

表10-6 SET DESCRIPTORの記述子項目名

記述子項目名

意味

TYPE

ANSI型コードは表10-1を参照してください。Oracle型コードは表11-2を参照してください。ANSI型が表にはなく、TYPE_CODE = ANSIである場合は、Oracle型コードの負の値を使用してください。

LENGTH

列内のデータの最大長。

PRECISION

桁数。

SCALE

真数値型での小数点の右側のバイト数。

INDICATOR

対応付けられたインジケータ値。参照セマンティクスのために設定します。

DATA

設定するデータの値。参照セマンティクスのために設定します。

CHARACTER_SET_NAME

列のキャラクタ・セット。

次の表に、記述子項目名のOracle拡張機能を示します。

表10-7 SET DESCRIPTORの記述子項目名の拡張機能

記述子項目名

意味

RETURNED_LENGTH

FETCH後に戻される長さ。参照セマンティクスを使用する場合に設定します。

NATIONAL_CHARACTER

入力ホスト変数がNCHARまたはNVARCHAR2型のときは、2に設定します。

使用上の注意

参照セマンティクスは、パフォーマンス向上のために使用する別のオプションのOracle拡張機能です。記述子項目名がDATA、INDICATORおよびRETURNED_LENGTHの場合にのみ、それらの前にREFキーワードを指定します。REFキーワードを使用した場合は、GET文を使用する必要はありません。複合データ型およびDMLのRETURNING句には、SET DESCRIPTORのREF書式が必要です。「DML RETURNING句」を参照してください。

REFを使用すると、対応付けられたホスト変数自体がSETで使用されます。この場合、GETは必要ありません。値構文ではなく、REFセマンティクスを使用するときにのみ、RETURNED_LENGTHを設定できます。

SETまたはGET文の配列サイズは、FETCHで使用する配列サイズと同じにしてください。

NCHARホスト変数には、NATIONAL_CHARフィールドを2に設定します。

オブジェクト型の特性を設定するときは、USER_DEFINED_TYPE_NAMEおよびUSER_DEFINED_TYPE_NAME_LENGTHを設定する必要があります。

省略した場合は、USER_DEFINED_TYPE_SCHEMAおよびUSER_DEFINED_TYPE_SCHEMA_LENGTHはデフォルトで現行の接続に設定されます。

例

バルク表の例は、「バルク操作での表の使用方法」を参照してください。

...
O1  BINDNO  PIC S9(9) COMP  VALUE 2.
01  INDI    PIC S9(4) COMP  VALUE -1.
01  DATA    PIC X(6)  COMP  VALUE "ignore".
01  BATCH   PIC S9(9) COMP  VALUE 1.
...
EXEC SQL FOR :batch ALLOCATE DESCRIPTOR :BINDDES END-EXEC.
EXEC SQL SET DESCRIPTOR GLOBAL :BINDDES COUNT = 3 END-EXEC.
EXEC SQL FOR :batch SET DESCRIPTOR :BINDDES
VALUE :BINDNO INDICATOR = :INDI, DATA = :DATA END-EXEC.
...

PREPAREの使用

用途

この方法で使用するPREPARE文は、Oracle動的SQL方法で使用するPREPARE文と同じです。Oracle拡張機能によって、変数と同様にSQL文で引用符付き文字列を使用できます。

構文

EXEC SQL PREPARE statement_id FROM :sql_statement END-EXEC.

変数

statement_id

この変数を宣言しないでください。これは、準備済のSQL文に対応付けられた宣言されていないSQL識別子です。

sql_statement

埋込みSQL文を格納する文字列(定数または変数)。

例

...
01  STATEMENT    PIC X(255)
VALUE "SELECT ENAME FROM emp WHERE deptno = :d".
...
EXEC SQL PREPARE S1 FROM :STATEMENT END-EXEC.

DESCRIBE INPUT

用途

この文は、入力バインド変数に関する情報を戻します。

構文

EXEC SQL DESCRIBE INPUT statement_id USING [SQL] DESCRIPTOR
[GLOBAL | LOCAL] {:desc_nam | string_literal}
END-EXEC.

変数

statement_id

PREPAREおよびDESCRIBE OUTPUTで使用するものと同じです。これは宣言しないでください(これはSQL識別子です)。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

desc_nam

記述子名。

使用上の注意

このバージョンでは、COUNTおよびNAMEのみがバインド変数のために実装されています。

例

EXEC SQL DESCRIBE INPUT S1 USING SQL DESCRIPTOR GLOBAL :BINDDES END-EXEC.
EXEC SQL DESCRIBE INPUT S2 USING DESCRIPTOR 'input' END-EXEC.

DESCRIBE OUTPUT

用途

DESCRIBE INPUT文は、PREPARE文の列に関する情報を取得するために使用します。ANSI構文は以前の構文と違います。SQL記述子領域に格納される情報は、戻された値の個数、および関連する情報(型、長さ、名前など)です。

構文

EXEC SQL DESCRIBE [OUTPUT] statement_id USING [SQL] DESCRIPTOR
[GLOBAL | LOCAL] {:desc_nam | string_literal}
END-EXEC.

変数

statement_id

statement_idはSQL識別子です。宣言しないでください。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

desc_nam

記述子名。ホスト変数の前に「:」を付けたもの、または引用符付き文字列。OUTPUTがデフォルト設定で、これは省略できます。

例

...
01  DESNAME   PIC X(10) VALUE "SELDES".
...
EXEC SQL DESCRIBE S1 USING SQL DESCRIPTOR 'SELDES' END-EXEC.
* Or:
EXEC SQL DESCRIBE OUTPUT S1 USING DESCRIPTOR :DESNAME END-EXEC.

EXECUTE

用途

EXECUTEは、準備済のSQL文の入力変数および出力変数を照合し、文を実行します。ANSIバージョンのEXECUTEは、以前のEXECUTEとは違い、DML RETURNINGをサポートするために1つの文に記述子を2つ使用できます。

構文

EXEC SQL [FOR [:]array_size] EXECUTE statement_id
[USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}]
[INTO [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}]
END-EXEC.

変数

array_size

文が処理する行数。

statement_id

PREPAREで使用するものと同じです。これは宣言しないでください(これはSQL識別子です)。リテラルを指定できます。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

desc_nam

記述子名。ホスト変数の前に「:」を付けたもの、または引用符付き文字列。

使用上の注意

INTO句は、INSERT、UPDATEおよびDELETEのRETURNING句を実装します(「行の挿入」とその後のページを参照してください)。

例

EXEC SQL EXECUTE S1 USING SQL DESCRIPTOR GLOBAL :BINDDES END-EXEC.

EXEC SQL EXECUTE S2 USING DESCRIPTOR :bv1 INTO DESCRIPTOR 'SELDES'
END-EXEC.

EXECUTE IMMEDIATEの使用

用途

EXECUTE IMMEDIATE文は、SQL文を含むリテラル文字列またはホスト変数文字列を実行します。この文のANSI SQL書式は、以前の動的SQLと同じです。

構文

EXEC SQL EXECUTE IMMEDIATE [:]sql_statement END-EXEC.

変数

EXECUTE IMMEDIATE文で使用できる変数は1つです。

sql_statement

sql_statement変数は、文字列内のSQL文またはPL/SQLブロックです。ホスト変数にもリテラルにも使用できます。

例

EXEC SQL EXECUTE IMMEDIATE :statement END-EXEC.

DYNAMIC DECLARE CURSORの使用

用途

DYNAMIC DECLARE CURSOR文は、問合せ文に対応付けられたカーソルを宣言します。これは、一般的なカーソル宣言部です。

構文

EXEC SQL DECLARE cursor_name CURSOR FOR statement_id END-EXEC.

変数

cursor_name

カーソル変数(SQL識別子であり、ホスト変数ではありません)。

statement_id

未定義のSQL識別子(PREPARE文で使用するものと同じです)。

例

EXEC SQL DECLARE C1 CURSOR FOR S1 END-EXEC.

カーソルのOPEN

用途

OPEN文は、入力パラメータとカーソルとを対応付け、カーソルをオープンします。

構文

EXEC SQL [FOR [:]array_size] OPEN dyn_cursor
[[USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] desc_nam1]
[INTO [SQL] DESCRIPTOR [GLOBAL | LOCAL] desc_nam2] ]
END-EXEC.

変数

array_size

この変数は、記述子を割り当てた時に指定した数と等しいか、それよりも小さい数に制限されます。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

dyn_cursor

カーソル変数。

desc_nam1、desc_nam2

オプションの記述子名。

使用上の注意

カーソルに対応付けられた準備済の文にコロンまたは疑問符が含まれる場合は、USING句を指定する必要があります。指定しない場合は、ランタイム・エラーが発生します。INTO句はDML RETURNINGをサポートしています(「行の挿入」およびそれ以降のDELETEおよびUPDATEに関する項を参照してください)。

例

EXEC SQL OPEN C1 USING SQL DESCRIPTOR :BINDDES END-EXEC.

EXEC SQL FOR :LIMIT OPEN C2 USING DESCRIPTOR :B1, :B2
INTO SQL DESCRIPTOR :SELDES
END-EXEC.

FETCH

用途

FETCH文は、動的DECLARE文で宣言したカーソルの行をフェッチします。

構文

EXEC SQL [FOR [:]array_size] FETCH cursor INTO [SQL] DESCRIPTOR
[GLOBAL | LOCAL] {:desc_nam | string_literal}
END-EXEC.

変数

array_size

文が処理する行数。

cursor

事前に宣言された動的カーソル。

GLOBAL | LOCAL

GLOBALは、すべてのプログラム・ファイルで記述子名が認識されることを示します。LOCALは、記述子名を割り当てたファイル内でのみ記述子名が認識されることを示します。LOCALがデフォルトです。

desc_nam

記述子名。

使用上の注意

FOR句のオプションのarray_sizeは、ALLOCATE DESCRIPTOR文で指定した数と等しいか、それより小さい必要があります。

RETURNED_LENGTHは、固定長キャラクタ・タイプに対しては未定義になります。

例

EXEC SQL FETCH FROM C1 INTO DESCRIPTOR 'SELDES' END-EXEC.

EXEC SQL FOR :ARSZ FETCH C2 INTO DESCRIPTOR :DESC END-EXEC.

動的カーソルのCLOSE

用途

CLOSE文は動的カーソルをクローズします。構文は方法4の場合と同じです。

構文

EXEC SQL CLOSE cursor END-EXEC.

変数

CLOSE文で使用できる変数は1つです。

cursor

カーソル変数は、前に宣言した動的カーソルを記述します。

例

EXEC SQL CLOSE C1 END-EXEC.

Oracle動的方法4との違い

ANSI動的SQLインタフェースでは、Oracle動的方法4でサポートされる機能がすべてサポートされており、それ以外に次のサポートが追加されています。

- ANSI動的SQLでは、すべてのデータ型(カーソル変数を含む)およびLOB型がサポートされます。

- ANSIモードでは、内部のSQL記述領域が使用されますが、これは、Oracleの以前の動的方法4で入力および出力情報の格納に使用される外部SQLDAを拡張したものです。

- ALLOCATE DESCRIPTOR、DEALLOCATE DESCRIPTOR、DESCRIBE、GET DESCRIPTORおよびSET DESCRIPTORという新しい埋込みSQL文が導入されています。

- ANSI動的SQLでは、DESCRIBE文は標識変数の名前を戻しません。

- ANSI動的SQLでは、戻される列名または式の最大サイズを指定できません。デフォルト・サイズは128に設定されます。

- 記述子名は、引用符で囲んだ識別子、または先頭にコロンをつけたホスト変数のどちらかであることが必要です。

- 出力時に、DESCRIBE文のSELECT LIST FOR句はオプション・キーワードOUTPUTに置き換えられます。INTO句はUSING DESCRIPTOR句に置き換えられます。この句には、オプション・キーワードSQLを含めることができます。

- 入力時に、DESCRIBE文のオプションのBIND VARIABLES FOR句をキーワードINPUTに置き換えることができます。INTO句はUSING DESCRIPTOR句に置き換えられます。この句には、オプション・キーワードSQLを含めることができます。

- EXECUTE、FETCHおよびOPEN文でUSING句のキーワードDESCRIPTORの前にオプション・キーワードSQLを指定できます。

制限

ANSI動的SQLには次の制限が適用されます。

- 同じモジュール内で2つの動的方法は併用できません。

- プリコンパイラ・オプションDYNAMICをANSIに設定する必要があります。DYNAMICをANSIに設定したときにのみ、プリコンパイラ・オプションTYPE_CODEをANSIに設定できます。

- SET文は、項目名としてのホスト変数のみサポートします。

サンプル・プログラム: SAMPLE12.PCO

次のANSI SQL動的方法4プログラムSAMPLE12.PCOは、デモ・ディレクトリにあります。SAMPLE12は、ユーザーが入力するSQL文を要求することによってSQL*Plusを模造したプログラムです。プログラムの流れの詳細は、最初のコメントを参照してください。

******************************************************************
* Sample Program 12: Dynamic SQL Method 4 using ANSI Dynamic SQL *
*                                                                *
* This program shows the basic steps required to use dynamic     *
* SQL Method 4 with ANSI Dynamic SQL.  After logging on to       *
* ORACLE, the program prompts the user for a SQL statement,      *
* PREPAREs the statement, DECLAREs a cursor, checks for any      *
* bind variables using DESCRIBE INPUT, OPENs the cursor, and     *
* DESCRIBEs any select-list variables.  If the input SQL         *
* statement is a query, the program FETCHes each row of data,    *
* then CLOSEs the cursor.                                        *
* use option dynamic=ansi when precompiling this sample.         *
******************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID.  ANSIDYNSQL4.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

01  USERNAME       PIC X(20).
01  PASSWD         PIC X(20).
01  BDSC           PIC X(6) VALUE "BNDDSC".
01  SDSC           PIC X(6) VALUE "SELDSC".
01  BNDCNT         PIC S9(9) COMP.
01  SELCNT         PIC S9(9) COMP.
01  BNDNAME        PIC X(80).
01  BNDVAL         PIC X(80).
01  SELNAME        PIC X(80) VARYING.
01  SELDATA        PIC X(80).
01  SELTYP         PIC S9(4) COMP.
01  SELPREC        PIC S9(4) COMP.
01  SELLEN         PIC S9(4) COMP.
01  SELIND         PIC S9(4) COMP.
01  DYN-STATEMENT  PIC X(80).
01  BND-INDEX      PIC S9(9) COMP.
01  SEL-INDEX      PIC S9(9) COMP.
01  VARCHAR2-TYP   PIC S9(4) COMP VALUE 1.
01  VAR-COUNT      PIC 9(2).
01  ROW-COUNT      PIC 9(4).
01  NO-MORE-DATA   PIC X(1) VALUE "N".
01  TMPLEN         PIC S9(9) COMP.
01  MAX-LENGTH     PIC S9(9) COMP VALUE 80.

EXEC SQL INCLUDE SQLCA         END-EXEC.

PROCEDURE DIVISION.
START-MAIN.

EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC.

DISPLAY "USERNAME: " WITH NO ADVANCING.
ACCEPT USERNAME.
DISPLAY "PASSWORD: " WITH NO ADVANCING.
ACCEPT PASSWD.
EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWD END-EXEC.
DISPLAY "CONNECTED TO ORACLE AS USER: ", USERNAME.

*    ALLOCATE THE BIND AND SELECT DESCRIPTORS.

EXEC SQL ALLOCATE DESCRIPTOR :BDSC WITH MAX 20 END-EXEC.
EXEC SQL ALLOCATE DESCRIPTOR :SDSC WITH MAX 20 END-EXEC.

*    GET A SQL STATEMENT FROM THE OPERATOR.

DISPLAY "ENTER SQL STATEMENT WITHOUT TERMINATOR:".
DISPLAY ">" WITH NO ADVANCING.
ACCEPT DYN-STATEMENT.
DISPLAY " ".

*    PREPARE THE SQL STATEMENT AND DECLARE A CURSOR.

EXEC SQL  PREPARE S1 FROM :DYN-STATEMENT  END-EXEC.
EXEC SQL  DECLARE C1 CURSOR FOR S1        END-EXEC.

*    DESCRIBE BIND VARIABLES.

EXEC SQL DESCRIBE INPUT S1 USING DESCRIPTOR :BDSC END-EXEC.

EXEC SQL GET DESCRIPTOR :BDSC :BNDCNT = COUNT END-EXEC.

IF BNDCNT < 0
DISPLAY "TOO MANY BIND VARIABLES."
GO TO END-SQL
ELSE
DISPLAY "NUMBER OF BIND VARIABLES: " WITH NO ADVANCING
MOVE BNDCNT TO VAR-COUNT
DISPLAY VAR-COUNT
*        EXEC SQL SET DESCRIPTOR :BDSC COUNT = :BNDCNT END-EXEC
END-IF.

IF BNDCNT = 0
GO TO DESCRIBE-ITEMS.
PERFORM SET-BND-DSC
VARYING BND-INDEX FROM 1 BY 1
UNTIL BND-INDEX > BNDCNT.

*    OPEN THE CURSOR AND DESCRIBE THE SELECT-LIST ITEMS.

DESCRIBE-ITEMS.
EXEC SQL  OPEN C1 USING DESCRIPTOR :BDSC END-EXEC.

EXEC SQL  DESCRIBE OUTPUT S1 USING DESCRIPTOR :SDSC  END-EXEC.

EXEC SQL GET DESCRIPTOR :SDSC :SELCNT = COUNT END-EXEC.

IF SELCNT < 0
DISPLAY "TOO MANY SELECT-LIST ITEMS."
GO TO END-SQL
ELSE
DISPLAY "NUMBER OF SELECT-LIST ITEMS: "
WITH NO ADVANCING
MOVE SELCNT TO VAR-COUNT
DISPLAY VAR-COUNT
DISPLAY " "
*        EXEC SQL SET DESCRIPTOR :SDSC COUNT = :SELCNT END-EXEC
END-IF.

*    SET THE INPUT DESCRIPTOR

IF SELCNT > 0
PERFORM SET-SEL-DSC
VARYING SEL-INDEX FROM 1 BY 1
UNTIL SEL-INDEX > SELCNT
DISPLAY " ".

*    FETCH EACH ROW AND PRINT EACH SELECT-LIST VALUE.

IF SELCNT > 0
PERFORM FETCH-ROWS UNTIL NO-MORE-DATA = "Y".

DISPLAY " "
DISPLAY "NUMBER OF ROWS PROCESSED: " WITH NO ADVANCING.
MOVE SQLERRD(3) TO ROW-COUNT.
DISPLAY ROW-COUNT.

*    CLEAN UP AND TERMINATE.

EXEC SQL CLOSE C1 END-EXEC.
EXEC SQL DEALLOCATE DESCRIPTOR :BDSC END-EXEC.
EXEC SQL DEALLOCATE DESCRIPTOR :SDSC END-EXEC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY!".
DISPLAY " ".
STOP RUN.

*    DISPLAY ORACLE ERROR MESSAGE AND CODE.

SQL-ERROR.
DISPLAY " ".
DISPLAY SQLERRMC.
END-SQL.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

*    PERFORMED SUBROUTINES BEGIN HERE:

*    SET A BIND-LIST ELEMENT'S ATTRIBUTE
*    LET THE USER FILL IN THE BIND VARIABLES AND
*    REPLACE THE 0S DESCRIBED INTO THE DATATYPE FIELDS OF THE
*    BIND DESCRIPTOR WITH 1S TO AVOID AN "INVALID DATATYPE"
*    ORACLE ERROR
SET-BND-DSC.
EXEC SQL GET DESCRIPTOR :BDSC VALUE
:BND-INDEX :BNDNAME = NAME END-EXEC.
DISPLAY "ENTER VALUE FOR ", BNDNAME.
ACCEPT BNDVAL.
EXEC SQL SET DESCRIPTOR :BDSC VALUE :BND-INDEX
TYPE = :VARCHAR2-TYP, LENGTH = :MAX-LENGTH,
DATA = :BNDVAL END-EXEC.

* SET A SELECT-LIST ELEMENT'S ATTRIBUTES
SET-SEL-DSC.
MOVE SPACES TO SELNAME-ARR.
EXEC SQL GET DESCRIPTOR :SDSC VALUE :SEL-INDEX
:SELNAME = NAME, :SELTYP = TYPE,
:SELPREC = PRECISION, :SELLEN = LENGTH END-EXEC.

*    IF DATATYPE IS DATE, LENGTHEN TO 9 CHARACTERS.
IF SELTYP = 12
MOVE 9 TO SELLEN.

*    IF DATATYPE IS NUMBER, SET LENGTH TO PRECISION.
MOVE 0 TO TMPLEN.
IF SELTYP = 2 AND SELPREC = 0
MOVE 40 TO TMPLEN.
IF SELTYP = 2 AND SELPREC > 0
ADD 2 TO SELPREC
MOVE SELPREC TO TMPLEN.

IF SELTYP = 2
IF TMPLEN > MAX-LENGTH
DISPLAY "COLUMN VALUE TOO LARGE FOR DATA BUFFER."
GO TO END-SQL
ELSE
MOVE TMPLEN TO SELLEN.

* COERCE DATATYPES TO VARCHAR2.
MOVE 1 TO SELTYP.

*    DISPLAY COLUMN HEADING.
DISPLAY "  ", SELNAME-ARR(1:SELLEN) WITH NO ADVANCING.

EXEC SQL SET DESCRIPTOR :SDSC VALUE :SEL-INDEX
TYPE = :SELTYP, LENGTH = :SELLEN END-EXEC.

* FETCH A ROW AND PRINT THE SELECT-LIST VALUE.

FETCH-ROWS.
EXEC SQL  FETCH C1 INTO DESCRIPTOR :SDSC END-EXEC.
IF SQLCODE NOT = 0
MOVE "Y" TO NO-MORE-DATA.
IF SQLCODE = 0
PERFORM PRINT-COLUMN-VALUES
VARYING SEL-INDEX FROM 1 BY 1
UNTIL SEL-INDEX > SELCNT
DISPLAY " ".

* PRINT A SELECT-LIST VALUE.

PRINT-COLUMN-VALUES.
MOVE SPACES TO SELDATA.
*    returned length is not set for blank padded types
IF SELTYP EQUALS 1
EXEC SQL GET DESCRIPTOR :SDSC VALUE :SEL-INDEX
:SELDATA = DATA, :SELIND = INDICATOR,
:SELLEN = LENGTH END-EXEC
ELSE
EXEC SQL GET DESCRIPTOR :SDSC VALUE :SEL-INDEX
:SELDATA = DATA, :SELIND = INDICATOR,
:SELLEN = RETURNED_LENGTH END-EXEC.
IF (SELIND = -1)
move "  NULL" to SELDATA.

DISPLAY SELDATA(1:SELLEN), "  "
WITH NO ADVANCING.

11 Oracle動的SQL: 方法4

この章ではOracle動的SQL方法4を実装する方法を説明します。この方法では、ホスト変数を含む動的SQL文を受け取ったり、作成できます。含まれるホスト変数の個数は様々です。

新しいアプリケーションは、第10章「ANSI動的SQL」に示した最新のANSI SQL方法4を使用して開発してください。ANSI方法4では、Oracleのすべての型をサポートしています。しかし、古いOracle方法4では、カーソル変数、グループ項目の表、DML RETURNING句およびLOBをサポートしていません。

内容は次のとおりです。

- 方法4の特殊要件

- SQL記述子領域(SQLDA)の理解

- SQLDA変数

- 前提知識

- 基本手順

- 各手順の詳細

- 方法4でのホスト表の使用

- サンプル・プログラム10: 動的SQL方法4

注意:
動的SQL方法1、2および3の詳細と方法4の概要は、第9章「Oracle動的SQL」を参照してください。

方法4の特殊要件

方法4の要件を学ぶ前に、選択リスト項目およびプレースホルダの用語を十分に理解してください。選択リスト項目とは、問合せ内でキーワードSELECTの後に続く列または式のことです。たとえば、次の動的問合せは3つの選択リスト項目を含んでいます。

SELECT ENAME, JOB, SAL + COMM FROM EMP WHERE DEPTNO = 20

プレースホルダとは、SQL文の中で実際のバインド変数用に場所を確保する、ダミーのバインド(入力)変数のことです。宣言する必要はなく、任意の名前を付けられます。バインド変数のプレースホルダは、SET、VALUESおよびWHERE句で多く使用されます。たとえば、次の動的SQL文にはそれぞれ2つのプレースホルダが記述されています。

INSERT INTO EMP (EMPNO, DEPTNO) VALUES (:E, :D)
DELETE FROM DEPT WHERE DEPTNO = :DNUM AND LOC = :DLOC

プレースホルダでは、表または列の名前は参照できません。

方法4の利点

方法1、2および3とは異なり、動的SQL方法4ではプログラムで次のことができます。

- 選択リスト項目の数またはプレースホルダの数が不明な動的SQL文の受け入れまたは作成

- OracleとCOBOL間のデータ型変換の明示的な制御

このような柔軟性をプログラムに加えるには、ランタイム・ライブラリに情報を追加する必要があります。

データベースに必要な情報

Pro*COBOLは、実行可能なすべての動的SQL文についてOracleのコールを作成します。データベースは、選択リスト項目もプレースホルダも組み込まれていない動的SQL文の実行には追加情報を必要としません。次のDELETE文がこのカテゴリに該当します。

*    Dynamic SQL statement...
MOVE 'DELETE FROM EMP WHERE DEPTNO = 30' TO STMT.

しかし、ほとんどの動的SQL文には選択リスト項目またはバインド変数のプレースホルダが組み込まれています。次のUPDATE文はその一例です。

*    Dynamic SQL statement with place-holders...
MOVE 'UPDATE EMP SET COMM = :C WHERE EMPNO = :E' TO STMT.

選択リスト項目またはバインド変数のプレースホルダ(あるいはその両方)が組み込まれている動的SQL文を実行する場合、データベースは出力値または入力値を格納するプログラム変数についての情報を必要とします。データベースでは、特に次の情報が必要です。

- 選択リスト項目およびバインド変数の数

- 各選択リスト項目および各バインド変数の長さ

- 各選択リスト項目および各バインド変数のデータ型

- 選択リスト項目の値を格納する各出力変数のメモリー・アドレスおよび各バインド変数のアドレス

たとえば、選択リスト項目の値を書き込むには、データベースは対応する出力変数のアドレスが必要です。

情報の格納位置

選択リスト項目またはバインド変数のプレースホルダに関してデータベースが必要とする情報は、(その値を除いて)すべてSQL記述子領域(SQLDA)と呼ばれるプログラム・データ構造に格納されます。

選択リスト項目の記述は選択SQLDAに格納され、バインド変数のプレースホルダの記述はバインドSQLDAに格納されます。

選択リスト項目の値は出力バッファに格納され、バインド変数の値は入力バッファに格納されます。これらのデータ・バッファのアドレスをライブラリ・ルーチンSQLADRを使用して選択SQLDAまたはバインドSQLDAに格納すると、データベースは出力値の書込み先や入力値の読取り元を認識できます。

値はどのようにしてこれらのデータ変数に格納されるのでしょうか。FETCHはカーソルを使用して出力値を生成します。入力値は、通常はユーザーが対話形式で入力した情報をもとに、プログラムによって代入されます。

情報の取得方法

データベースが必要とする情報を取得するには、DESCRIBE文を使用します。DESCRIBE SELECT LIST文は、各選択リスト項目を調べて、その名前、データ型、制約、長さ、位取りおよび精度を確認した後、それらの情報を選択SQLDAに格納します。たとえば、格納された情報は、後で印刷出力の列見出しとして選択リスト名を使用するときなどに使用できます。DESCRIBEでは、選択リスト項目の総数もSQLDAに格納されます。

DESCRIBE BIND VARIABLES文は、各プレースホルダを調べて、その名前および長さを確認した後、それらの情報を入力バッファおよびバインドSQLDAに格納します。格納された情報は、後でプレースホルダ名を使用してバインド変数の値の入力をユーザーに求めるときなどに使用できます。

SQL記述子領域(SQLDA)の理解

この項ではSQLDAのデータ構造を詳しく説明します。SQLDAの宣言方法、格納されている変数、初期化の方法およびプログラム内での使用方法を理解できます。

SQLDAの目的

方法4は、選択リスト項目の数またはバインド変数のプレースホルダの数が不明な動的SQL文の処理に必要とされます。このような動的SQL文を処理するには、プログラムでSQLDA (記述子とも呼ばれます)を明示的に宣言する必要があります。個々の記述子は、プログラム内のグループ項目に対応します。

選択記述子には、選択リスト項目の記述、および選択リスト項目の名前および値を格納する出力バッファのアドレスが格納されます。

注意:
選択リスト項目の名前には、列名、列の別名またはSAL+COMMなどの式を表すテキストが使用できます。

バインド記述子にはバインド変数と標識変数の記述、およびバインド変数と標識変数の名前と値が格納されている入力バッファのアドレスを格納します。

記述子変数の中には、値ではなくアドレスを格納するものがあります。このため、値を保持するためのデータ・バッファを宣言する必要があります。必要な入力バッファおよび出力バッファのサイズは自由に設定できます。COBOLではポインタはサポートされていないので、入力バッファおよび出力バッファのアドレスを取得するにはライブラリ・サブルーチンSQLADRを使用する必要があります。SQLADRのコール方法については、「SQLADRの使用」を参照してください。

複数のSQLDA

プログラムにアクティブな動的SQL文が2つ以上ある場合は、それぞれの文が専用のSQLDAを持つ必要があります。別の名前で任意の数のSQLDAを宣言できます。たとえば、同時にオープンされている3つのカーソルからFETCHするために、SELDSC1、SELDSC2およびSELDSC3の名前の3つの選択SQLDAを宣言できます。ただし、非並行のカーソルではSQLDAを再利用できます。

SQLDAの宣言

選択およびバインドSQLDAを宣言するには、図11-1に示す選択およびバインドSQLDAのサンプルを使用して、プログラムに記述する方法があります。配列の大きさは、必要に応じて変更できます。

注意:
バイトスワップ・プラットフォームの場合は、SQLDAの宣言時にCOMPのかわりにCOMP5を使用します。

図11-1 サンプルPro*COBOL SQLDA記述子およびデータ・バッファの例(32ビット)

注意:
64ビット・プラットフォームの場合は、SQLDAの宣言時に、PIC S9(9)のかわりにPIC S9(18)を使用します。

次に示すように、SQLDAを(たとえばSELDSCおよびBNDDSCの名前の)ファイルに格納して、INCLUDE文を使用してそのファイルをプログラムにコピーできます。

EXEC SQL INCLUDE SELDSC END-EXEC.
EXEC SQL INCLUDE BNDDSC END-EXEC.

図11-2は、変数がSQLADRコール、DESCRIBEコマンド、FETCHコマンドまたはプログラム代入のどれによって設定されるかを示しています。

図11-2 変数の設定方法

SQLDA変数

この項では、SQLDA内の各変数の用途および使用方法を説明します。

SQLDNUM

この変数では、DESCRIBEに含めることができる選択リスト項目またはプレースホルダの最大数を指定します。したがって、SQLDNUMによって記述子表の要素の数(ディメンション)が決まります。

DESCRIBEコマンドを発行する前に、この変数を記述子表のサイズに設定する必要があります。また、DESCRIBEの実行後に、この変数をDESCRIBE内の実際の変数の数(これはSQLDFNDに格納されます)に再設定する必要があります。

SQLDFND

SQLDFND変数は、DESCRIBEコマンドで実際に検出された選択リスト項目またはプレースホルダの数です。

SQLDFNDはDESCRIBEによって設定されます。SQLDFNDが負の値の場合は、DESCRIBEコマンドが検出した選択リスト項目またはプレースホルダの数が、記述子のサイズに対して多すぎることを意味します。たとえば、SQLDNUMを10に設定した場合にDESCRIBEで11個の選択リスト項目またはプレースホルダが検索されると、SQLDFNDは-11に設定されます。この場合、記述子を再び割り当てないかぎりSQL文の処理はできません。

DESCRIBEの後で、SQLDNUMをSQLDFNDの値に設定してください。

SELDV | BNDDV

SELDV | BNDDV表は、選択リストまたはバインド変数の値を格納するデータ・バッファのアドレスの表です。

SELDVおよびBNDDVの要素は、SQLADRを使用して設定する必要があります。

選択記述子の場合

次の文を実行するとします。

EXEC SQL FETCH ... USING DESCRIPTOR ...

この文は、FETCHされた選択リスト変数を、SELDV(1)からSELDV(SQLDNUM)でアドレス指定されたデータ・バッファに格納するようにデータベースに指示します。したがって、データベースはJ番目の選択リスト値をSEL-DV(J)に格納します。

バインド記述子の場合

バインド記述子は、OPENコマンドを発行する前に設定する必要があります。次の文を実行するとします。

EXEC SQL OPEN ... USING DESCRIPTOR ...

この文は、BNDDV(1)からBNDDV(SQLDNUM)でアドレス指定されたバインド変数の値を使用して動的SQL文を実行するように、Oracleに指示します。(通常、値はユーザーによって入力されます。)データベースは、J番目のバインド変数値をBND-DV(J)から検索します。

SELDFMT | BNDDFMT

SELDFMT | BNDDFMT表は、選択リストまたはバインド変数の変換フォーマット文字列の値を格納するデータ・バッファのアドレスの表です。現在は、COBOLのパック10進数にのみ使用できます。変換文字列の書式はPP.+SSまたはPP.-SSです。PPは精度、SSは位取りです。精度および位取りの定義については、「精度および位取りの抽出」の項を参照してください。

フォーマット文字列の使用はオプションです。J番目の選択リスト項目またはバインド変数に変換形式を使用する場合は、SQLADRを使用してSELDFMT(J)またはBNDDFMT(J)を設定し、パック10進形式(07.+02など)をSEL-DFMTまたはBND-DFMTに格納します。変換形式を使用しない場合は、SELDFMT(J)またはBNDDFMT(J)を0 (ゼロ)に設定してください。

SELDVLN | BNDDVLN

SELDVLN | BNDDVLNは、データ・バッファに格納される選択リスト変数またはバインド変数値の長さの表です。

選択記述子の場合

この表は、DESCRIBE SELECT LISTによって、各選択リスト項目に期待される最大値に設定されます。しかし、FETCHコマンドを発行する前に長さを再設定する場合も考えられます。FETCHでは最大でn文字が戻されます(nは、FETCHコマンドを実行する前のSELDVLN(J)の値です)。

長さの形式はデータ型によって異なります。CHAR型の選択リスト項目の場合は、DESCRIBE SELECT LISTはSELDVLN(J)をその選択リスト項目の最大長(バイト数)に設定します。NUMBER型の選択リスト項目については、位取りおよび精度が変数の下位バイトおよびその次の上位側バイトにそれぞれ戻されます。ライブラリ・ルーチンSQLPRCを使用して、SELDVLNから精度および位取りを抽出できます。「精度および位取りの抽出」を参照してください。

FETCHを実行する前に、SELDVLN(J)を必要なデータ・バッファの長さに再設定する必要があります。たとえば、NUMBER型の数値をCOBOLの文字列に強制変換するときには、SELDVLN(J)を、その数値の精度に符号および小数点のために2を加えた長さに設定してください。また、NUMBER型の数値をCOBOLの浮動小数点数に強制変換するときには、SELDVLN(J)を、使用しているシステムでの適切な浮動小数点型の長さに設定してください。

強制変換するデータ型の長さの詳細は、「データの交換」を参照してください。

バインド記述子の場合

OPENコマンドを発行する前に、バインド記述子の長さを設定する必要があります。たとえば、次の文を使用して、ユーザーが入力したバインド変数文字列の長さを設定できます。

PROCEDURE DIVISION.
...
PERFORM GET-INPUT-VAR
VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN BNDDSC.
...
GET-INPUT-VAR.
DISPLAY "Enter value of ", BND-DH-VNAME(J).
ACCEPT INPUT-STRING.
UNSTRING INPUT-STRING DELIMITED BY "  "
INTO BND-DV(J) COUNT IN BNDDVLN(J).

Oracleは、SELDV(J)またはBNDDV(J)に格納されているアドレスを使用して間接的にデータ・バッファにアクセスするため、データ・バッファ内の値の長さは認識しません。J番目の選択リスト値またはバインド変数値に対してOracleが使用する長さを変更する場合は、SELDVLN(J)またはBNDDVLN(J)を必要な長さに再設定してください。入力バッファまたは出力バッファにはそれぞれ異なる長さを指定できます。

SELDFMTL | BNDDFMTL

これは、選択リストまたはバインド変数の変換フォーマット文字列の長さの表です。現在は、COBOLのパック10進数にのみ使用できます。

フォーマット文字列の使用はオプションです。J番目の選択リスト項目に変換形式を使用する場合は、FETCHの前に、SELDFMTL(J)をSEL-DFMTに格納されているパック10進形式の長さに設定します。J番目のバインド変数に変換形式を使用する場合は、OPENの前に、BNDDFMTL(J)をBND-DFMTに格納されているパック10進形式の長さに設定します。変換形式を使用しない場合は、SELDFMTL(J)またはBNDDFMTL(J)を0(ゼロ)に設定してください。

SELDFMTL(J)の値が0 (ゼロ)の場合は、SELDFMT(J)は使用されません。同様に、BNDDFMTL(J)の値が0 (ゼロ)の場合は、BNDDFMT(J)は使用されません。

SELDVTYP | BNDDVTYP

SELDVTYP | BNDDVTYP表は、選択リスト値またはバインド変数値のデータ型コードの表です。データ型コードによって、SELDVの要素でアドレス指定されたデータ・バッファに格納されたときに、Oracleのデータがどのように変換されるかが決定されます。データ型記述子表の詳細は、「データの変換」を参照してください。

選択記述子の場合

DESCRIBE SELECT LISTにより、この表は、選択リスト項目の内部データ型(VARCHAR2、CHAR、NUMBER、DATEなど)に設定されます。

データ型の内部形式は処理が難しいため、FETCHを実行する前にデータ型を再設定することをお薦めします。表示用には、選択リスト値のデータ型をVARCHAR2に強制変換するのが一般的です。計算用には、数値をOracleからCOBOL書式に強制変換できます。「データ型の強制変換」を参照してください。

SELDVTYP(J)の上位ビットは、J番目の選択リスト列のNULL/NOT NULL状態を示します。OPENコマンドまたはFETCHコマンドを発行する前に、常にこのビットを消去する必要があります。ライブラリ・ルーチンSQLNULを使用して、データ型コードを取り出し、NULL/NOT NULLビットを消去します。詳細は、「NULLまたはNot NULLデータ型の処理」を参照してください。

NUMBER内部データ型は、SELDV(J)でアドレス指定されたCOBOLデータ・バッファの外部データ型と互換性のある外部データ型に変更することをお薦めします。

バインド記述子の場合

DESCRIBE BIND VARIABLESは、この表を0 (ゼロ)に設定します。OPENコマンドを発行する前に、このデータ型の表を再設定する必要があります。コードは、BNDDV(J)でアドレス指定されたバッファの外部(COBOL)データ型を表します。多くの場合、バインド変数値は文字列に格納されるので、データ型表の要素は1 (VARCHAR2データ型コード)に設定されます。

J番目の選択リスト値またはバインド変数値のデータ型を変更するには、SELDVTYP(J)またはBNDDVTYP(J)を希望するデータ型に再設定してください。

SELDI | BNDDI

SELDI | BNDDI表は、標識変数の値を格納するデータ・バッファのアドレスの表です。SELDIまたはBNDDIの要素は、SQLADRを使用して設定する必要があります。

選択記述子の場合

この表は、FETCHコマンドを発行する前に設定する必要があります。次の文を実行するとします。

EXEC SQL FETCH ... USING DESCRIPTOR ...

戻された選択リストのJ番目の値がNULLの場合は、SELDI(J)でアドレス指定されたバッファが-1に設定されます。それ以外の場合は、(値がNULLでない) 0または(値が切り捨てられている)正の整数に設定されます。

バインド記述子の場合

OPENコマンドを実行する前にこの表を初期化し、対応する標識変数を設定する必要があります。次の文を実行するとします。

EXEC SQL OPEN ... USING DESCRIPTOR ...

BNDDI(J)でアドレス指定されたバッファによって、J番目のバインド変数がNULLかどうかがわかります。標識変数の値が-1の場合、対応するバインド変数はNULLです。

SELDH-VNAME | BNDDH-VNAME

SELDH-VNAME | BNDDH-VNAME表は、動的SQL文に表示される選択リストまたはプレースホルダの名前を格納するデータ・バッファのアドレスの表です。SELDH-VNAMEまたはBNDDH-VNAMEの要素は、DESCRIBEコマンドを発行する前にSQLADRを使用して設定する必要があります。

DESCRIBEは、J番目の選択リスト項目またはプレースホルダの名前をSELDH-VNAME(J)またはBNDDH-VNAME(J)でアドレス指定されたデータ・バッファに格納するように、Oracleに指示します。Oracleは、J番目の選択リストまたはプレースホルダの名前をSEL-DH-VNAME(J)またはBND-DH-VNAME(J)に格納します。

注意:
SELDH-VNAME | BNDDH-VNAME表は列名のみを格納します。SQL文中で指定した場合でも、表修飾子付きの列名は格納しません。たとえば、SQL文select a.owner from all_tablesで選択リストの記述を行うと、not a.ownerではなくownerが戻されます。必要に応じて列別名を使用して、選択リストの列が正しく識別されるようにします。

SELDH-MAX-VNAMEL | BNDDH-MAX-VNAMEL

SELDH-MAX-VNAMEL | BNDDH-MAX-VNAMEL表は、選択リストまたはプレースホルダの名前を格納するデータ・バッファの最大長の表です。バッファはSELDH-VNAMEまたはBNDDH-VNAMEの要素によってアドレス指定されます。

SELDH-MAX-VNAMELまたはBNDDH-MAX-VNAMELの要素は、DESCRIBEコマンドを発行する前に設定する必要があります。選択リスト名のバッファまたはプレースホルダ名のバッファは、それぞれ長さが異なっていてもかまいません。

SELDH-CUR-VNAMEL | BNDDH-CUR-VNAMEL

SELDH-CUR-VNAMEL | BNDDH-CUR-VNAMEL表は、選択リストまたはプレースホルダの実際の長さの表です。DESCRIBEはこの表を、各選択リスト名またはプレースホルダ名の文字数に設定します。

SELDI-VNAME | BNDDI-VNAME

SELDI-VNAME | BNDDI-VNAME表は、標識変数の値を格納するデータ・バッファのアドレスの表です。

標識変数の値は、選択リスト項目およびバインド変数と対応付けできます。ただし標識変数の名前は、バインド変数のみに対応付けることができます。この表はバインド記述子でのみ使用できます。BNDDI-VNAMEの要素は、DESCRIBEコマンドを発行する前にSQLADRを使用して設定する必要があります。

DESCRIBE BIND VARIABLESは、標識変数名をBNDDI-VNAME(1)からBNDDI-VNAME(SQLDNUM)でアドレス指定されたデータ・バッファに格納するように、Oracleに指示します。Oracleは、J番目の標識変数名をBND-DI-VNAME(J)に格納します。

SELDI-MAX-VNAMEL | BNDDI-MAX-VNAMEL

SELDI-MAX-VNAMEL | BNDDI-MAX-VNAMEL表は、標識変数名を格納するデータ・バッファの最大長の表です。バッファは、SELDI-VNAMEまたはBNDDI-VNAMEの要素によってアドレス指定されます。

標識変数名はバインド変数にのみ対応付けできます。この表はバインド記述子でのみ使用できます。

要素BNDDI-MAX-VNAMEL(1)からBNDDI-MAX-VNAMEL(SQLDNUM)は、DESCRIBEコマンドの発行前に設定する必要があります。標識変数名のバッファは、それぞれ長さが異なっていてもかまいません。

SELDI-CUR-VNAMEL | BNDDI-CUR-VNAMEL

SELDI-CUR-VNAMEL | BNDDI-CUR-VNAMEL表は、標識変数名の実際の長さの表です。標識変数名はバインド変数にのみ対応付けできます。この表はバインド記述子でのみ使用できます。

DESCRIBE BIND VARIABLESは、この表を、各標識変数名の文字数に設定します。

SELDFCLP | BNDDFCLP

SELDFCLP | BNDDFCLPは、将来の使用のために確保されている表です。Oracleはグループ項目SELDSCまたはBNDDSCが特定のサイズであるとみなすため、この表が必要となります。現在はSELDFCLPおよびBNDDFCLPの要素を0 (ゼロ)に設定する必要があります。

SELDFCRCP | BNDDFCRCP

SELDFCRCP | BNDDFCRCPは、将来の使用のために確保されている表です。Oracleはグループ項目SELDSCまたはBNDDSCが特定のサイズであるとみなすため、この表が必要となります。現在はSELDFCRCPおよびBNDDFCRCPの要素を0 (ゼロ)に設定する必要があります。

前提知識

動的SQL方法4を実装するには次の処理についての知識が必要です。

- ライブラリ・ルーチンSQLADRの使用

- データの変換

- データ型の強制変換

- NULLまたはNOT NULLデータ型の処理

SQLADRの使用

入力値および出力値を格納するデータ・バッファのアドレスを取得するには、ライブラリ・サブルーチンSQLADRをコールする必要があります。取得したアドレスをバインドSQLDAまたは選択SQLDAに格納すると、Oracleはバインド変数値の読取り元や選択リスト値の書込み先を認識できるようになります。

次の構文で、SQLADRをコールします。

CALL "SQLADR" USING BUFFER, ADDRESS.

パラメータは次のとおりです。

BUFFER

選択リスト項目、バインド変数または標識変数の値または名前を格納するデータ・バッファ。

ADDRESS

データ・バッファのアドレスを戻す整変数。

SQLADRをコールすると、BUFFERのアドレスがADDRESSに格納されます。次の例では、SQLADRを使用して、選択記述子表SELDV、SELDH-VNAME、SELDIを初期化します。これらの表の要素によって、選択リスト値、選択リスト名、インジケータ値のデータ・バッファのアドレスが指定されます。

PROCEDURE DIVISION.
...
PERFORM INIT-SELDSC
VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN SELDSC.
...
INIT-SELDSC.
CALL "SQLADR" USING SEL-DV(J), SELDV(J).
CALL "SQLADR" USING SEL-DH-VNAME(J), SELDH-VNAME(J).
CALL "SQLADR" USING SEL-DI(J), SELDI(J).

データの変換

この項では、データ型記述子表を詳しく説明します。データ型の同値化も動的SQL方法4も使用しないホスト・プログラムでは、内部データ型と外部データ型の間の変換はプリコンパイル時に決定されます。デフォルトでは、Pro*COBOLによって各ホスト変数に特定の外部データ型が割り当てられます。たとえば、型PIC S9(n) COMPのホスト変数にはINTEGER外部データ型がPro*COBOLにより割り当てられます。

しかし方法4を使用すると、データの変換および形式を制御できます。変換の指定は、データ型記述子表のデータ型コードを設定して行います。

内部データ型

内部データ型により、Oracleが疑似列値の表現のためにデータベース表に列値を格納する際の形式が指定されます。

DESCRIBE SELECT LISTコマンドを発行すると、Oracleは各選択リスト項目の内部データ型コードをSELDVTYP (データ型)記述子表に戻します。たとえば、J番目の選択リスト項目のデータ型コードはSELDVTYP(J)に戻されます。

表11-1は、内部のデータ型およびそのコードを示しています。

表11-1 内部のデータ型および関連コード

内部データ型

コード

VARCHAR2

NUMBER

LONG

ROWID

DATE

RAW

LONG RAW

CHAR

1

2

8

11

12

23

24

96

外部データ型

外部データ型には、入力ホスト変数および出力ホスト変数に値を格納するのに使用する形式を指定します。

DESCRIBE BIND VARIABLESコマンドは、データ型コードのBNDDVTYP表を0 (ゼロ)に設定します。このため、OPENコマンドを発行する前にそれらのコードを再設定する必要があります。データ型コードは、様々なバインド変数にどの外部データ型が使用されるかをOracleに知らせます。J番目のバインド変数の外部データ型を指定するには、BNDDVTYP(J)を希望する外部データ型に再設定してください。

次の表は、外部データ型とそのコード、および対応するCOBOLデータ型を示したものです。

表11-2 Oracleの外部データ型および関連するCOBOLデータ型

名前

コード

COBOLデータ型

VARCHAR2

1

PIC X(n)(MODE=ANSIの場合)

NUMBER

2

PIC X(n)

INTEGER

3

PIC S9(n) COMP

(SPARC Solaris 64ビット・プラットフォームでは、COMP5ではなく、COMPを使用します。)

PIC S9(n) COMP5

(バイトスワップ・プラットフォームの場合はCOMP5)

FLOAT

4

COMP-1

COMP-2

STRING (1)

5

PIC X(n)

VARNUM

6

PIC X(n)

DECIMAL

7

PIC S9(n)V9(n) COMP-3

LONG

8

PIC X(n)

VARCHAR(2)

9

PIC X(n) VARYING

PIC N(n) VARYING

ROWID

11

PIC X(n)

DATE

12

PIC X(n)

VARRAW(2)

15

PIC X(n)

RAW

23

PIC X(n)

LONG RAW

24

PIC X(n)

UNSIGNED

68

(サポートされていません)

DISPLAY

91

PIC S9...9V9...9 DISPLAY SIGN LEADING SEPARATE

PIC S9(n)V9(n) DISPLAY SIGN LEADING SEPARATE

LONG VARCHAR(2)

94

PIC X(n)

LONG VARRAW(2)

95

PIC X(n)

CHARF

96

PIC X(n)(MODE=ANSIの場合)

PIC N(n)(MODE=ANSIの場合)

CHARZ(1)

97

PIC X(n)

CURSOR

102

SQL-CURSOR

注意:

1. EXEC SQL VAR文でのみ使用します。

2. nバイトの長さフィールドを含みます。

データ型およびその書式の詳細は、「Oracle Databaseのデータ型」を参照してください。

PL/SQLのデータ型

PL/SQLでは、各種の事前定義済スカラー・データ型および複合データ型を使用できます。スカラー型には内部コンポーネントはありません。複合型には、個々に操作できる内部コンポーネントがあります。表11-4は、事前定義済のPL/SQLのスカラー・データ型およびそれに相当する内部データ型を示しています。

表11-3 PL/SQLのデータ型とそれに相当する内部データ型

PL/SQLデータ型

Oracle内部データ型

VARCHAR

VARCHAR2

VARCHAR2

BINARY_INTEGER

DEC

DECIMAL

DOUBLE PRECISION

FLOAT

INT

INTEGER

NATURAL

NUMBER

NUMERIC

POSITIVE

REAL

SMALLINT

NUMBER

LONG

LONG

ROWID

ROWID

DATE

DATE

RAW

RAW

LONG RAW

LONG RAW

CHAR

CHARACTER

STRING

CHAR

データ型の強制変換

選択記述子の場合、DESCRIBE SELECT LISTはいずれの内部データ型も戻すことができます。文字データの場合など、ほとんどの場合内部データ型は適切な外部データ型と正確に対応しています。ただし、内部データ型には扱いにくい外部データ型にマップするものもあります。このため、SELDVTYP記述子表の要素の中には再設定が必要なものもあります。

たとえば、NUMBER値をFLOAT値(これはCOBOLのPIC S9(n)V9(n) COMP-1値に対応)に再設定します。Oracleは、内部データ型と外部データ型の間の必要な変換をFETCH時に行います。データ型の再設定は必ずDESCRIBE SELECT LISTの後、FETCHの前に行ってください。

バインド記述子の場合は、DESCRIBE BIND VARIABLESによってバインド変数のデータ型が戻されることはなく、バインド変数の数および名前のみ戻されます。したがって、データ型コードのBNDDVTYP表を明示的に設定して、各バインド変数の外部データ型をOracleに認識させる必要があります。Oracleは、内部データ型と外部データ型の間の必要な変換をOPEN時に行います。

SELDVTYPまたはBNDDVTYPの記述子表でデータ型コードをリセットするときに、データ型を強制変換します。たとえば、J番目の選択リスト値をVARCHAR2に強制変換するには、次の文を使用します。

*    Coerce select-list value to VARCHAR2.
MOVE 1 TO SELDVTYP(J).

表示を目的としてNUMBER選択リスト値をVARCHAR2に強制変換する場合は、その値の精度および位取りのバイトを抽出し、その情報を使用して最大表示長を算出する必要があります。その後、FETCHを行う前にSELDVLN (長さ)記述子表の該当する要素を再設定して、使用するバッファの長さをOracleに認識させる必要があります。J番目の選択リスト値の長さを指定するには、SELDVLN(J)を必要な長さに設定します。

たとえば、DESCRIBE SELECT LISTでJ番目の選択リスト項目の型がNUMBERであるとわかった場合、戻り値をPIC S9(n)V9(n) COMP-1として宣言したCOBOL変数に格納するには、SELDVTYP(J)を4に設定し、SELDVLN(J)をシステムが定めるCOMP-1数値の長さに設定します。

例外

DESCRIBE SELECT LISTによって戻される内部データ型が、目的に合わない場合もあります。DATE型およびNUMBER型がその例です。DATE選択リスト項目をDESCRIBEすると、Oracleはデータ型コード12をSELDVTYP表に戻します。FETCHの前にコードを再設定しないかぎり、日付の値はその7バイト内部形式で戻されます。デフォルトの文字形式で日付を取得するには、データ型コードを12から1 (VARCHAR2)に変更して、SELDVLNの値を7から9に増やす必要があります。

同様に、NUMBER選択リスト項目をDESCRIBEすると、Oracleはデータ型コード2をSELDVTYP表に戻します。FETCHの前にコードを再設定しないかぎり、数値はその内部形式で戻されるため、求めている値と異なる可能性が高くなります。このような場合は、コードを2から1 (VARCHAR2)、3 (INTEGER)または4 (FLOAT)に変更するか、その他の適切なデータ型に変更してください。

精度および位取りの抽出

ライブラリ・サブルーチンSQLPRCにより、精度および位取りが抽出されます。このサブルーチンは通常、DESCRIBE SELECT LISTの後で使用され、その最初のパラメータはSELDVLN(J)です。次の構文で、SQLPRCをコールします。

CALL "SQLPRC" USING LENGTH, PRECISION, SCALE.

パラメータは次のとおりです。

構文

説明

LENGTH

NUMBER値の長さが格納される整変数。値の位取りおよび精度はそれぞれ、下位バイトおよびその上のバイトに格納されます。

PRECISION

NUMBER値の精度を戻す整変数。精度とは有効桁数を指します。サイズが未指定のNUMBERが選択リスト項目によって参照される場合は、precisionの値は0 (ゼロ)に設定されます。この場合、サイズが未指定なので、最大精度の38とみなされます。

SCALE

NUMBER値の位取りを戻す整変数。位取りには四捨五入する位置を指定します。たとえば、位取りが2の場合は最も近い100分の1の位に値が四捨五入され(3.456は3.46となります)、位取りが-3の場合は最も近い1000の位に値が四捨五入されます(3.456は3000となります)。

次の例に、SQLPRCを使用して、VARCHAR2に強制変換されるNUMBER値の最大表示長を算出する方法を示します。

WORKING-STORAGE SECTION.
01  PRECISION       PIC S9(9) COMP.
01  SCALE           PIC S9(9) COMP.
01  DISPLAY-LENGTH  PIC S9(9) COMP.
01  MAX-LENGTH      PIC S9(9) COMP VALUE 80.
...
PROCEDURE DIVISION.
...
PERFORM ADJUST-LENGTH
VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN SELDSC.
ADJUST-LENGTH.
*    If datatype is NUMBER, extract precision and scale.
IF SELDVTYP(J) = 2
CALL "SQLPRC" USING SELDVLN(J), PRECISION, SCALE.
MOVE 0 TO DISPLAY-LENGTH.
*    Precision is set to zero if the select-list item
*    refers to a NUMBER of unspecified size.  We allow for
*    a maximum precision of 10.
IF SELDVTYP(J) = 2 AND PRECISION = 0
MOVE 10 TO DISPLAY-LENGTH.
*    Allow for possible decimal point and sign.
IF SELDVTYP(J) = 2 AND PRECISION > 0
ADD 2 TO PRECISION
MOVE PRECISION TO DISPLAY-LENGTH.
...

このサブルーチン・コールの最初のパラメータは、選択リストの長さの表のJ番目の要素になるので注意してください。

SQLPRCプロシージャ(これはSQLLIBランタイム・ライブラリで定義されています)により、特定のSQLデータ型については精度および位取りの値として0 (ゼロ)が戻されます。SQLPR2プロシージャは、この表に示すデータ型を除けば、同じ構文で同じバイナリ値を戻すという点でSQLPRCに似ています。

表11-4 SQLPR2プロシージャのデータ型の例外

SQLデータ型

2進数精度

2進数位取り

FLOAT

126

-127

FLOAT(n)

n(1から126)

-127

REAL

63

-127

DOUBLE PRECISION

126

-127

NULLまたはNOT NULLデータ型の処理

すべての選択リスト列(式は不可)について、DESCRIBE SELECT LISTは選択記述子のデータ型表にNULL/NOT NULLインジケータを戻します。J番目の選択リスト列にNOT NULL制約が指定されていると、SELDVTYP(J)データ型変数の上位ビットはオフにされます。それ以外の場合は上位ビットが設定されます。

NULLステータス・ビットがセットされている場合、OPEN文またはFETCH文でデータ型を使用する前に消去する必要があります。このビットはセットしないでください。

ライブラリ・ルーチンSQLNULを使用して、列にNULLデータ型を使用できるかどうかを調べたり、そのデータ型のNULLステータス・ビットを消去できます。次の構文で、SQLNULをコールします。

CALL "SQLNUL" USING VALUE-TYPE, TYPE-CODE, NULL-STATUS.

パラメータは次のとおりです。

構文

説明

VALUE-TYPE

選択リスト列のデータ型コードを戻す2バイトの整変数。

TYPE-CODE

選択リスト列のデータ型コードを戻す2バイトの整変数。上位ビットは消去されます。

NULL-STATUS

選択リスト列のNULL状態を戻す整変数。1は列がNULLを許可し、0は許可しないことを意味します。

次の例は、SQLNULの使用方法を示したものです。

WORKING-STORAGE SECTION.
...
*    Declare variable for subroutine call.
01  NULL-STATUS  PIC S9(9) COMP.
...
PROCEDURE DIVISION.
MAIN.
EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC.
...
PERFORM HANDLE-NULLS
VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN SELDSC.
...
HANDLE-NULLS.
*    Find out if column is NOT NULL, and clear high-order bit.
CALL "SQLNUL" USING SELDVTYP(J), SELDVTYP(J), NULL-STATUS.
*    If NULL-STATUS = 1, NULLs are allowed.

このサブルーチン・コールの最初のパラメータと2番目のパラメータが同じことに注意してください。この2つのパラメータはそれぞれ、NULLステータス・ビットが消去される前と後のデータ型変数です。

基本手順

方法4は任意の動的SQL文に使用できます。「方法4でのホスト表の使用」の例では、入力ホスト変数および出力ホスト変数をどのように扱うかわかるように問合せが処理されています。

このサンプル・プログラムでは次の手順に従って動的問合せを処理します。

1. 問合せテキストを保存するためのホスト文字列を宣言します。

2. 選択記述子およびバインド記述子を宣言します。

3. DESCRIBEできる選択リスト項目およびプレースホルダの最大数を設定します。

4. 選択記述子およびバインド記述子を初期化します。

5. 問合せテキストをホスト文字列に格納します。

6. ホスト文字列から問合せをPREPAREします。

7. 問合せ用のカーソルをDECLAREします。

8. バインド記述子にバインド変数をDESCRIBEします。

9. プレースホルダの数を、DESCRIBEで実際に検出された数に再設定します。

10. DESCRIBEで検出されたバインド変数の値を取得します。

11. バインド記述子を使用してカーソルをOPENします。

12. 選択記述子に選択リストをDESCRIBEします。

13. 選択リスト項目の最大数をDESCRIBEにより実際に検出された数に再設定します。

14. 表示用にそれぞれの選択リスト項目の長さおよびデータ型を再設定します。

15. 選択記述子を使用してデータベースからデータ・バッファに行をFETCH INTOします。

16. FETCHにより戻された選択リストの値を処理します。

17. FETCHする行がなくなった場合カーソルをCLOSEします。

注意:
動的SQL文が問合せではない場合、または個数がわかっている選択リスト項目またはプレースホルダを含む場合は、前述の一部のステップは必要ありません。

各手順の詳細

この項では、個々のステップを詳しく説明します。方法4の完全なサンプル・プログラムをこの章の最後に示します。方法4では、埋込みSQL文を次のような順序で使用します。

EXEC SQL
PREPARE <statement_name>
FROM {:<host_string> | <string_literal>}
END-EXEC.
EXEC SQL
DECLARE <cursor_name> CURSOR FOR <statement_name>
END-EXEC.
EXEC SQL
DESCRIBE BIND VARIABLES FOR <statement_name>
INTO <bind_descriptor_name>
END-EXEC.
EXEC SQL
OPEN <cursor_name>
[USING DESCRIPTOR <bind_descriptor_name>]
END-EXEC.
EXEC SQL
DESCRIBE [SELECT LIST FOR] <statement_name>
INTO <select_descriptor_name>
END-EXEC.
EXEC SQL
FETCH <cursor_name> USING DESCRIPTOR <select_descriptor_name>
END-EXEC.
EXEC SQL
CLOSE <cursor_name>
END-EXEC.

動的問合せの選択リスト項目の数がわかっているときは、DESCRIBE SELECT LISTを省略するとともに次の方法3のFETCH文を使用できます。

EXEC SQL FETCH <cursor_name> INTO <host_variable_list> END-EXEC.

また、動的SQL文中のバインド変数のプレースホルダの数がわかっている場合は、DESCRIBE BIND VARIABLESを使用せずに、次に示す方法3のOPEN文を使用できます。

EXEC SQL OPEN <cursor_name> [USING <host_variable_list>] END-EXEC.

次の項では、これらの文により、記述子を使用してホスト・プログラムで動的SQL文を受け入れ、それを処理する方法を説明します。

注意:
以降では、図を使用して説明します。図が複雑になるのを避けるため、記述子表の要素は3つまで、名前および値の最大長はそれぞれ5文字と10文字に制限しました。

ホスト文字列の宣言

プログラムには、動的SQL文のテキストを格納するためのホスト変数が必要です。このホスト変数(例ではSELECTSTMT)は、文字列として宣言する必要があります。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01  SELECTSTMT  PIC X(120).
EXEC SQL END DECLARE SECTION END-EXEC.

SQLDAの宣言

例では、問合せの選択リスト項目またはプレースホルダの数が不明な場合があるため、選択記述子およびバインド記述子を宣言する必要があります。SQLDAをハードコードするかわりに、次のように、INCLUDEを使用してSQLDAをプログラムにコピーします。

EXEC SQL INCLUDE SELDSC END-EXEC.
EXEC SQL INCLUDE BNDDSC END-EXEC.

参考のため、INCLUDEされるSELDSCの宣言を次に示します。

WORKING-STORAGE SECTION.
...
01  SELDSC.
05  SQLDNUM              PIC S9(9) COMP.
05  SQLDFND              PIC S9(9) COMP.
05  SELDVAR              OCCURS 3 TIMES.
10 SELDV             PIC S9(9) COMP.
10 SELDFMT           PIC S9(9) COMP.
10 SELDVLN           PIC S9(9) COMP.
10 SELDFMTL          PIC S9(4) COMP.
10 SELDVTYP          PIC S9(4) COMP.
10 SELDI             PIC S9(9) COMP.
10 SELDH-VNAME       PIC S9(9) COMP.
10 SELDH-MAX-VNAMEL  PIC S9(4) COMP.
10 SELDH-CUR-VNAMEL  PIC S9(4) COMP.
10 SELDI-VNAME       PIC S9(9) COMP.
10 SELDI-MAX-VNAMEL  PIC S9(4) COMP.
10 SELDI-CUR-VNAMEL  PIC S9(4) COMP.
10 SELDFCLP          PIC S9(9) COMP.
10 SELDFCRCP         PIC S9(9) COMP.

01  XSELDI.
05  SEL-DI        OCCURS 3 TIMES PIC S9(9) COMP.
01  XSELDIVNAME.
05  SEL-DI-VNAME  OCCURS 3 TIMES PIC X(5).
01  XSELDV.
05  SEL-DV        OCCURS 3 TIMES PIC X(10).
01  XSELDHVNAME.
05  SEL-DH-VNAME  OCCURS 3 TIMES PIC X(5).

DESCRIBEへの最大数の設定

次に、記述できる選択リスト項目またはプレースホルダの最大数を設定します。

MOVE 3 TO SQLDNUM IN SELDSC.
MOVE 3 TO SQLDNUM IN BNDDSC.

記述子の初期化

初期化を必要とする記述子変数もあります。また、初期化にライブラリ・サブルーチンSQLADRが必要なものもあります。

例では、名前バッファの最大長がSELDH-MAX-VNAMEL表、BNDDH-MAX-VNAMELおよびBNDDI-MAX-VNAMEL表に格納され、SQLADRを使用して値バッファおよび名前バッファのアドレスが表SELDV、SELDI、BNDDV、BNDDI、SELDH-VNAME、BNDDH-VNAMEおよびBNDDI-VNAMEに格納されています。

PROCEDURE DIVISION.
...
PERFORM INIT-SELDSC
VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN SELDSC.
PERFORM INIT-BNDDSC
VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN BNDDSC.
...
INIT-SELDSC.
MOVE SPACES TO SEL-DV(J).
MOVE SPACES TO SEL-DH-VNAME(J).
MOVE 5 TO SELDH-MAX-VNAMEL(J).
CALL "SQLADR" USING SEL-DV(J), SELDV(J).
CALL "SQLADR" USING SEL-DH-VNAME(J), SELDH-VNAME(J).
CALL "SQLADR" USING SEL-DI(J), SELDI(J).
...
INIT-BNDDSC.
MOVE SPACES TO BND-DV(J).
MOVE SPACES TO BND-DH-VNAME(J).
MOVE SPACES TO BND-DI-VNAME(J).
MOVE 5 TO BNDDH-MAX-VNAMEL(J).
MOVE 5 TO BNDDI-MAX-VNAMEL(J).
CALL "SQLADR" USING BND-DV(J), BNDDV(J).
CALL "SQLADR" USING BND-DH-VNAME(J), BNDDH-VNAME(J).
CALL "SQLADR" USING BND-DI(J), BNDDI(J).
CALL "SQLADR" USING BND-DI-VNAME(J), BNDDI-VNAME(J).
...

図11-3と図11-4に、結果として得られる記述子を示します。

図11-3 初期化した選択記述子

図11-4 初期化したバインド記述子

ホスト文字列への問合せテキストの格納

次に、ユーザーにSQL文の入力を要求し、入力された文字列をSELECTSTMTに格納します。

DISPLAY "Enter a SELECT statement: " WITH NO ADVANCING.
ACCEPT SELECTSTMT.

このときユーザーが次の文字列を入力したと仮定します。

SELECT ENAME, EMPNO, COMM FROM EMP WHERE COMM < :BONUS

ホスト文字列からの問合せのPREPARE

PREPAREは、このSQL文を解析して名前を指定します。例では、PREPAREでホスト文字列SELECTSTMTを解析し、SQLSTMTの名前を付けます。

EXEC SQL PREPARE SQLSTMT FROM :SELECTSTMT END-EXEC.

カーソルの宣言

DECLARE CURSORは名前を指定し、特定のSELECT文に対応付けることにより、カーソルを定義します。

静的問合せ用のカーソルを宣言するには次の構文を使用します。

EXEC SQL DECLARE cursor_name CURSOR FOR SELECT ...

動的問合せ用にカーソルを宣言するには、PREPAREにより動的問合せに指定された文の名前で静的問合せを置換します。例では、次に示すように、DECLARE CURSORはEMPCURSORの名前のカーソルを定義し、それをSQLSTMTと対応付けます。

EXEC SQL DECLARE EMPCURSOR CURSOR FOR SQLSTMT END-EXEC.

注意:
問合せのみでなく、すべての動的SQL文にカーソルを宣言する必要があります。また、問合せ以外の場合も、カーソルのOPENにより動的SQL文を実行します。

バインド変数のDESCRIBE

DESCRIBE BIND VARIABLESは、バインド変数の記述をバインド記述子に格納します。例では、DESCRIBEでBNDDSCを準備します。

EXEC SQL
DESCRIBE BIND VARIABLES FOR SQLSTMT
INTO BNDDSC
END-EXEC.

BNDDSCの前にはコロンを付けないでください。

DESCRIBE BIND VARIABLES文はPREPARE文の後で、かつOPEN文の前に指定する必要があります。

図11-5に、DESCRIBE実行後のバインド記述子の例を示します。DESCRIBEにより、処理対象のSQL文で検出されたプレースホルダの実際の数に、SQLDFNDが設定されていることに注意してください。

図11-5 DESCRIBE実行後のバインド記述子

プレースホルダの数の再設定

次に、プレースホルダの最大数を、DESCRIBEで実際に検出された数に再設定する必要があります。

IF SQLDFND IN BNDDSC < 0
DISPLAY "Too many bind variables"
GOTO ROLL-BACK
ELSE
MOVE SQLDFND IN BNDDSC TO SQLDNUM IN BNDDSC
END-IF.

バインド変数の値の取得

プログラムはSQL文中のバインド変数の値を取得する必要があります。値はどのように取得してもかまいません。たとえば値をハードコードしたり、ファイルから読み込むことや対話形式で入力することもできます。

例では、問合せのWHERE句のプレースホルダBONUSに置き換わるバインド変数に値を代入する必要があります。次のように、ユーザーに値の入力を求め、入力された値を処理します。

PROCEDURE DIVISION.
...
PERFORM GET-INPUT-VAR
VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN BNDDSC.
...
GET-INPUT-VAR.
...
*    Replace the 0 DESCRIBEd into the datatype table
*    with a 1 to avoid an "invalid datatype" Oracle error.
MOVE 1 TO BNDDVTYP(J).
*    Get value of bind variable.
DISPLAY "Enter value of ", BND-DH-VNAME(J).
ACCEPT INPUT-STRING.
UNSTRING INPUT-STRING DELIMITED BY "  "
INTO BND-DV(J) COUNT IN BNDDVLN(J).

ここでは、ユーザーがBONUSの値として625を入力したとして、次の表に結果として得られるバインド記述子を示します。

図11-6 値を割り当てた後のバインド記述子

カーソルのOPEN

動的問合せのOPEN文は、カーソルがバインド記述子に対応付けられることを除けば、静的問合せのOPEN文と同じです。実行時に決定され、バインド記述子表の要素でアドレス指定されたバッファに格納された値を使用して、SQL文を評価します。問合せの場合は、アクティブ・セットの識別にも同じ値を使用します。

例では、OPENがEMPCURSORをBNDDSCに対応付けています。

EXEC SQL
OPEN EMPCUR USING DESCRIPTOR BNDDSC
END-EXEC.

BNDDSCの前にはコロンを付けないでください。

OPENはSQL文を実行します。問合せのときは、OPENはアクティブ・セットを決定するとともにカーソルを先頭行に位置づけます。

選択リストのDESCRIBE

動的SQL文が問合せのときは、DESCRIBE SELECT LIST文はOPEN文の後で、かつFETCH文の前に指定する必要があります。

DESCRIBE SELECT LISTは、選択リスト項目の記述を選択記述子に格納します。例では、DESCRIBEによってSELDSCを準備しています。

EXEC SQL
DESCRIBE SELECT LIST FOR SQLSTMT INTO SELDSC
END-EXEC.

DESCRIBEは、データ・ディクショナリにアクセスして、各選択リスト値の長さおよびデータ型を設定します。

図11-7に、DESCRIBE実行後の選択記述子の例を示します。DESCRIBEにより、問合せの選択リストで実際に検出された項目の数に、SQLDFNDが設定されていることに注意してください。SQL文が問合せではない場合は、SQLDFNDは0 (ゼロ)に設定されます。また、NUMBER型の長さはまだ使用できないことに注意してください。NUMBERとして定義された列については、ライブラリ・サブルーチンSQLPRCを使用して精度および位取りを抽出する必要があります。「データ型の強制変換」を参照してください。

図11-7 DESCR実行後の選択記述子

選択リスト項目の最大数の再設定

次に選択リスト項目の最大数を、DESCRIBEにより実際に検出された数に再設定する必要があります。

MOVE SQLDFND IN SELDSC TO SQLDNUM IN SELDSC.

各選択リスト項目の長さおよびデータ型の再設定

例では、選択リストの値をフェッチする前に、長さおよびデータ型の表の要素の一部を表示するために再設定します。

PROCEDURE DIVISION.
...
PERFORM COERCE-COLUMN-TYPE
VARYING J FROM 1 BY 1 UNTIL J > SQLDNUM IN SELDSC.
...
COERCE-COLUMN-TYPE.
*    Clear NULL bit.
CALL "SQLNUL" USING SELDVTYP(J), SELDVTYP(J), NULL-STATUS.

*    If datatype is DATE, lengthen to 9 characters.
IF SELDVTYP(J) = 12
MOVE 9 TO SELDVLN(J).

*    If datatype is NUMBER, extract precision and scale.
MOVE 0 TO DISPLAY-LENGTH.
IF SELDVTYP(J) = 2 AND PRECISION = 0
MOVE 10 TO DISPLAY-LENGTH.
IF SELDVTYP(J) = 2 AND PRECISION > 0
ADD 2 TO PRECISION
MOVE PRECISION TO DISPLAY-LENGTH.
IF SELDVTYP(J) = 2
IF DISPLAY-LENGTH > MAX-LENGTH
DISPLAY "Column value too large for data buffer."
GO TO END-PROGRAM
ELSE
MOVE DISPLAY-LENGTH TO SELDVLN(J).

*    Coerce datatypes to VARCHAR2.
MOVE 1 TO SELDVTYP(J).

図11-8に、結果として得られる選択記述子を示します。NUMBERの長さが使用でき、すべてのデータ型がVARCHAR2になっていることに注意してください。符号と小数点を使用できるよう、DESCRIBEした長さ4および7をそれぞれ2ずつ増加させたため、SELDVLN(2)およびSELDVLN(3)の長さが6および9になっています。

図11-8 FETCH実行前の選択記述子

アクティブ・セットからの行のFETCH

FETCHはアクティブ・セットから1行を戻し、データ・バッファに選択リストの値を格納してから、カーソルをアクティブ・セットの次の行に進めます。行がなくなると、FETCHは「データが見つかりません。」のエラー・コードをSQLCAのSQLCODE、SQLCODE変数、またはSQLSTATE変数に設定します。次の例では、FETCHはENAME列、EMPNO列、およびCOMM列からSELDSC列の値を戻します。

EXEC SQL
FETCH EMPCURSOR USING DESCRIPTOR SELDSC
END-EXEC.

図11-9に、FETCH実行後の選択記述子の例を示します。Oracleが、SELDVおよびSELDIの要素によってアドレス指定されたデータ・バッファに、選択リストおよびインジケータの値を格納していることに注意してください。

データ型1の出力バッファの場合、OracleはSELDVLNに格納されている長さを使用して、CHARデータまたはVARCHAR2データは左揃えにし、NUMBERデータは右揃えにします。

値MARTINは、EMP表のVARCHAR2(10)列から取り出されました。Oracleは、SELDVLN(1)に格納された長さを使用して、この値を10バイトのフィールドに左揃えにして入れ、バッファの残りの部分を埋めます。

値7654はNUMBER(4)列から取り出され、7654に強制変換されています。しかし、SELDVLN(2)の長さが2増加して符号および小数点を使用できるようになっているため、Oracleでは6バイトのフィールドで値が右揃えになります。

値482.50はNUMBER(7,2)列から取り出され、482.50に強制変換されています。ここでも、SELDVLN(3)の長さが2増加しているため、Oracleでは9バイトのフィールドで値が右揃えになります。

選択リストの値の取得および処理

FETCHの後、プログラムはFETCHで戻された選択リストの値を処理できます。例では、列ENAME、EMPNOおよびCOMMの値が処理されます。

カーソルのCLOSE

CLOSEはカーソルを使用禁止にします。例では、CLOSEによってEMPCURSORが使用禁止になります。

EXEC SQL CLOSE EMPCURSOR END-EXEC

図11-9 FETCH実行後の選択記述子

方法4でのホスト表の使用

方法4で入力ホスト表または出力ホスト表を使用するには、オプションのFOR句を使用してホスト表のサイズをOracleに認識させる必要があります。FOR句の詳細は、第7章「ホスト表」を参照してください。

J番目の選択リスト項目またはバインド変数の記述子エントリを設定します。ただし、SELDVLN(J)またはBNDDVLN(J)は、単一のデータ・バッファをアドレス指定するのではなく、データ・バッファの表をアドレス指定します。EXECUTE文またはFETCH文のいずれか適切な方にFOR句を指定して、処理対象の表要素の数をOracleに通知する必要があります。

Oracleがホスト表のサイズを認識する方法は他にないため、このステップは必須です。

次の例(32ビットのみ)では、2つの入力ホスト表を使用して、EMPNOおよびDEPTNOの8組の値をEMP表に挿入します。方法4では、問合せ以外のSQL文に対してEXECUTEを使用できるので注意してください。

IDENTIFICATION DIVISION.
PROGRAM-ID. DYN4INS.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  BNDDSC.
02  SQLDNUM              PIC S9(9) COMP VALUE 2.
02  SQLDFND              PIC S9(9) COMP.
02  BNDDVAR              OCCURS 2 TIMES.
03 BNDDV             PIC S9(9) COMP.
03 BNDDFMT           PIC S9(9) COMP.
03 BNDDVLN           PIC S9(9) COMP.
03 BNDDFMTL          PIC S9(4) COMP.
03 BNDDVTYP          PIC S9(4) COMP.
03 BNDDI             PIC S9(9) COMP.
03 BNDDH-VNAME       PIC S9(9) COMP.
03 BNDDH-MAX-VNAMEL  PIC S9(4) COMP.
03 BNDDH-CUR-VNAMEL  PIC S9(4) COMP.
03 BNDDI-VNAME       PIC S9(9) COMP.
03 BNDDI-MAX-VNAMEL  PIC S9(4) COMP.
03 BNDDI-CUR-VNAMEL  PIC S9(4) COMP.
03 BNDDFCLP          PIC S9(9) COMP.
03 BNDDFCRCP         PIC S9(9) COMP.
01  XBNDDI.
03  BND-DI               OCCURS 2 TIMES PIC S9(4) COMP.
01  XBNDDIVNAME.
03  BND-DI-VNAME         OCCURS 2 TIMES PIC X(80).
01  XBNDDV.
*    Since you know what the SQL statement will be, you can set
*    up a two-dimensional table with a maximum of 2 columns and
*    8 rows.  Each element can be up to 10 characters long.  (You
*    can alter these values according to your needs.)
03  BND-COLUMN           OCCURS 2 TIMES.
05  BND-ELEMENT      OCCURS 8 TIMES PIC X(10).
01  XBNDDHVNAME.
03  BND-DH-VNAME         OCCURS 2 TIMES PIC X(80).
01  COLUMN-INDEX             PIC 999.
01  ROW-INDEX                PIC 999.
01  DUMMY-INTEGER            PIC 9999.
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME         PIC X(20).
01  PASSWD           PIC X(20).
01  DYN-STATEMENT    PIC X(80).
01  NUMBER-OF-ROWS   PIC S9(4) COMP.
EXEC SQL END DECLARE SECTION END-EXEC.

EXEC SQL INCLUDE SQLCA END-EXEC.

PROCEDURE DIVISION.
START-MAIN.

EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC.

MOVE "SCOTT" TO USERNAME.
MOVE "TIGER" TO PASSWD.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY "Connected to Oracle".

*    Initialize bind and select descriptors.
PERFORM INIT-BNDDSC THRU INIT-BNDDSC-EXIT
VARYING COLUMN-INDEX FROM 1 BY 1
UNTIL COLUMN-INDEX > 2.

*    Set up the SQL statement.
MOVE SPACES TO DYN-STATEMENT.
MOVE "INSERT INTO EMP(EMPNO, DEPTNO) VALUES(:EMPNO,:DEPTNO)"
TO DYN-STATEMENT.
DISPLAY DYN-STATEMENT.

*    Prepare the SQL statement.
EXEC SQL
PREPARE S1 FROM :DYN-STATEMENT
END-EXEC.

*    Describe the bind variables.
EXEC SQL
DESCRIBE BIND VARIABLES FOR S1 INTO BNDDSC
END-EXEC.

PERFORM Z-BIND-TYPE THRU Z-BIND-TYPE-EXIT
VARYING COLUMN-INDEX FROM 1 BY 1
UNTIL COLUMN-INDEX > 2.

IF SQLDFND IN BNDDSC < 0
DISPLAY "TOO MANY BIND VARIABLES."
GO TO SQL-ERROR
ELSE
DISPLAY "BIND VARS = " WITH NO ADVANCING
MOVE SQLDFND IN BNDDSC TO DUMMY-INTEGER
DISPLAY DUMMY-INTEGER
MOVE SQLDFND IN BNDDSC TO SQLDNUM IN BNDDSC.

MOVE 8 TO NUMBER-OF-ROWS.
PERFORM GET-ALL-VALUES THRU GET-ALL-VALUES-EXIT
VARYING ROW-INDEX FROM 1 BY 1
UNTIL ROW-INDEX > NUMBER-OF-ROWS.

*    Execute the SQL statement.
EXEC SQL FOR :NUMBER-OF-ROWS
EXECUTE S1 USING DESCRIPTOR BNDDSC
END-EXEC.

DISPLAY "INSERTED " WITH NO ADVANCING.
MOVE SQLERRD(3) TO DUMMY-INTEGER.
DISPLAY DUMMY-INTEGER WITH NO ADVANCING.
DISPLAY " ROWS.".
GO TO END-SQL.

SQL-ERROR.
*    Display any SQL error message and code.
DISPLAY SQLERRMC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

END-SQL.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL COMMIT WORK RELEASE END-EXEC.
STOP RUN.

INIT-BNDDSC.
*    Start of COBOL PERFORM procedures, initialize the bind
*    descriptor.
MOVE 80 TO BNDDH-MAX-VNAMEL(COLUMN-INDEX).
CALL "SQLADR" USING
BND-DH-VNAME(COLUMN-INDEX)
BNDDH-VNAME(COLUMN-INDEX).
MOVE 80 TO BNDDI-MAX-VNAMEL(COLUMN-INDEX).
CALL "SQLADR" USING
BND-DI-VNAME(COLUMN-INDEX)
BNDDI-VNAME (COLUMN-INDEX).
MOVE 10 TO BNDDVLN(COLUMN-INDEX).
CALL "SQLADR" USING
BND-ELEMENT(COLUMN-INDEX,1)
BNDDV(COLUMN-INDEX).
MOVE ZERO TO BNDDI(COLUMN-INDEX).
CALL "SQLADR" USING
BND-DI(COLUMN-INDEX)
BNDDI(COLUMN-INDEX).
MOVE ZERO TO BNDDFMT(COLUMN-INDEX).
MOVE ZERO TO BNDDFMTL(COLUMN-INDEX).
MOVE ZERO TO BNDDFCLP(COLUMN-INDEX).
MOVE ZERO TO BNDDFCRCP(COLUMN-INDEX).
INIT-BNDDSC-EXIT.
EXIT.

Z-BIND-TYPE.
*    Replace the 0s DESCRIBEd into the datatype table with 1s to
*    avoid an "invalid datatype" Oracle error.
MOVE 1 TO BNDDVTYP(COLUMN-INDEX).

Z-BIND-TYPE-EXIT.
EXIT.

GET-ALL-VALUES.
*    Get the bind variables for each row.
DISPLAY "ENTER VALUES FOR ROW NUMBER ",ROW-INDEX.
PERFORM GET-BIND-VARS
VARYING COLUMN-INDEX FROM 1 BY 1
UNTIL COLUMN-INDEX > SQLDFND IN BNDDSC.
GET-ALL-VALUES-EXIT.
EXIT.

GET-BIND-VARS.
*    Get the value of each bind variable.
DISPLAY "    ENTER VALUE FOR ",BND-DH-VNAME(COLUMN-INDEX)
WITH NO ADVANCING.
ACCEPT BND-ELEMENT(COLUMN-INDEX,ROW-INDEX).
GET-BIND-VARS-EXIT.
EXIT.

サンプル・プログラム10: 動的SQL方法4

このプログラムでは、動的SQL方法4の使用に必要な基本手順を示します。

注意:
次の例は32ビットのみです。問題を回避するには、$ORACLE_HOME/precomp/demo/procob2/sample10.pcoからの例を使用し、変数宣言ファイルの正しいバージョンを含めます。
bndsel.cob(64ビット・バージョン)は、precomp/public (64ビット・コンピュータ)にあります。

bndsel.cob_32(32ビット・バージョン)は、precomp/public32 (64ビット・コンピュータ)にあります。

ログインすると、プログラムはSQL文のユーザーの入力を求め、文の準備を行い、カーソルを宣言し、DESCRIBE BINDを使用してバインド変数のチェックを行い、選択リスト変数を記述します。入力されたSQL文が問合せのときは、プログラムは各行のデータをフェッチしてからカーソルをクローズします。

***************************************************************
* Sample Program 10: Dynamic SQL Method 4                     *
*                                                             *
* This program shows the basic steps required to use dynamic  *
* SQL Method 4.  After logging on to ORACLE, the program      *
* prompts the user for a SQL statement, PREPAREs the          *
* statement, DECLAREs a cursor, checks for any bind variables *
* using DESCRIBE BIND, OPENs the cursor, and DESCRIBEs any    *
* select-list variables.  If the input SQL statement is a     *
* query, the program FETCHes each row of data, then CLOSEs    *
* the cursor.                                                 *
***************************************************************

IDENTIFICATION DIVISION.
PROGRAM-ID.  DYNSQL4.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.

01  BNDDSC.

02  SQLDNUM               PIC S9(9) COMP VALUE 20.
02  SQLDFND               PIC S9(9) COMP.
02  BNDDVAR               OCCURS 20 TIMES.
03  BNDDV             PIC S9(9) COMP.
03  BNDDFMT           PIC S9(9) COMP.
03  BNDDVLN           PIC S9(9) COMP.
03  BNDDFMTL          PIC S9(4) COMP.
03  BNDDVTYP          PIC S9(4) COMP.
03  BNDDI             PIC S9(9) COMP.
03  BNDDH-VNAME       PIC S9(9) COMP.
03  BNDDH-MAX-VNAMEL  PIC S9(4) COMP.
03  BNDDH-CUR-VNAMEL  PIC S9(4) COMP.
03  BNDDI-VNAME       PIC S9(9) COMP.
03  BNDDI-MAX-VNAMEL  PIC S9(4) COMP.
03  BNDDI-CUR-VNAMEL  PIC S9(4) COMP.
03  BNDDFCLP          PIC S9(9) COMP.
03  BNDDFCRCP         PIC S9(9) COMP.

01  XBNDDI.

03  BND-DI                OCCURS 20 TIMES PIC S9(4) COMP.

01  XBNDDIVNAME.
03  BND-DI-VNAME          OCCURS 20 TIMES PIC X(80).
01  XBNDDV.
03  BND-DV                OCCURS 20 TIMES PIC X(80).
01  XBNDDHVNAME.
03  BND-DH-VNAME          OCCURS 20 TIMES PIC X(80).

01  SELDSC.

02  SQLDNUM               PIC S9(9) COMP VALUE 20.
02  SQLDFND               PIC S9(9) COMP.
02  SELDVAR               OCCURS 20 TIMES.
03  SELDV             PIC S9(9) COMP.
03  SELDFMT           PIC S9(9) COMP.
03  SELDVLN           PIC S9(9) COMP.
03  SELDFMTL          PIC S9(4) COMP.
03  SELDVTYP          PIC S9(4) COMP.
03  SELDI             PIC S9(9) COMP.
03  SELDH-VNAME       PIC S9(9) COMP.
03  SELDH-MAX-VNAMEL  PIC S9(4) COMP.
03  SELDH-CUR-VNAMEL  PIC S9(4) COMP.
03  SELDI-VNAME       PIC S9(9) COMP.
03  SELDI-MAX-VNAMEL  PIC S9(4) COMP.
03  SELDI-CUR-VNAMEL  PIC S9(4) COMP.
03  SELDFCLP          PIC S9(9) COMP.
03  SELDFCRCP         PIC S9(9) COMP.

01  XSELDI.

03  SEL-DI                OCCURS 20 TIMES PIC S9(4) COMP.

01  XSELDIVNAME.
03  SEL-DI-VNAME          OCCURS 20 TIMES PIC X(80).
01  XSELDV.
03  SEL-DV                OCCURS 20 TIMES PIC X(80).
01  XSELDHVNAME.
03  SEL-DH-VNAME          OCCURS 20 TIMES PIC X(80).

01  TABLE-INDEX               PIC 9(3).
01  VAR-COUNT                 PIC 9(2).
01  ROW-COUNT                 PIC 9(4).
01  NO-MORE-DATA              PIC X(1) VALUE "N".
01  NULLS-ALLOWED             PIC S9(9) COMP.

01  PRECISION                 PIC S9(9) COMP.
01  SCALE                     PIC S9(9) COMP.

01  DISPLAY-LENGTH            PIC S9(9) COMP.
01  MAX-LENGTH                PIC S9(9) COMP VALUE 80.
01  COLUMN-NAME               PIC X(30).
01  NULL-VAL                  PIC X(80) VALUE SPACES.
EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  USERNAME       PIC X(20).
01  PASSWD         PIC X(20).
01  DYN-STATEMENT  PIC X(80).
EXEC SQL END DECLARE SECTION   END-EXEC.
EXEC SQL INCLUDE SQLCA         END-EXEC.

PROCEDURE DIVISION.
START-MAIN.

EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC.

DISPLAY "USERNAME: " WITH NO ADVANCING.

ACCEPT USERNAME.

DISPLAY "PASSWORD: " WITH NO ADVANCING.

ACCEPT PASSWD.

EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWD END-EXEC.
DISPLAY "CONNECTED TO ORACLE AS USER: ", USERNAME.

*    INITIALIZE THE BIND AND SELECT DESCRIPTORS.

PERFORM INIT-BNDDSC
VARYING TABLE-INDEX FROM 1 BY 1
UNTIL TABLE-INDEX > 20.

PERFORM INIT-SELDSC
VARYING TABLE-INDEX FROM 1 BY 1
UNTIL TABLE-INDEX > 20.

*    GET A SQL STATEMENT FROM THE OPERATOR.

DISPLAY "ENTER SQL STATEMENT WITHOUT TERMINATOR:".
DISPLAY ">" WITH NO ADVANCING.

ACCEPT DYN-STATEMENT.

DISPLAY " ".

*    PREPARE THE SQL STATEMENT AND DECLARE A CURSOR.

EXEC SQL  PREPARE S1 FROM :DYN-STATEMENT  END-EXEC.
EXEC SQL  DECLARE C1 CURSOR FOR S1        END-EXEC.

*    DESCRIBE ANY BIND VARIABLES.

EXEC SQL  DESCRIBE BIND VARIABLES FOR S1 INTO BNDDSC
END-EXEC.

IF SQLDFND IN BNDDSC < 0
DISPLAY "TOO MANY BIND VARIABLES."
GO TO END-SQL
ELSE
DISPLAY "NUMBER OF BIND VARIABLES: " WITH NO ADVANCING
MOVE SQLDFND IN BNDDSC TO VAR-COUNT
DISPLAY VAR-COUNT
MOVE SQLDFND IN BNDDSC TO SQLDNUM IN BNDDSC
END-IF.

*    REPLACE THE 0S DESCRIBED INTO THE DATATYPE FIELDS OF THE
*    BIND DESCRIPTOR WITH 1S TO AVOID AN "INVALID DATATYPE"
*    ORACLE ERROR

MOVE 1 TO TABLE-INDEX.
FIX-BIND-TYPE.
MOVE 1 TO BNDDVTYP(TABLE-INDEX)
ADD 1 TO TABLE-INDEX
IF TABLE-INDEX <= 20
GO TO FIX-BIND-TYPE.

*    LET THE USER FILL IN THE BIND VARIABLES.

IF SQLDFND IN BNDDSC = 0
GO TO DESCRIBE-ITEMS.
MOVE 1 TO TABLE-INDEX.
GET-BIND-VAR.
DISPLAY "ENTER VALUE FOR ", BND-DH-VNAME(TABLE-INDEX).

ACCEPT BND-DV(TABLE-INDEX).

ADD 1 TO TABLE-INDEX
IF TABLE-INDEX <= SQLDFND IN BNDDSC
GO TO GET-BIND-VAR.

*    OPEN THE CURSOR AND DESCRIBE THE SELECT-LIST ITEMS.

DESCRIBE-ITEMS.

EXEC SQL  OPEN C1 USING DESCRIPTOR BNDDSC          END-EXEC.
EXEC SQL  DESCRIBE SELECT LIST FOR S1 INTO SELDSC  END-EXEC.

IF SQLDFND IN SELDSC < 0
DISPLAY "TOO MANY SELECT-LIST ITEMS."
GO TO END-SQL
ELSE
DISPLAY "NUMBER OF SELECT-LIST ITEMS: "
WITH NO ADVANCING
MOVE SQLDFND IN SELDSC TO VAR-COUNT
DISPLAY VAR-COUNT
DISPLAY " "
MOVE SQLDFND IN SELDSC TO SQLDNUM IN SELDSC
END-IF.

*    COERCE THE DATATYPE OF ALL SELECT-LIST ITEMS TO VARCHAR2.

IF SQLDNUM IN SELDSC > 0
PERFORM COERCE-COLUMN-TYPE
VARYING TABLE-INDEX FROM 1 BY 1
UNTIL TABLE-INDEX > SQLDNUM IN SELDSC
DISPLAY " ".

*    FETCH EACH ROW AND PRINT EACH SELECT-LIST VALUE.

IF SQLDNUM IN SELDSC > 0
PERFORM FETCH-ROWS UNTIL NO-MORE-DATA = "Y".

DISPLAY " "
DISPLAY "NUMBER OF ROWS PROCESSED: " WITH NO ADVANCING.
MOVE SQLERRD(3) TO ROW-COUNT.
DISPLAY ROW-COUNT.

*    CLEAN UP AND TERMINATE.

EXEC SQL  CLOSE C1             END-EXEC.
EXEC SQL  COMMIT WORK RELEASE  END-EXEC.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY!".
DISPLAY " ".
STOP RUN.

*    DISPLAY ORACLE ERROR MESSAGE AND CODE.

SQL-ERROR.
DISPLAY " ".
DISPLAY SQLERRMC.
END-SQL.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
STOP RUN.

*    PERFORMED SUBROUTINES BEGIN HERE:

*    INIT-BNDDSC: INITIALIZE THE BIND DESCRIPTOR.

INIT-BNDDSC.

MOVE SPACES TO BND-DH-VNAME(TABLE-INDEX).
MOVE 80 TO BNDDH-MAX-VNAMEL(TABLE-INDEX).
CALL "SQLADR" USING
BND-DH-VNAME(TABLE-INDEX)
BNDDH-VNAME(TABLE-INDEX).

MOVE SPACES TO BND-DI-VNAME(TABLE-INDEX).
MOVE 80 TO BNDDI-MAX-VNAMEL(TABLE-INDEX).
CALL "SQLADR" USING
BND-DI-VNAME(TABLE-INDEX)
BNDDI-VNAME (TABLE-INDEX).

MOVE SPACES TO BND-DV(TABLE-INDEX).
MOVE 80 TO BNDDVLN(TABLE-INDEX).
CALL "SQLADR" USING
BND-DV(TABLE-INDEX)
BNDDV(TABLE-INDEX).
MOVE ZERO TO BND-DI(TABLE-INDEX).
CALL "SQLADR" USING
BND-DI(TABLE-INDEX)
BNDDI(TABLE-INDEX).

MOVE ZERO TO BNDDFMT(TABLE-INDEX).
MOVE ZERO TO BNDDFMTL(TABLE-INDEX).
MOVE ZERO TO BNDDFCLP(TABLE-INDEX).
MOVE ZERO TO BNDDFCRCP(TABLE-INDEX).

*    INIT-SELDSC: INITIALIZE THE SELECT DESCRIPTOR.

INIT-SELDSC.

MOVE SPACES TO SEL-DH-VNAME(TABLE-INDEX).
MOVE 80 TO SELDH-MAX-VNAMEL(TABLE-INDEX).
CALL "SQLADR" USING
SEL-DH-VNAME(TABLE-INDEX)
SELDH-VNAME(TABLE-INDEX).

MOVE SPACES TO SEL-DI-VNAME(TABLE-INDEX).
MOVE 80 TO SELDI-MAX-VNAMEL(TABLE-INDEX).
CALL "SQLADR" USING
SEL-DI-VNAME(TABLE-INDEX)
SELDI-VNAME (TABLE-INDEX).

MOVE SPACES TO SEL-DV(TABLE-INDEX).
MOVE 80 TO SELDVLN(TABLE-INDEX).
CALL "SQLADR" USING
SEL-DV(TABLE-INDEX)
SELDV(TABLE-INDEX).

MOVE ZERO TO SEL-DI(TABLE-INDEX).
CALL "SQLADR" USING
SEL-DI(TABLE-INDEX)
SELDI(TABLE-INDEX).

MOVE ZERO TO SELDFMT(TABLE-INDEX).
MOVE ZERO TO SELDFMTL(TABLE-INDEX).
MOVE ZERO TO SELDFCLP(TABLE-INDEX).
MOVE ZERO TO SELDFCRCP(TABLE-INDEX).

*    COERCE SELECT-LIST DATATYPES TO VARCHAR2.

COERCE-COLUMN-TYPE.
CALL "SQLNUL" USING
SELDVTYP(TABLE-INDEX)
SELDVTYP(TABLE-INDEX)
NULLS-ALLOWED.

*    IF DATATYPE IS DATE, LENGTHEN TO 9 CHARACTERS.
IF SELDVTYP(TABLE-INDEX) = 12
MOVE 9 TO SELDVLN(TABLE-INDEX).

*    IF DATATYPE IS NUMBER, SET LENGTH TO PRECISION.
IF SELDVTYP(TABLE-INDEX) = 2
CALL "SQLPRC" USING
SELDVLN(TABLE-INDEX)
PRECISION
SCALE.
MOVE 0 TO DISPLAY-LENGTH.
IF SELDVTYP(TABLE-INDEX) = 2 AND PRECISION = 0
MOVE 40 TO DISPLAY-LENGTH.
IF SELDVTYP(TABLE-INDEX) = 2 AND PRECISION > 0
ADD 2 TO PRECISION
MOVE PRECISION TO DISPLAY-LENGTH.

IF SELDVTYP(TABLE-INDEX) = 2
IF DISPLAY-LENGTH > MAX-LENGTH
DISPLAY "COLUMN VALUE TOO LARGE FOR DATA BUFFER."
GO TO END-SQL
ELSE
MOVE DISPLAY-LENGTH TO SELDVLN(TABLE-INDEX).

*    COERCE DATATYPES TO VARCHAR2.
MOVE 1 TO SELDVTYP(TABLE-INDEX).

*    DISPLAY COLUMN HEADING.
MOVE SEL-DH-VNAME(TABLE-INDEX) TO COLUMN-NAME.
DISPLAY COLUMN-NAME(1:SELDVLN(TABLE-INDEX)), " "
WITH NO ADVANCING.

*FETCH A ROW AND PRINT THE SELECT-LIST VALUE.

FETCH-ROWS.
EXEC SQL  FETCH C1 USING DESCRIPTOR SELDSC  END-EXEC.
IF SQLCODE NOT = 0
MOVE "Y" TO NO-MORE-DATA.
IF SQLCODE = 0
PERFORM PRINT-COLUMN-VALUES
VARYING TABLE-INDEX FROM 1 BY 1
UNTIL TABLE-INDEX > SQLDNUM IN SELDSC
DISPLAY " ".

*PRINT A SELECT-LIST VALUE.

PRINT-COLUMN-VALUES.
IF SEL-DI(TABLE-INDEX) = -1
DISPLAY NULL-VAL(1:SELDVLN(TABLE-INDEX)), " "
WITH NO ADVANCING
ELSE
DISPLAY SEL-DV(TABLE-INDEX)(1:SELDVLN(TABLE-INDEX)), " "
WITH NO ADVANCING
END-IF.

12 マルチスレッド・アプリケーション

開発プラットフォームがスレッドをサポートしていない場合、この章は無視してもかまいません。

この章の内容は、次のとおりです。

- スレッドの概要

- Pro*COBOLのランタイム・コンテキスト

- ランタイム・コンテキストの使用モデル

- マルチスレッド・アプリケーションのユーザー・インタフェース機能

- マルチスレッドの例

スレッドの概要

マルチスレッド・アプリケーションでは、共有のアドレス空間で複数のスレッドが実行されます。スレッドはプロセス内で実行される軽量のサブプロセスです。コードとデータ・セグメントは共有しますが、独自のプログラム・カウンタ、マシン・レジスタおよびスタックがあります。スレッド・ローカル属性なしで作業記憶域で宣言された変数は(ローカル記憶域あるいはスレッド・ローカル記憶域とは異なり)、すべてのスレッドに共通のものになります。アプリケーション内部の複数のスレッドから変数へのアクセスを管理するため、相互排他的なメカニズムが多くの場面で必要になります。Mutexは、データの整合性が保たれることを保証する同期化メカニズムです。

mutexの詳細は、マルチスレッドの説明を参照してください。マルチスレッド・アプリケーションの詳細は、スレッド・ファンクションのマニュアルを参照してください。

Pro*COBOLは、マルチスレッド・アプリケーション対応のプラットフォームで、次のものを使用したマルチスレッドOracleサーバー・アプリケーションの開発に対応しています。

- スレッド・セーフのコードを生成するコマンドライン・オプション。

- マルチスレッドに対応した埋込みSQL文およびディレクティブ。

- スレッド・セーフSQLLIBおよびその他のクライアント側Oracleライブラリ。

注意:
プラットフォームによりサポートするスレッド・パッケージが異なるため、使用しているプラットフォーム固有のOracleマニュアルを参照して、Oracleがスレッド・パッケージをサポートしているかを調べてください。

この章では、前述の機能を使用してマルチスレッドPro*COBOLアプリケーションを開発する方法を説明します。

- マルチスレッド・アプリケーション用のランタイム・コンテキスト。

- ランタイム・コンテキストを使用するための2つのモデル。

- マルチスレッド・アプリケーションのユーザー・インタフェース機能。

- Pro*COBOLでマルチスレッド・アプリケーションを作成するためのプログラミングに関する注意事項。

- マルチスレッドPro*COBOLアプリケーションのサンプル。

Pro*COBOLのランタイム・コンテキスト

Pro*COBOLには、スレッドと接続を疎結合するためのランタイム・コンテキストの概念が導入されています。ランタイム・コンテキストには、次のリソースおよびその現在の状態が含まれます。

- 1つ以上のOracleサーバーへのゼロまたはそれ以上の接続。

- サーバー接続に使用されるゼロまたはそれ以上のカーソル。

- MODE、HOLD_CURSOR、RELEASE_CURSORおよびSELECT_ERRORなどのインライン・オプション。

スレッドと接続の間の疎結合をサポートしているのみでなく、Pro*COBOLではスレッドとランタイム・コンテキストを疎結合できます。Pro*COBOLを使用すると、アプリケーションでランタイム・コンテキストを処理するハンドルを定義し、そのハンドルをスレッド間で渡すことができます。

たとえば、対話形式のアプリケーションで、スレッドT1を作成し、問合せを実行して先頭の10行をアプリケーションに戻します。その後、T1は終了します。必要なユーザー入力が取得されると、別のスレッドT2が作成され(または既存のスレッドが使用され)、T1のランタイム・コンテキストがT2に渡されます。T2は同じカーソルを処理して次の10行をフェッチできます。図12-1はこの処理を示します。

図12-1 疎結合接続およびスレッド

ランタイム・コンテキストの使用モデル

マルチスレッド・アプリケーションでランタイム・コンテキストを使用する際に考えられる2つのモデルは次のとおりです。

- 複数のスレッドで1つのランタイム・コンテキストを共有。

- 複数のスレッドで別々のランタイム・コンテキストを使用。

いずれのモデルを使用した場合も、複数のスレッドで同時に1つのランタイム・コンテキストを共有することはできません。2つ以上のスレッドで同じランタイム・コンテキストを同時に使用すると、ランタイム・エラーが発生します。

複数のスレッドで1つのランタイム・コンテキストを共有

図12-2は、マルチスレッド環境で実行するアプリケーションを示します。1つ以上のSQL文を処理するために、様々なスレッドが1つのランタイム・コンテキストを共有します。この場合も、同時に複数のスレッドでランタイム・コンテキストを共有することはできません。図12-2のmutexは、同時使用を回避する方法を示します。

図12-2 スレッド間でのコンテキストの共有

複数のスレッドで複数のランタイム・コンテキストを共有

図12-3は、複数のランタイム・コンテキストを使用して複数のスレッドを実行するアプリケーションを示します。この場合、各スレッドは専用のランタイム・コンテキストを使用するため、アプリケーションにはmutexは必要ありません。

図12-3 スレッド間でのコンテキストの非共有

マルチスレッド・アプリケーションのユーザー・インタフェース機能

Pro*COBOLには、マルチスレッド・アプリケーションに対応した次のユーザー・インタフェース機能があります。

- LOCAL-STORAGE節およびTHREAD-LOCAL-STORAGE節にホスト変数の宣言が可能。

- コマンドライン・オプションTHREADS=YES | NO。

- 埋込みSQL文およびディレクティブ。

- スレッド・セーフSQLLIBパブリック・ファンクション。

THREADSオプション

Pro*COBOLでは、「マルチスレッド・プログラミングに関する注意事項」に説明されたガイドラインに従ってコマンドラインにTHREADS=YESを指定すると、スレッド・セーフのコードが生成されます。Pro*COBOLでは、THREADS=YESを指定すると、すべてのSQL文がユーザー定義のランタイム・コンテキストのスコープ内で実行されます。プログラムがこの要件を満たしていないと、プリコンパイラ・エラーが戻されます。

ランタイム・コンテキストの埋込みSQL文およびディレクティブ

ランタイム・コンテキストおよびスレッドの定義と使用に対応した埋込みSQLおよびディレクティブは、次のとおりです。

- EXEC SQL ENABLE THREADS END-EXEC.

- EXEC SQL CONTEXT ALLOCATE :context_var END-EXEC.

- EXEC SQL CONTEXT USE { :context_var | DEFAULT} END-EXEC.

- EXEC SQL CONTEXT FREE :context_var END-EXEC.

前述のEXEC SQL文では、context_varはランタイム・コンテキストに対するハンドルで、次のようにSQL-CONTEXT型として宣言する必要があります。

01  SQL-CONTEXT context_var END-EXEC.

DEFAULTを使用すると、別のCONTEXT USE文でオーバーライドされるまで、以降のすべての埋込みSQL文にデフォルト(グローバル)ランタイム・コンテキストが使用されます。

様々なコンテキスト文の使用例は、後述の例を参照してください。

SQL-CONTEXTのホスト表の使用禁止

SQL-CONTEXTのホスト表は宣言できません。かわりに、S9(9) COMP変数のホスト表を宣言し、SQL-CONTEXTとしてサブプログラムに宣言した後に、1つずつサブプログラムに渡してください。

EXEC SQL ENABLE THREADS

この実行SQL文は、複数のスレッドをサポートするプロセスを初期化します。このSQL文は、マルチスレッド・アプリケーションを含むプログラム内の最初の実行SQL文にしてください。アプリケーションのすべてのファイルにおいて、ENABLE THREADS文は1回しか使用できません。それ以上使用した場合はエラーとなります。詳細は、「ENABLE THREADS(実行可能埋込みSQL拡張機能)」を参照してください。

EXEC SQL CONTEXT ALLOCATE

この実行SQL文は指定されたランタイム・コンテキストにメモリーを割り当てて初期化します。ランタイム・コンテキスト変数はSQL_CONTEXT型として宣言する必要があります。詳細は、「CONTEXT ALLOCATE(実行可能埋込みSQL拡張機能)」を参照してください。

EXEC SQL CONTEXT USE

EXEC SQL CONTEXT USEディレクティブは、以降の実行SQL文に指定されたランタイム・コンテキストを使用するようにプリコンパイラに指示します。ランタイム・コンテキストを指定するには、EXEC SQL CONTEXT ALLOCATE文で事前に割り当てる必要があります。

EXEC SQL CONTEXT USEディレクティブは、EXEC SQL WHENEVERディレクティブと同様に動作します。つまり、COBOLの標準スコープ・ルールに関係なく、指定されたソース・ファイルでこの文とともに動作するすべての実行SQL文に対して有効です。

詳細は、「CONTEXT USE (Oracle埋込みSQLディレクティブ)」および「CONTEXT ALLOCATE (実行可能埋込みSQL拡張機能)」を参照してください。

EXEC SQL CONTEXT FREE

EXEC SQL CONTEXT FREE実行SQL文は、指定されたランタイム・コンテキストに対応付けられたメモリーを解放し、ホスト・プログラム変数にNULLポインタを挿入します。詳細は、「CONTEXT FREE (実行可能埋込みSQL拡張機能)」を参照してください。

Pro*C/C++プログラムとの対話

ランタイム・コンテキストは、連絡節で定義した引数を使用して渡すことができます。マルチスレッドPro*C/C++プログラムはPro*COBOLサブプログラムを、またPro*COBOLプログラムはPro*C/C++で記述されたサブプログラムをコールできます。

マルチスレッド・プログラミングに関する注意事項

Oracleでは、必ずスレッド・セーフのSQLLIBコードが生成されますが、スレッドと正常に動作するようにソース・コードを設計するのはプログラマの責任です。たとえば、使用する変数のスコープは慎重に決定してください。

また、マルチスレッドでは次のような設計上の要件を考慮してください。

- 各ランタイム・コンテキストにSQLCAを1つ含めます。

- 通常は自動変数であるSQLCAのように、スレッド・セーフ・グループ項目としてランタイム・コンテキストごとにSQLDAを宣言します。

- スレッド・セーフ方式でホスト変数を宣言するときは、静的ホスト変数およびグローバル・ホスト変数の使用に注意してください。

- 複数のスレッドで1つのランタイム・コンテキストを同時に使用しないでください。

- デフォルトのデータベース接続を使用するか、AT句でデータベース接続を明示的に定義します。

ランタイム・コンテキストでは、EXEC SQL UPDATEなどの実行可能埋込みSQL文は1つのみにしてください。

プリコンパイル済アプリケーションの既存の要件も適用されます。たとえば、特定のカーソルへの参照はすべて同じソース・ファイルに含まれている必要があります。

マルチスレッドの制限

スレッドを使用する場合は、次の制限事項が適用されます。

- SQL-CONTEXTデータ型の配列は使用できません。

- 同時スレッドにはそれぞれSQLCAを指定します。

- 同時スレッドにはそれぞれ専用のコンテキスト領域を割り当てます。

複数のコンテキストの例

次のコードは、複数のコンテキストを使用する方法と、コンテキスト使用文のスコープを示します。

例1

この例では、スレッドが生成されないため、プリコンパイル・オプションをTHREADS=YESに設定する必要はありません。

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN.
...
* declare a context area
01  CTX1  SQL-CONTEXT.
01  UID1  PIC X(11) VALUE "SCOTT/TIGER".
01  UID2  PIC X(10) VALUE "MARY/LION"

PROCEDURE DIVISION.
...
* allocate context area
EXEC SQL CONTEXT ALLOCATE :CTX1 END-EXEC.
EXEC SQL CONTEXT USE :CTX1 END-EXEC.
* all statements until the next context use will use CTX1
EXEC SQL CONNECT :UID1 END-EXEC.
EXEC SQL SELECT ....
EXEC SQL CONTEXT USE DEFAULT END-EXEC.
* all statements physically after the preceding lines will use the default context
EXEC SQL CONNECT :UID2 END-EXEC.
EXEC SQL INSERT ...
...

例2

次の例は、複数のコンテキストを示します。コンテキストの1つは生成されたスレッドに使用され、もう1つはメイン・プログラムに使用されます。開始したスレッド、SUBPRGM1はコンテキストCTX1を使用し、CTX1はLINKAGE SECTIONを介して渡されます。この例から、CONTEXT USE文のスコープもわかります。

注意:
この例のプログラム・ファイルに加え、この項では以降のすべての例のメイン・プログラムを、THREADS=YESオプションを設定してプリコンパイルする必要があります。

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN.
...
* declare two context areas
01  CTX1  SQL-CONTEXT.
01  CTX2  SQL-CONTEXT.

PROCEDURE DIVISION.

* enable threading
EXEC SQL ENABLE THREADS END-EXEC.

* allocate context areas
EXEC SQL CONTEXT ALLOCATE :CTX1 END-EXEC.
EXEC SQL CONTEXT ALLOCATE :CTX2 END-EXEC.

* include your code to start thread "SUBPGM1" using CTX1 here.

EXEC SQL CONTEXT USE :CTX2 END-EXEC.
* all statement physically after the preceding lines will use CTX2

EXEC SQL CONNECT :USERID END-EXEC.
EXEC SQL INSERT .....
...

スレッドSUBPRGM1は別のファイルに入ります。

PROGRAM-ID. SUBPRGM1.
...
01  USERID PIC X(11) VALUE "SCOTT/TIGER".
LINKAGE SECTION.
01  CTX1 SQL-CONTEXT.
PROCEDURE DIVISION USING CTX1.

EXEC SQL CONTEXT USE :CTX1 END-EXEC.
EXEC SQL CONNECT :USERID END-EXEC.
EXEC SQL SELECT ...
...

例3

次の例では複数のスレッドが使用されます。各スレッドには、それぞれ別のコンテキストを使用します。スレッドを同時実行する場合は、各スレッドに専用のコンテキストが必要になります。コンテキストは、START文のUSING CLAUSEを使用してスレッドに渡され、スレッド・サブプログラムのLINKAGE SECTIONに宣言されます。

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN.
...
DATA DIVISION.

01  CTX1 SQL-CONTEXT.
01  CTX2 SQL-CONTEXT.

PROCEDURE DIVISION.
...
EXEC SQL ENABLE THREADS END-EXEC.
EXEC SQL CONTEXT ALLOCATE :CTX1 END-EXEC.
EXEC SQL CONTEXT ALLOCATE :CTX2 END-EXEC.

* include your code to start thread "SUBPGM" using CTX1 here.
* include your code to start thread "SUBPGM" using CTX2 here.
...

スレッドSUBPGMは別のファイルに入ります。

PROGRAM-ID. SUBPGM.
...
DATA DIVISION.
...
01  USERID PIC X(11) VALUE "SCOTT/TIGER".
...
LINKAGE SECTION.
01  CTX SQL-CONTEXT.
PROCEDURE DIVISION USING CTX.
EXEC SQL CONTEXT USE :CTX END-EXEC.
EXEC SQL CONNECT :USERID END-EXEC.
EXEC SQL SELECT ....
...

例4

次の例では、前の例を基にしていますが、トップレベルのプログラムで接続し、コンテキストとともにその接続がスレッド・サブプログラムに渡されます。

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN.
...
DATA DIVISION.

01  CTX1 SQL-CONTEXT.
01  CTX2 SQL-CONTEXT.
01  USERID PIC X(11) VALUE "SCOTT/TIGER".

ROCEDURE DIVISION.

EXEC SQL ENABLE THREADS END-EXEC.
EXEC SQL CONTEXT ALLOCATE :CTX1 END-EXEC.
EXEC SQL CONTEXT ALLOCATE :CTX2 END-EXEC.
EXEC SQL CONTEXT USE :CTX1 END-EXEC.
EXEC SQL CONNECT :USERID END-EXEC.
EXEC SQL CONTEXT USE :CTX2 END-EXEC.
EXEC SQL CONNECT :USERID END-EXEC.

* include your code to start thread "SUBPGM" using CTX1 here.
* include your code to start thread "SUBPGM" using CTX2 here.
...

スレッドSUBPRGMは別のファイルに入ります。

PROGRAM-ID. SUBPGM.
...
LINKAGE SECTION.
01  CTX SQL-CONTEXT.
PROCEDURE DIVISION USING CTX.
EXEC SQL CONTEXT USE :CTX END-EXEC.
EXEC SQL SELECT ....
...

例5

次の例は、1つのコンテキストを共有する複数のスレッドを示します。この場合、スレッドをシリアライズする必要があります。

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN.
...
DATA DIVISION.

01  CTX1 SQL-CONTEXT.

PROCEDURE DIVISION.

EXEC SQL ENABLE THREADS END-EXEC.
EXEC SQL CONTEXT ALLOCATE :CTX1 END-EXEC.

* include your code to start thread1 "SUBPGM1" using CTX1 here.
* include your code to wait for thread1 here.
* include your code to start thread2 "SUBPGM2" using CTX1 here.
...

2つのスレッドは別々に2つのファイルに入れられます。最初のファイルの内容は次のとおりです。

PROGRAM-ID. SUBPGM1.
...
DATA DIVISION.
..
01  USERID PIC X(11) VALUE "SCOTT/TIGER".
...
LINKAGE SECTION.
01  CTX SQL-CONTEXT.
PROCEDURE DIVISION USING CTX.
EXEC SQL CONTEXT USE :CTX END-EXEC.
...
EXEC SQL CONNECT :USERID END-EXEC.

もう1つのファイルにはSUBPGM2が入ります。

PROGRAM-ID. SUBPGM2.
...
DATA DIVISION.
...
LINKAGE SECTION.
01  CTX SQL-CONTEXT.
PROCEDURE DIVISION USING CTX.
EXEC SQL CONTEXT USE :CTX END-EXEC.
EXEC SELECT ....
...

マルチスレッドの例

この複数ファイルで構成されるアプリケーションは、SQLLIBランタイム・コンテキスト領域(SQL-CONTEXT)を使用して複数のスレッドに対応する1つの方法を示します。THREADS=YESを設定して再コンパイルします。

メイン・プログラム、orathrd2は、sqllibコンテキストを格納するS9(9) COMP変数の配列を宣言します。orathrd2は、次の文を通じてスレッドを使用可能にします。

EXEC SQL ENABLE THREADS END-EXEC.

次に、(oracon.pcoファイル内の)サブプログラムoraconをコールして、スレッドを割り当てます。さらに、oraconは割り当てられたコンテキストごとに接続を確立します。

ORTHRD2は、THREAD-1またはTHREAD-2のいずれかのスレッド・エントリ・ポイントにコンテキストを渡します。THREAD-1は、1人の従業員の給与を選択して表示するのみです。THREAD-2は、その従業員の給与を選択して更新します。THREAD-2はCOMMITを発行するので、コミット後にSELECTを実行するスレッドから更新を参照できます。(ただし、更新と同時実行するスレッドでは参照できません。)更新とコミットのタイミングは不確定であるため、実行ごとに出力が異なる点に注意してください。

同時スレッドにはそれぞれ別のコンテキストが必要であることに注意してください。コンテキストは後続のスレッドに渡して使用することができますが、スレッドは同一のコンテキストを同時に使用することができません。このモデルは接続プーリングに使用することができます。接続プーリングでは、最初に最大数の接続が作成され、ユーザーの要求を実行するため、使用可能な接続がスレッドに渡されます。

現時点ではSQL-CONTEXTの配列を宣言できないため、S9(9) COMP変数の配列が使用されます。

注意: このプログラムは、SolarisおよびMicroFocus ServerExpressコンパイラを実行するSunワークステーション用に開発されていて、ベンダー固有のディレクティブおよび機能を使用します。

マルチスレッドに対応するCOBOL文の詳細は、使用するプラットフォームのマニュアルを参照してください。

メイン・プログラムは、ファイルorathrd2.pcoにあります。

$SET REENTRANT MF
IDENTIFICATION DIVISION.
PROGRAM-ID. ORATHRD2.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
78 MAX-LOOPS            VALUE 10.
01 THREAD-ID            USAGE POINTER.
01 TP-1                 USAGE THREAD-POINTER OCCURS MAX-LOOPS.
01 IDEN-4               PIC 9(4).
01 LOOP-COUNTER         PIC 9(2)  COMP-X EXTERNAL.
01 PEMPNO               PIC S9(4) COMP EXTERNAL.
01 ISAL                 PIC S9(4) COMP   VALUE ZERO.
EXEC SQL
INCLUDE SQLCA
END-EXEC.
THREAD-LOCAL-STORAGE SECTION.
01  CONTEXT-AREA          PIC S9(9) COMP OCCURS MAX-LOOPS.
PROCEDURE DIVISION.
MAIN SECTION.

PERFORM INITIALISATION
PERFORM ORACLE-CONNECTIONS VARYING LOOP-COUNTER
FROM 1 BY 1 UNTIL LOOP-COUNTER > MAX-LOOPS
PERFORM  VARYING LOOP-COUNTER FROM 1 BY 1
UNTIL LOOP-COUNTER > MAX-LOOPS
PERFORM START-THREAD
END-PERFORM
STOP RUN.

*---------------------------------------------------------------
* CHECK THAT WE ARE RUNNING UNDER A MULTI THREADED RTS.
*---------------------------------------------------------------
INITIALISATION SECTION.

CALL "CBL_THREAD_SELF" USING THREAD-ID ON EXCEPTION
DISPLAY "NO THREAD SUPPORT IN THIS RTS"
STOP RUN
END-CALL
IF RETURN-CODE = 1008
DISPLAY "CANNOT RUN THIS TEST ON SINGLE THREADED RTS"
STOP RUN
END-IF
DISPLAY "MULTI-THREAD RTS"

* ENABLING THREADS MUST BE DONE ONCE BEFORE ANY CONTEXT USEAGE
EXEC SQL ENABLE THREADS END-EXEC.
IF SQLCODE NOT = ZERO
DISPLAY 'ERROR ENABLING ORACLE THREAD SUPPORT '
' - ABORTING : ' SQLERRMC
STOP RUN
END-IF

*  SET A VALUE FOR THE EMPLOYEE NUMBER.  BECAUSE THIS IS AN
*  EXTERNAL VARIABLE, A COPY OF ITS VALUE IS VISIBLE TO THE
*  OTHER MODULES IN THIS APPLICATION
MOVE 7566 TO PEMPNO
EXIT SECTION.

*-----------------------------------------------------------------
* CREATE THREADS AND START WITH EITHER THREAD-1 OR THREAD-2
*-----------------------------------------------------------------
START-THREAD SECTION.

IF LOOP-COUNTER = 2 OR LOOP-COUNTER = 5
START "THREAD-2 "
USING CONTEXT-AREA(LOOP-COUNTER)
IDENTIFIED BY TP-1(LOOP-COUNTER)
STATUS IS IDEN-4
ON EXCEPTION DISPLAY "THREAD CREATE FAILED"
END-START
IF IDEN-4 NOT = ZERO
DISPLAY "THREAD CREATE FAILED RETURNED " IDEN-4
END-IF
ELSE
START "THREAD-1 "
USING CONTEXT-AREA(LOOP-COUNTER)
IDENTIFIED BY TP-1(LOOP-COUNTER)
STATUS IS IDEN-4
ON EXCEPTION DISPLAY "THREAD CREATE FAILED"
END-START
IF IDEN-4 NOT = ZERO
DISPLAY "THREAD CREATE FAILED RETURNED " IDEN-4
END-IF
END-IF.

START-THREAD-END.
EXIT SECTION.

*-----------------------------------------------------------------
* ALLOCATE CONTEXT AREAS ESTABLISH CONNECTION WITH EACH AREA.
*-----------------------------------------------------------------
ORACLE-CONNECTIONS SECTION.

CALL "ORACON" USING CONTEXT-AREA(LOOP-COUNTER).
ORACLE-CONNECTIONS-END.
EXIT SECTION.

ファイルthread-1.pcoの内容は次のとおりです。

* This is Thread 1.  It selects and displays the data for
* the employee. The context area upon which a connection
* has been established is passed to the thread through the
* linkage section. In a multi-file application, you
* can pass the context through the linkage section.
* Precompile with THREADS=YES.
*
$SET REENTRANT MF
IDENTIFICATION DIVISION.
PROGRAM-ID. THREAD-1.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 PEMPNO               PIC S9(4) COMP EXTERNAL.

LOCAL-STORAGE SECTION.
01 DEMPNO               PIC Z(4) VALUE ZERO.
01 PEMP-NAME1           PIC X(15) VARYING  VALUE SPACES.
01 PSAL-VALUE1          PIC S9(7)V99 COMP-3 VALUE ZERO.
01 ISAL1                PIC S9(4)   COMP   VALUE ZERO.
01 DSAL-VALUE           PIC +(7).99 VALUE ZERO.
EXEC SQL
INCLUDE SQLCA
END-EXEC.

LINKAGE SECTION.
01 CONTEXT-AREA1         SQL-CONTEXT.

*---------------------------------------------------------------
* USING THE PASSED IN CONTEXT, SELECT AND DISPLAY THE
* DATA FOR EMPLOYEE.
*---------------------------------------------------------------
PROCEDURE DIVISION USING CONTEXT-AREA1.
MAIN SECTION.

EXEC SQL WHENEVER SQLERROR GOTO SELECT-ERROR END-EXEC
EXEC SQL CONTEXT USE :CONTEXT-AREA1 END-EXEC
EXEC SQL
SELECT  ENAME, SAL
INTO  :PEMP-NAME1, :PSAL-VALUE1:ISAL1
FROM  EMP
WHERE  EMPNO = :PEMPNO
END-EXEC
IF ISAL1 < ZERO
MOVE ZERO     TO PSAL-VALUE1
END-IF
MOVE PEMPNO      TO DEMPNO
MOVE PSAL-VALUE1 TO DSAL-VALUE
DISPLAY "FOR EMP ", DEMPNO, " NAME ",
PEMP-NAME1-ARR(1:PEMP-NAME1-LEN),
" THE CURRENT SALARY IS ", DSAL-VALUE
EXIT PROGRAM.

*---------------------------------------------------------------
* THERE HAS BEEN AN ERROR WHEN SELECTING FROM THE EMP TABLE
*---------------------------------------------------------------
SELECT-ERROR SECTION.

EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC
DISPLAY "HIT AN ORACLE ERROR SELECTING EMPNO 7566"
DISPLAY "SQLCODE = ", SQLCODE
DISPLAY "ERROR TEXT ", SQLERRMC(1:SQLERRML)
GOBACK
EXIT SECTION.

ファイルthread-2.pcoの内容は次のとおりです。

* This is Thread 2.  The program will select, then update,
* increment, and then commit the salary.  It uses the passed-in
* context upon which a connection has previously been established.
* Precompile with THREADS=YES.
*
$SET REENTRANT MF
IDENTIFICATION DIVISION.
PROGRAM-ID. THREAD-2.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 PEMPNO               PIC S9(4)   COMP EXTERNAL.

LOCAL-STORAGE SECTION.
01 DEMPNO               PIC Z(4) VALUE ZERO.
01 PEMP-NAME2           PIC X(15) VARYING  VALUE SPACES.
01 PSAL-VALUE2          PIC S9(7)V99 COMP-3 VALUE 100.
01 ISAL2                PIC S9(4)   COMP   VALUE ZERO.
01 DSAL-VALUE           PIC +(7).99 VALUE ZERO.
EXEC SQL
INCLUDE SQLCA
END-EXEC.

LINKAGE SECTION.
01 CONTEXT-AREA2         SQL-CONTEXT.

*---------------------------------------------------------------
* USING THE PASSED IN CONTEXT AREA, FIRST SELECT TO GET INITIAL
* VALUES, INCREMENT THE SALARY, UPDATE AND COMMIT.
*---------------------------------------------------------------
PROCEDURE DIVISION USING CONTEXT-AREA2.
MAIN SECTION.

EXEC SQL WHENEVER SQLERROR GOTO UPDATE-ERROR END-EXEC
EXEC SQL CONTEXT USE     :CONTEXT-AREA2 END-EXEC
EXEC SQL
SELECT  ENAME, SAL
INTO  :PEMP-NAME2, :PSAL-VALUE2:ISAL2
FROM  EMP
WHERE  EMPNO = :PEMPNO
END-EXEC
ADD  10  TO PSAL-VALUE2
EXEC SQL
UPDATE  EMP
SET  SAL   = :PSAL-VALUE2
WHERE  EMPNO = :PEMPNO
END-EXEC
MOVE PEMPNO      TO DEMPNO
MOVE PSAL-VALUE2 TO DSAL-VALUE
DISPLAY "FOR EMP ", DEMPNO, " NAME ",
PEMP-NAME2-ARR(1:PEMP-NAME2-LEN),
" THE UPDATED SALARY IS ", DSAL-VALUE
*    THIS COMMIT IS REQUIRED, OTHERWISE THE DATABASE
*    WILL BLOCK SINCE THE UPDATES ARE TO THE SAME ROW
EXEC SQL COMMIT WORK END-EXEC
EXIT PROGRAM.

*---------------------------------------------------------------
* THERE HAS BEEN AN ERROR WHEN UPDATING THE SAL IN THE EMP TABLE
*---------------------------------------------------------------
UPDATE-ERROR SECTION.

EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC
DISPLAY "HIT AN ORACLE ERROR UPDATING EMPNO 7566"
DISPLAY "SQLCODE = ", SQLCODE
DISPLAY "ERROR TEXT ", SQLERRMC(1:SQLERRML)
GOBACK
EXIT SECTION.

ファイルoracon.pcoの内容は次のとおりです。

* This program allocates SQLLIB runtime contexts, stores
* a pointer to the context in the variable which was
* passed in from the main program through the linkage section,
* and establishes a connection on the allocated context.
*
* This program is written for Merant MicroFocus COBOL and uses
* vendor-specific directives and functionality. Precompile
* with THREADS=YES.
*
$SET REENTRANT MF
IDENTIFICATION DIVISION.
PROGRAM-ID. ORACON.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 LOGON-STRING         PIC X(40)          VALUE SPACES.
EXEC SQL
INCLUDE SQLCA
END-EXEC.
LINKAGE SECTION.
01  CONTEXT          SQL-CONTEXT.

PROCEDURE DIVISION USING CONTEXT.
MAIN SECTION.

*-----------------------------------------------------------------
* ALLOCATE CONTEXT AREAS ESTABLISH CONNECTION WITH EACH AREA.
*-----------------------------------------------------------------
ORACLE-CONNECTION SECTION.

MOVE "SCOTT/TIGER"  TO LOGON-STRING
EXEC SQL CONTEXT ALLOCATE :CONTEXT END-EXEC
IF SQLCODE NOT = ZERO
DISPLAY 'ERROR ALLOCATING CONTEXT '
'- ABORTING : ' SQLERRMC
GOBACK
ELSE
DISPLAY 'CONTEXT ALLOCATED'
END-IF

EXEC SQL CONTEXT USE :CONTEXT END-EXEC
EXEC SQL  CONNECT    :LOGON-STRING  END-EXEC
IF SQLCODE NOT = ZERO
DISPLAY 'ERROR CONNECTING SECOND THREAD TO THE DATABASE '
'- ABORT TEST : ' SQLERRMC
GOBACK
ELSE
DISPLAY 'CONNECTION ESTABLISHED'
END-IF
EXIT SECTION.

13 ラージ・オブジェクト(LOB)

この章では、埋込みSQL文により提供されるLOB (ラージ・オブジェクト)データ型のサポートについて記述します。4種類のLOB型を説明し、従来のLONGおよびLONG RAWデータ型と比較します。

Pro*COBOLの埋込みSQLインタフェースは、PL/SQL言語と同様の機能を提供します。

LOB文およびそのLOBオプションとホスト変数を説明します。

LOBインタフェースを使用したPro*COBOLによるプログラミング例を説明します。

内容は次のとおりです。

- LOBの使用

- LOBの使用方法

- LOB文のルール

- LOB文

- LOBサンプル・プログラム: LOBDEMO1.PCO

LOBの使用

LOB (ラージ・オブジェクト)とは、ASCIIテキスト、各国文字のテキスト、様々なグラフィック・フォーマットのファイルおよびサウンド波形などの大量のデータ(最大4GB)を格納するために使用されるデータベース型のことです。

内部LOB

内部LOB (BLOB、CLOB、NCLOB)はデータベースの表領域に格納されます。また、内部LOBでは、データベース・サーバーのトランザクション・サポートが有効です。(COMMIT、ROLLBACKなどを使用できます。)

BLOB(Binary LOB)には、ビデオ・クリップなどの非構造化バイナリ(「ロー」とも呼ばれます)・データが格納されます。

CLOB(Character LOB)には、データベース・キャラクタ・セットの文字列データのラージ・ブロックが格納されます。

NCLOB(National Character LOB)には、各国語キャラクタ・セットの文字列データのラージ・ブロックが格納されます。

外部LOB

外部LOBは、データベース表領域外のオペレーティング・システム・ファイルです。ただし、データベース・サーバーのトランザクション・サポートは無効です。

BFILE(Binary Files)では、データは外部バイナリ・ファイルの形式で格納されます。BFILEでは、GIF、JPEG、MPEG、MPEG2、テキストなどのフォーマットを扱うことができます。

BFILEのセキュリティ

DIRECTORYオブジェクトは、BFILEに対するアクセスや使用のために使用します。DIRECTORYは、ファイルが格納されているサーバー・ファイル・システムの実際の物理ディレクトリの(サーバーに格納されている)論理的な別名です。DIRECTORYオブジェクトに対するアクセス権限が割り当てられているユーザー以外は、ファイルにアクセスできません。

BFILEで使用できるSQL文は、次の2種類です。

- データ定義言語(DDL) SQL文のCREATE、REPLACE、ALTERおよびDROP。

- DIRECTORYオブジェクト上のシステムおよびオブジェクトに対するREAD権限のGRANTおよびREVOKEを行うデータ操作言語(DML)SQL文。

CREATE DIRECTORYディレクティブの例を、次に示します。

EXEC SQL CREATE OR REPLACE DIRECTORY "Mydir" AS '/usr/home/mydir' END-EXEC.

ユーザーまたはロールは、GRANTなどのデータ操作言語(DML)文の権限が割り当てられている場合にのみ、ディレクトリを読み込むことができます。たとえば、ユーザーscottがディレクトリ/usr/home/mydirのBFILESを読み込めるようにするには次のようにします。

EXEC SQL GRANT READ ON DIRECTORY "Mydir" TO scott END-EXEC.

1セッション内で、最大10個のBFILESを同時にオープンできます。SESSION_MAX_OPEN_FILESパラメータの設定を変更して、デフォルト値を変更できます。

DIRECTORYオブジェクト、BFILEセキュリティおよびGRANTコマンドの詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

LOBとLONGおよびLONG RAWの比較

LOBは、従来のLONGおよびLONG RAWデータ型と多くの点で異なります。

- LOBの最大サイズは4GBです。LONGおよびLONG RAWの最大サイズは2GBです。

- LOBでは、ランダム・アクセス方法および順次アクセス方法を使用できます。LONGおよびLONG RAWでは、順次アクセス方法のみです。

- LOB (NCLOBは除きます)は、定義したオブジェクト型の属性になります。

- 表では複数のLOB列を作成できますが、複数のLONGまたはLONG RAW列は作成できません。

既存のLONGおよびLONG RAW属性は、LOBに移行することをお薦めします。今後のリリースでは、LONGおよびLONG RAWはサポートしない予定です。関連項目: 移行の詳細は『Oracle Databaseアップグレード・ガイド』を、LOBの詳細は『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。

LOBロケータ

LOBロケータによって、実際のLOB内容がポイントされます。ロケータはLOBの内容ではなくLOBを取り出したときに戻されます。LOBロケータは、特定のトランザクションまたはセッションには保存されずに、後続のトランザクションまたはセッションで再使用されます。

一時LOB

LOBデータベースを使用しやすくするために、一時LOBを作成できます。一時LOBはローカル変数に似ていますが、表には関連付けられていません。一時LOBを作成したユーザーのみがロケータを使用してアクセスでき、セッションが終了すると削除されます。

一時BFILEはサポートされていません。一時LOBはINSERT文のWHERE句、UPDATEのSET句、またはDELETE文のWHERE句の入力変数(IN値)としてのみ使用できます。一時LOBではデータベース・サーバーのトランザクション・サポートが無効なため、COMMITまたはROLLBACKを行うことはできません。

一時LOBロケータは、トランザクションをまたがって使用することができます。一時LOBは、サーバーが異常終了したとき、およびデータベースSQL操作からエラーが戻されたときは削除されます。

LOBバッファリング・サブシステム

LBS (LOB Buffering Subsystem)は、クライアントのアドレス空間で1つまたは複数のLOBバッファとして使用するためのユーザー・メモリー領域です。

バッファリングには次の利点があります。特に、LOBの特定領域に小規模な読取りおよび書込みを繰り返すクライアントのアプリケーションに有効です。

- LOBに対する複数の読取り/書込みをバッファに蓄積し、FLUSHディレクティブが実行されたときにサーバーに書き込むため、LBSによってサーバーへのラウンドトリップが減少します。

- サーバー上でのLOBの合計更新数が減少します。この結果、LOBのパフォーマンスが向上し、ディスク領域が節約されます。

このバッファリングは、簡単なバッファ・サブシステムで、キャッシュではありません。バッファの内容が、サーバーのLOB値と常に同期しているとはかぎりません。サーバーのLOBに実際に更新を書き込むには、FLUSH文を使用します。

LOBのバッファへの読取り/書込みは、ロケータを使用して実行されます。バッファリングが使用可能なロケータを使用すると、書込みを実行するまで、LOBを常に読み込むことができます。

ロケータは、WRITEのバッファに使用された後で更新され、バッファリング・サブシステムを介して表示できる最新のLOBに対するアクセス権限が割り当てられます。これ以降のバッファされたLOBへのWRITEは、更新されたロケータを使用しないとできません。バッファされたLOBの操作を行うトランザクションは、ユーザー・セッション間では移行できません。

LBSは、サーバーのLOB値をFLUSH文を使用して更新するユーザーが管理します。LBSは、シングル・ユーザーでシングル・スレッドです。サーバーLOBの妥当性を確保するには、ROLLBACKおよびSAVEPOINTアクションを使用します。バッファされたLOB操作のトランザクション・サポートは無効です。バッファされたLOB更新のトランザクション・セマンティクスを確保するには、エラー発生時にロールバックを行う論理セーブポイントをメンテナンスする必要があります。

LBSの詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

LOBの使用方法

Pro*COBOLからLOBにアクセスするには、次の2つの方法があります。

- PL/SQLブロックのDBMS_LOBパッケージ。

- 埋込みSQL文。

埋込みSQL文は、PL/SQLインタフェースと同じ機能を使用できるように設計されています。

次の表では、PL/SQLからのLOBアクセスおよびPro*COBOLの埋込みSQL文を比較します。ハイフンは、機能がないことを示します。

表13-1 LOBへのアクセス方法

PL/SQL脚注 1

Pro*COBOLの埋込みSQL

COMPARE()

-

INSTR()

-

SUBSTR()

-

APPEND()

APPEND

:=

ASSIGN

CLOSE()

CLOSE

COPY()

COPY

CREATETEMPORARY()

CREATE TEMPORARY

-

DISABLE BUFFERING

-

ENABLE BUFFERING

ERASE()

ERASE

GETCHUNKSIZE()

DESCRIBE

ISOPEN()

DESCRIBE

FILECLOSE()

CLOSE

FILECLOSEALL()

FILE CLOSE ALL

FILEEXISTS()

DESCRIBE

FILEGETNAME()

DESCRIBE

FILEISOPEN()

DESCRIBE

FILEOPEN()

OPEN

BFILENAME()

FILE SET脚注 2

-

FLUSH BUFFER

FREETEMPORARY()

FREE TEMPORARY

GETLENGTH()

DESCRIBE

=

-

ISTEMPORARY()

DESCRIBE

LOADFROMFILE()

LOAD FROM FILE

OPEN()

OPEN

READ()

READ

TRIM()

TRIM

WRITE()

WRITE

WRITEAPPEND()

WRITE

脚注 1 dbmslob.sqlからコールします。BFILENAMEを除くルーチンの前には、すべて'DBMS_LOB'を付ける必要があります。

脚注 2 SQL関数に組み込まれているBFILENAME()も使用できる場合があります。

注意:
新しい文を使用する前に、LOBに対して修正または変更する行を明示的にロックする必要があります。LOB値を修正する操作には、APPEND、COPY、ERASE、LOAD FROM FILE、TRIMおよびWRITEがあります。

アプリケーションでのLOBロケータ

Pro*COBOLアプリケーションでLOBロケータを使用するには、次の擬似タイプを使用します。

- SQL-BLOB

- SQL-CLOB

- SQL-NCLOB

- SQL-BFILE

MY-NCLOBと呼ばれるNCLOB変数を宣言するには、次のようにします。

01  MY-NCLOB    SQL-NCLOB.

LOBの初期化

この項では、様々なLOBの初期化方法を説明します。

内部LOB

BLOBを初期化して空にするには、EMPTY_BLOB()関数またはALLOCATE SQL文を使用します。CLOBおよびNCLOBには、EMPTY_CLOB()関数を使用します。EMPTY_BLOB()およびEMPTY_CLOB()の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。これらの関数は、INSERT文のVALUES句内またはUPDATE文のSET句のソースでのみ使用できます。

次に例を示します。

EXEC SQL INSERT INTO lob_table (a_blob, a_clob)
VALUES (EMPTY_BLOB(), EMPTY_CLOB()) END-EXEC.

ALLOCATE文は、LOBロケータを割り当て、初期化して空にします。次のコードは、前の例と同じです。

...
01  A-BLOB      SQL-BLOB.
01  A-CLOB      SQL-CLOB.
...
EXEC SQL ALLOCATE :A-BLOB END-EXEC.
EXEC SQL ALLOCATE :A-CLOB END-EXEC.
EXEC SQL INSERT INTO lob_table (a_blob, a_clob)
VALUES (:A-BLOB, :A-CLOB) END-EXEC.

外部LOB

BFILEおよびFILENAMEのDIRECTORY別名を初期化するには、LOB FILE SET文を次のように使用します。

...
01  ALIAS        PIC X(14) VARYING.
01  FILENAME     PIC X(14) VARYING.
01  A-BFILE      SQL-BFILE.
...
MOVE "lob_dir" TO ALIAS-ARR.
MOVE 7 TO ALIAS-LEN.
MOVE "image.gif" TO FILENAME-ARR
MOVE 9 TO FILENAME-LEN..
EXEC SQL ALLOCATE :A-BFILE END-EXEC.
EXEC SQL LOB FILE SET :A-BFILE
DIRECTORY = :ALIAS, FILENAME = :FILENAME END-EXEC.
EXEC SQL INSERT INTO file_table (a_bfile) VALUES (:A-BFILE) END-EXEC.

DIRECTORYオブジェクトのネーミング規則およびDIRECTORYオブジェクト権限の詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

また、INSERTまたはUPDATE文のBFILENAME('ディレクトリ', 'ファイル名')機能を使用して、BFILE列または特定行の属性を初期化し、実際の物理ディレクトリおよびファイル名を取得できます。

EXEC SQL INSERT INTO file_table (a_bfile)
VALUES (BFILENAME('lob_dir', 'image.gif'))
RETURNING a_bfile INTO :A-BFILE END-EXEC.

注意:
BFILENAME()では、ディレクトリまたはファイル名の権限、および物理ディレクトリの有無は確認されません。BFILEロケータを使用してファイルにアクセスしたときに、これらが確認され、ファイルにアクセスできない場合にはエラーが戻されます。

一時LOB

埋込みSQLのLOB CREATE TEMPORARY文を使用して最初に一時LOBを作成したときに、一時LOBは初期化され空になります。EMPTY_BLOB()およびEMPTY_CLOB()関数は、一時LOBでは使用できません。

LOBの解放

ALLOCATE文で使用されるメモリーを解放するには、FREE文を使用します。

EXEC SQL FREE :A-BLOB END-EXEC.

LOB文のルール

LOB文を使用するときのルールを説明します。

すべてのLOB文に適用されるルール

次の一般的な制限および制約は、SQL LOB文を使用してLOBを操作するときに適用されます。

- 埋込みSQLのLOB文では、FOR句は使用できません。これらの文は、単一のLOBロケータのみ使用できます。ただし、ALLOCATEおよびFREE文では、FOR句を使用できます。

- 分散LOBはサポートされていません。新規の埋込みSQL LOB文であればATデータベース句を使用できますが、異なったデータベース接続を使用して作成または割り当てられたLOBロケータを、同一SQL LOB文内で併用することはできません。

LOBバッファリング・サブシステムに適用されるルール

LBSでは、次のルールに従う必要があります。

- 読取りまたは書込みアクセス時のエラーは、次回のサーバーへのアクセス時にレポートされます。このため、エラー・リカバリのコードは、ユーザーが作成する必要があります。

- バッファへの書込みによりLOBを更新するときは、必ずLOBバッファリング・サブシステムを経由して更新を行ってください。

- バッファリングが可能な更新済LOBロケータは、INパラメータとしてPL/SQLプロシージャに渡せますが、IN OUTあるいはOUTパラメータとしては渡すことはできません。エラーが戻されます。更新済ロケータを戻そうとしたときにも、エラーが戻されます。

- バッファリング可能な更新済ロケータを、別のロケータにはASSIGNできません。

- バッファへの書込みをLOB値に追加することができますが、その開始オフセットの1文字は、LOBの最後に続く必要があります。LBSでは、データベース・サーバーのLOBに、0バイトの充填文字または空白が入るAPPEND文は使用できません。

- ホスト・ロケータのバインド変数のキャラクタ・セットとデータベース・サーバーのCLOBは、同じであることが必要です。

- ASSIGN、READおよびWRITE文のみ、バッファリング可能なロケータとともに使用できます。

- バッファリング可能なロケータでAPPEND、COPY、ERASE、DESCRIBE (LENGTHのみ)、SELECTおよびTRIMの文を使用すると、エラーになります。また、これらの文をバッファリング不可能なロケータとともに使用した場合でも、そのロケータによってポイントされたLOBが他のロケータによってバッファ・モードでアクセスされた場合には、エラーが戻されます。

注意:
FLUSH文をLOBで使用するときは、次の処理の前に、LOBバッファリング・サブシステムでLOBが使用可能になっている必要があります。

- トランザクションのコミット。

- カレント・トランザクションから他のトランザクションへの移行。

- LOB上でのバッファ操作の使用禁止。

ホスト変数に適用されるルール

LOB文の場合、次のルールおよび注意を使用します。

- srcおよびdstを使用して、内部または外部LOBロケータを参照できますが、fileでは、外部ロケータ以外は参照できません。

- 数値のホスト値(amt、src_offset、dst_offsetなど)は、4バイトの整変数PIC S9(9) COMPとして宣言されます。値は、0から4GBに制限されています。

- NULLは、LOBロケータで使用します。LOB文では標識変数は必要ありません。NULLは、数値変数(amt、src_offsetなど)には使用できません。エラーが発生します。

- オフセット値src_offsetおよびdst_offsetのデフォルト値は1です。

注意:
変数BLOB、CLOBおよびNCLOBは、使用するプラットフォームの位置合せの要件に従って使用する必要があります。使用するプラットフォームの位置合せの制限の詳細は、そのプラットフォームのマニュアルを参照してください。

LOB文

アルファベット順に文を説明します。すべての説明文で、databaseはデータベース接続を示します。

APPEND

用途

APPEND文では、別のLOBの最後にLOB値を追加します。

構文

EXEC SQL [AT [:]database] LOB APPEND :src TO :dst END-EXEC.

ホスト変数

src (IN):

ソースLOBを一意に参照する内部LOBロケータ。

dsc (IN OUT):

宛先LOBを一意に参照する内部LOBロケータ。

使用上の注意

ソースLOBのデータが宛先LOBの最後にコピーされると、宛先LOBが最大4GBまで拡張されます。LOBが4GBを超えて拡張される場合は、エラーが発生します。

ソースおよび宛先LOBは、すでに存在している必要があります。また、宛先LOBは初期化されている必要があります。

ソースおよび宛先LOBの両方が、同じ内部LOB型であることが必要です。どちらのロケータに対しても、LOBバッファリングを有効にすると、エラーとなります。

ASSIGN

用途

LOBまたはBFILEロケータを、別のロケータに割り当てます。

構文

EXEC SQL [AT [:]database] LOB ASSIGN :src to :dst END-EXEC.

ホスト変数

src (IN):

コピー元のLOBまたはBFILEロケータ・ソース。

dsc (IN OUT):

コピー先のLOBまたはBFILEロケータ。

使用上の注意

割当て後は、両方のロケータが同じLOB値を参照します。宛先LOBロケータは、有効な初期化された(割り当てられた)ロケータであることが必要です。

内部LOBでは、宛先ロケータが表に格納されている場合にのみ、ソース・ロケータのLOB値が宛先ロケータのLOB値にコピーされます。Pro*COBOLでは、宛先ロケータを格納しているオブジェクトのFLUSHを発行すると、LOB値をコピーします。

BFILEロケータが内部LOBロケータに割り当てられている場合、またはその逆の場合には、エラーが戻されます。src LOBとdst LOBが同じ型でない場合にもエラーになります。

ソース・ロケータがバッファリング可能な内部LOB用であり、かつLOBバッファリング・サブシステムを介してLOB値を変更するために使用されていた場合、またバッファがWRITE後にフラッシュされていない場合には、ソース・ロケータを宛先ロケータに割り当てることはできません。これは、LOBバッファリング・サブシステムを介してLOB値を修正する場合、1つのLOBに対してロケータは1つしか使用できないためです。

CLOSE

用途

オープンされているLOBまたはBFILEをクローズします。

構文

EXEC SQL [AT [:]database] LOB CLOSE :src END-EXEC.

ホスト変数

src (IN OUT):

クローズされるLOBまたはBFILEのロケータ。

使用上の注意

異なるロケータまたは同一ロケータを使用した場合でも、同一LOBを2回クローズするとエラーになります。外部LOBの場合は、BFILEが存在して一度もオープンされていない状態であれば、エラーは発生しません。

オープンしていたLOBをすべてクローズする前に、トランザクションをCOMMITするとエラーになります。トランザクションのROLLBACK時にオープンしているLOBは、クローズされず、すべて破棄されます。

COPY

用途

LOB値の全部または一部を別のLOBにコピーします。

構文

EXEC SQL [AT [:]database] LOB COPY :amt FROM :src [AT :src_offset]
TO :dst [AT :dst_offset] END-EXEC.

ホスト変数

amt (IN): コピーするBLOBの最大バイト数またはCLOBおよびNCLOBの文字数。

src (IN): ソースLOBのロケータ。

src_offset (IN): CLOBまたはNCLOBの文字数、およびBLOBのバイト数。LOBの先頭で1から始まります。

dst (IN): 宛先LOBのロケータ。

dst_offset (IN): 宛先オフセット。src_offsetと同じルールが適用されます。

使用上の注意

データが宛先のオフセット以降にあらかじめ存在する場合は、ソース・データで上書きされます。宛先のオフセットがカレント・データの最後を超えている場合は、宛先LOBのカレント・データの最後から新しく書き込まれたソース・データの先頭まで、ゼロバイト充填文字(BLOB)または空白(CLOB)が書き込まれます。

新しく書き込まれるデータが宛先LOBの現行の長さを超えている場合は、そのデータを格納できるように宛先LOBが拡張されます。4GBを超えてLOBが拡張されると、ランタイム・エラーが発生します。

初期化されていないLOBからコピーすると、エラーになります。

ソースLOBおよび宛先LOBは、同じ型である必要があります。LOBバッファリングは、両方のロケータに対して使用可能にしないでください。

一時LOBを永続LOBにするには、COPY文を使用して、一時LOBを永続LOBに明示的にCOPYする必要があります。amt変数はコピーする最大量を示します。指定した量がコピーされる前にソースLOBの最後に到達した場合、エラーを発行せずに操作が終了します。

CREATE TEMPORARY

用途

一時LOBを作成します。

構文

EXEC SQL [AT [:]database] LOB CREATE TEMPORARY :src END-EXEC.

ホスト変数

src (IN OUT): 実行前でINのときは、srcは事前に割り当てられたLOBロケータです。

実行後でOUTになったときは、srcは新しい空の一時LOBをポイントするLOBロケータです。

使用上の注意

実行が正常に終了すると、ロケータはデータベース・サーバーに新しく作成された、表に依存しない一時LOBをポイントします。一時LOBは空で、長さゼロです。

セッション終了時に、すべての一時LOBは解放されます。一時LOBへの読取りおよび書込みは、バッファ・キャッシュを経由しません。

DISABLE BUFFERING

用途

LOBロケータのLOBバッファリングを使用禁止にします。

構文

EXEC SQL [AT [:]database] LOB DISABLE BUFFERING :src END-EXEC.

ホスト変数

src(IN OUT): 内部LOBロケータ。

使用上の注意

この文は、BFILEをサポートしていません。後続の読取りまたは書込みは、LBS経由では行われません。

注意: 変更を永続的なものにするには、FLUSH BUFFERコマンドを使用してください。DISABLE BUFFERING文は、LOBバッファリング・サブシステムが作成した変更を、暗黙的にフラッシュすることはありません。

ENABLE BUFFERING

用途

LOBロケータのLOBバッファリングを使用可能にします。

構文

EXEC SQL [AT [:]database] LOB ENABLE BUFFERING :src END-EXEC.

ホスト変数

src(IN OUT): 内部LOBロケータ。

使用上の注意

この文は、BFILEをサポートしていません。後続の読取りおよび書込みは、LBSを経由して行われます。

ERASE

用途

指定されたオフセットから始まる、指定された量のLOBデータを消去します。

構文

EXEC SQL [AT [:]database] LOB ERASE :amt
FROM :src [AT :src_offset] END-EXEC.

ホスト変数

amt (IN OUT): 入力は、消去するバイト数または文字数です。戻される出力は、実際に消去されたバイト数または文字数です。

src(IN OUT): 内部LOBロケータ。

src_offset (IN): LOBの開始からのオフセット。1から指定できます。

使用上の注意

この文は、BFILEをサポートしていません。

実行後、消去された実際の文字数またはバイト数がamtから戻されます。要求した文字数またはバイト数を消去する前にLOB値の最後に到達した場合は、実際の消去数と要求した消去数は異なります。LOBが空の場合は、amtは0文字または0バイトが消去されたことを示します。

BLOBの場合は、消去とはゼロバイト充填文字で既存のLOB値を上書きすることです。CLOBの場合は、空白で既存のLOB値を上書きすることです。

FILE CLOSE ALL

用途

カレント・セッションでオープンしているBFILESをすべてクローズします。

構文

EXEC SQL [AT [:]database] LOB FILE CLOSE ALL END-EXEC.

使用上の注意

適切にクローズされなかったオープン・ファイルがセッションに存在する場合は、FILE CLOSE ALL文を使用して、セッションでオープンしているファイルをすべてクローズし、ファイル操作を始めから再開できます。

FILE SET

用途

BFILEロケータのDIRECTORY別名およびFILENAMEを設定します。

構文

EXEC SQL [AT [:]database] LOB FILE SET :file
DIRECTORY = :alias, FILENAME = :filename END-EXEC.

ホスト変数

file (IN OUT): DIRECTORY別名およびFILENAMEを設定するBFILEロケータ。

alias (IN): 設定するDIRECTORY名。

filename (IN): 設定するFILENAME。

使用上の注意

指定したBFILEロケータは、この文で使用する前に、ALLOCATEされている必要があります。

DIRECTORY別名およびFILENAMEは必須項目です。

DIRECTORY別名の最大長は30バイトです。FILENAMEの最大長は255バイトです。

DIRECTORY別名およびFILENAME属性がサポートされている外部データ型は、VARCHAR、VARCHAR2およびCHARFのみになります。

この文を外部LOBロケータ以外で使用すると、エラーになります。

FLUSH BUFFER

用途

LOBのバッファをデータベース・サーバーに書き込みます。

構文

EXEC SQL [AT [:]database] LOB FLUSH BUFFER :src [FREE] END-EXEC.

ホスト変数

src (IN OUT): 内部LOBロケータ。

使用上の注意

入力ロケータが参照するLOBからサーバーのデータベースLOBに、バッファ・データを書き込みます。

LOBバッファリングは、入力LOBロケータに対してすでに有効になっている必要があります。

デフォルトでのFLUSH操作では、バッファ・リソースの解放および別のバッファされたLOB操作への再割当ては行われません。ただし、バッファを明示的に解放する場合は、オプションのFREEキーワードを使用して指定できます。

FREE TEMPORARY

用途

LOBロケータ用に一時領域を解放します。

構文

EXEC SQL [AT [:]database] LOB FREE TEMPORARY :src END-EXEC.

ホスト変数

src (IN OUT): 一時LOBをポイントするLOBロケータ。

使用上の注意

入力ロケータは、一時LOBをポイントしている必要があります。出力ロケータは、初期化されずに、後続のLOB文で使用されます。

LOAD FROM FILE

用途

BFILEの一部または全部を、内部LOBにコピーします。

構文

EXEC SQL [AT [:]database] LOB LOAD :amt
FROM FILE :file [AT :src_offset] INTO :dst [AT :dst_offset] END-EXEC.

ホスト変数

amt (IN): ロードする最大バイト数。

file (IN OUT): ソースのBFILEロケータ。

src_offset (IN): ファイルの先頭からのオフセット・バイト数。1から指定できます。

dst (IN OUT): 宛先LOBロケータ。BLOB、CLOBおよびNCLOBが有効です。

dst_offset (IN): 書込みが開始する宛先LOBの先頭からのバイト数(BLOBの場合)または文字数(CLOBおよびNCLOBの場合)です。1から始まります。

使用上の注意

データは、ソースBFILEから宛先内部LOBにコピーされます。BFILEデータをCLOBまたはNCLOBにコピーする場合、キャラクタ・セットは変換されません。このため、BFILEデータは、あらかじめデータベース内のCLOBまたはNCLOBと同じキャラクタ・セットになっている必要があります。

ソースおよび宛先LOBは、すでに存在している必要があります。宛先の開始位置にすでにデータがある場合は、ソース・データで上書きされます。宛先の開始位置が現行データの最後を超えている場合は、ゼロバイト充填文字(BLOB)または空白(CLOBおよびNCLOB)が、宛先LOBのデータの最後からソースによって新しく書き込まれたデータの先頭まで書き込まれます。

新しく書き込まれるデータが宛先LOBの現行の長さを超えている場合は、そのデータを格納できるように宛先LOBが拡張されます。4GBを超えてLOBが拡張されると、エラーになります。

また、初期化されていないBFILEからコピーをすると、エラーになります。

amountパラメータは、ロードする最大量を示します。指定した量がロードされる前にソースBFILEの最後に到達した場合は、エラーを発行せずに操作が終了します。

OPEN

用途

読取り、または読取り/書込みアクセスのために、LOBまたはBFILEをオープンします。

構文

EXEC SQL [AT [:]database] LOB OPEN :src
[ READ ONLY | READ WRITE ] END-EXEC.

ホスト変数

src (IN OUT): LOBまたはBFILEのLOBロケータ。

使用上の注意

デフォルト・モードでは、LOBまたはBFILEはREAD ONLYアクセスでオープンされます。

内部LOBの場合は、OPENはロケータではなくLOBに対応付けられます。すでにオープンしているロケータを別のロケータに割り当てても、新規LOBのOPENとしてはカウントされません。両方のロケータから同じLOBが参照されます。BFILEの場合は、OPENはロケータに対応付けられます。

同時にOPENできるLOBの最大数は32個です。33個目のLOBをオープンすると、エラーが戻されます。

書込み可能なBFILEは、サポートしていません。このため、BFILEをREAD WRITEモードでOPENすると、エラーが戻されます。

LOBをREAD ONLYモードでオープンした後にWRITEすると、エラーになります。

READ

用途

LOBまたはBFILEの一部または全部をバッファに読み込みます。

構文

EXEC SQL [AT [:]database] LOB READ :amt FROM :src [AT :src_offset]
INTO :buffer [WITH LENGTH :buflen] END-EXEC.

ホスト変数

amt (IN OUT): 入力は、読み込む文字数またはバイト数です。出力は、読み込まれた実際の文字数またはバイト数です。

読み込まれたバイト数がバッファ長より大きい場合は、LOBはポーリング・モードで読み込まれているとみなされます。入力時にこの値がゼロの場合は、データは入力オフセットからLOBの最後までポーリング・モードで読み込まれます。

実際に読み込まれるバイト数または文字数はamtで戻されます。データがピース単位で読み込まれる場合、amtには常に最後に読み込まれたピースが含まれます。

LOBの最後に到達すると、「ORA-01403: データが見つかりません。」というエラーが発行されます。

ポーリング・モードで読み込むときは、アプリケーションからLOB READを繰り返しコールし、データがなくなるまでLOBのピースを読み込む必要があります。ORA-01403エラーを捕捉するには、WHENEVERディレクティブでNOT FOUND条件を使用してポーリング・モードを制御してください。

src (IN): LOBまたはBFILEロケータ。

src_offset (IN): これは読込みを開始したLOB値の先頭からの絶対オフセットです。キャラクタLOBにおいては、これはLOBの先頭からの文字数を意味します。バイナリLOBまたはBFILEにおいては、これはバイト数を意味します。最初の位置は1です。

buffer (IN OUT): LOBデータが読み込まれるバッファ。バッファの外部データ型は、ソースLOBの型によって一定の型に制限されます。バッファの最大長は、LOB値を格納するために使用される外部データ型によって決まります。次の表は、有効な外部データ型、およびそのソースLOB型ごとの最大長のリストです。

表13-2 ソースLOBおよびプリコンパイラのデータ型

外部LOB脚注 1

内部LOB

プリコンパイラの外部データ型

プリコンパイラの最大長脚注 2

PL/SQLデータ型

PL/SQL最大長

BFILE

BLOB

RAW

VARRAW

LONG RAW

LONG VARRAW

65535

65533

2147483647

2147483643

RAW

32767

-

CLOB

VARCHAR2

VARCHAR

LONG VARCHAR

65535

65533

2147483643

VARCHAR2

32767

-

NCLOB

NVARCHAR2

4000

NVARCHAR2

4000

脚注 1 これらの外部データ型は、BFILEで使用できます。

脚注 2  長さは、文字単位ではなく、バイト単位で計算されています。

buflen (IN): 他の方法で長さがわからない場合は、指定したバッファの長さを指定します。

使用上の注意

BFILEは、データベース・サーバーにすでに存在し、入力ロケータを使用してオープンされている必要があります。データベースにはファイルの読取り権限が必要で、ユーザーにはディレクトリの読取り権限が必要になります。

初期化されていないLOBまたはBFILEからの読込みは、エラーとなります。

バッファの長さは、次のように決定されます。

- WITH LENGTH句を指定した場合の、buflenの値。

- WITH LENGTH句を指定しなかった場合は、「文字データの処理」のルールに従ってバッファ・ホスト変数をOUTモードで処理すると長さが決定します。

TRIM

用途

LOB値を切り捨てます。

構文

EXEC SQL [AT [:]database] LOB TRIM :src TO :newlen END-EXEC.

ホスト変数

src (IN OUT): 内部LOB用のLOBロケータ。

newlen (IN): LOB値の新規の長さ。

使用上の注意

この文はBFILEには使用できません。新規の長さは、現行の長さより大きくは設定できません。大きく設定した場合は、エラーが戻されます。

WRITE

用途

バッファの内容をLOBに書き込みます。

構文

EXEC SQL [AT [:]database] LOB WRITE [APPEND] [ FIRST | NEXT | LAST | ONE ]
:amt FROM :buffer [WITH LENGTH :buflen]
INTO :dst [AT :dst_offset] END-EXEC.

ホスト変数

amt (IN OUT): 入力は、書き込む文字数またはバイト数です。

出力は、書き込まれた実際の文字数またはバイト数です。

ポーリング・メソッドを使用して書込みをした場合は、WRITE LAST文の実行後に、WRITE文実行時に書き込まれた累積合計長がamtから戻されます。WRITE文が中断された場合は、amtは定義されません。

buffer (IN): LOBデータの書込み元のバッファ。データ型の長さについては、「READ」を参照してください。

dst (IN OUT): LOBロケータ。

dst_offset (IN): LOBの先頭からのオフセット(1から始まります)。文字単位の場合はCLOBおよびNCLOB、バイト単位の場合はBLOB。

buflen (IN): 他の方法で計算できなかった場合のバッファ長。

使用上の注意

LOBデータがすでに存在する場合は、バッファに格納されているデータで上書きされます。指定されたオフセットが、現在LOB内にあるデータの最後を超える場合は、ゼロバイト充填文字または空白がLOBに挿入されます。

WRITE文にキーワードAPPENDを指定すると、LOBの最後にデータが自動的に書き込まれます。APPENDを指定すると、宛先オフセットがLOBの最後とみなされます。WRITE文にAPPENDオプションを指定したときに、宛先オフセットを指定するとエラーになります。

バッファは、LOBに対して1ピースで書き込まれるか(デフォルトのONE方向変換を使用します)、標準のポーリング・メソッドを使用してピース単位で書き込むことができます。

FIRSTを使用してポーリングを開始し、NEXTで後続のピースを書き込みます。LASTキーワードは、書込みを終了する最後のピースの書込みに使用します。

このピース単位の書込みモードを使用すると、各ピースのサイズおよび場所が異なる場合に、バッファおよびバッファ長をコール単位に指定できます。

すべての書込みの終了後に渡される合計データ量が、amtパラメータで指定した量よりも少ない場合は、エラーになります。

同じルールが、READ文のバッファ長の決定にも適用されます。詳細は、「READ」を参照してください。

DESCRIBE

用途

この文は、いくつかのOCIおよびPL/SQL文と同等です。LOB DESCRIBE SQL文を使用してLOBから属性を取り出します。LOB DESCRIBE文の書式は次のとおりです。

構文

EXEC SQL [AT [:]database] LOB DESCRIBE :src GET attribute1 [{, attributeN}]
INTO :hv1 [[INDICATOR] :hv_ind1] [{, :hvN [[INDICATOR] :hv_indN] }]
END-EXEC.

次の属性を指定できます。

CHUNKSIZE | DIRECTORY | FILEEXISTS | FILENAME | ISOPEN | ISTEMPORARY | LENGTH

ホスト変数

src (IN): 内部または外部LOBのLOBロケータ。

hv1 ... hvN (OUT): 属性名リストで指定された順番で、属性値を受け取るホスト変数。

hv_ind1 ... hv_indN (OUT): 属性名リストの順番で、NULL状態のインジケータを受け取るオプションのホスト変数。

次の表では、関連するLOBの属性および読込みが必要なCOBOL型を説明します。

表13-3 LOB属性

LOB属性

属性の説明

制限

COBOL型

CHUNKSIZE

LOB値の格納に使用される、指定された表領域ブロックに対する最適なスペース量(BLOBの場合はバイト、CLOBおよびNCLOBの場合は文字)です。チャンク・サイズは固定値ではなく、利用可能なチャンク・サイズに基づいた最大限の値が記憶域に利用されます。同一ページまたは同一ページ・セットで複数のWRITEリクエストを行った場合、データはコミット時のみディスクに書き込まれ、単一の変更として扱われます。これにより、より大きなチャンク・サイズでデータを書き込むことができます。

BLOB、CLOBおよびNCLOBのみ

PIC S9(9) COMP

DIRECTORY

BFILEの場合は、DIRECTORY別名。長さnは、1から30バイトです。実際の長さを使用します。

FILE LOBのみ

PIC X(n) [VARYING]

FILEEXISTS

BFILEが、サーバーのオペレーティング・システムのファイル・システム上に存在するかどうかを決定します。ゼロ以外の場合は、FILEEXISTは真、ゼロの場合は、偽です。

FILE LOBのみ

PIC S9(9) COMP

FILENAME

BFILEの名前。長さnは、1から255バイトです。実際の長さを使用します。

FILE LOBのみ

PIC X(n) [VARYING]

ISOPEN

BFILEの場合は、入力BFILEロケータがOPEN文で使用されなかった場合は、このロケータからはOPENされていないものとみなされます。ただし、別のBFILEロケータによって、BFILEがOPENされていることもあります。複数のロケータを使用して、同一BFILE上で複数のOPENを実行することもできます。LOBの場合は、別のロケータを使用してLOBをオープンしても、LOBは入力ロケータによってOPENされているとみなされます。ゼロ以外の場合は、ISOPENは真、ゼロの場合は、偽です。

-

PIC S9(9) COMP

ISTEMPORARY

入力LOBロケータが一時LOBを参照するかどうかを決定します。ゼロ以外の場合は、ISTEMPORARYは真、ゼロの場合は、偽です。

BLOB、CLOBおよびNCLOBのみ

PIC S9(9) COMP

LENGTH

BLOBおよびBFILEの長さはバイト数単位、CLOBおよびNCLOBの長さは文字数単位で表されます。BFILEの場合、EOFが存在するときは、EOFも長さに含まれます。空の内部LOBは、ゼロ長になります。初期化されていないLOBおよびBFILEの長さは、定義されません。

-

PIC 9(9) COMP

使用上の注意

標識変数は、PIC S9(4) COMPとして宣言する必要があります。実行完了後、SQLERRD(3)には、エラーなしに取り出された属性の数が格納されます。実行エラーが発生した場合は、エラーが発生した属性の数はSQLERRD(3)の内容より1だけ多くなっています。

DESCRIBEの例

指定されたBFILEから、DIRECTORYおよびFILENAME属性を抽出する簡単なPro*COBOLの例です。

...
01  A-BFILE      SQL-BFILE.
01  DIRECTORY    PIC X(30) VARYING.
01  FILENAME     PIC X(30) VARYING.
01  D-IND        PIC S9(4) COMP.
01  F-IND        PIC S9(4) COMP.
01  FEXISTS      PIC S9(9) COMP.
01  ISOPN        PIC S9(9) COMP.
...

最後に、いくつかのLOB表からBFILEロケータを選択し、DESCRIBEします。

EXEC SQL ALLOCATE :A-BFILE END-EXEC.
EXEC SQL INSERT INTO lob_table (a_bfile) VALUES (BFILENAME ('lob.dir',
'image.gif')) END-EXEC.
EXEC SQL SELECT a_bfile INTO :A-BFILE FROM lob_table WHERE ... END-EXEC.
EXEC SQL DESCRIBE :A-BFILE GET DIRECTORY, FILENAME, FILEEXISTS, ISOPEN
INTO :DIRECTORY:D-IND, :FILENAME:F-IND, FEXISTS, ISOPN ND-EXEC.

標識変数は、DIRECTORYおよびFILENAME属性を使用するときにのみ有効です。これらの属性は文字列なので、値が格納されるホスト変数バッファの大きさが不足している場合は、値が切り捨てられることがあります。切捨てが発生した場合は、インジケータの値には属性の元の長さが設定されます。

ポーリング・メソッドを使用したREADおよびWRITE

ポーリング・メソッドでREADを行うときの例です。

最初のLOB READで量にゼロを設定(または読み込まれる全データのサイズ量を設定)し、読込みポーリングを開始します。次の例では、この量にゼロが初期設定されます(詳細は省略してあります)。

EXEC SQL ALLOCATE :CLOB1 END-EXEC.

EXEC SQL WHENEVER NOT FOUND GOTO END-OF-CLOB END-EXEC.

EXEC SQL SELECT A_CLOB INTO :CLOB1 FROM LOB_TABLE WHERE ... END-EXEC.

MOVE 0 TO AMT.
EXEC SQL LOB READ :AMT FROM :VLOB1 AT :OFFSET INTO :BUFFER END-EXEC.

READ-LOOP.
EXEC SQL LOB READ :AMT FROM :CLOB1 INTO BUFFER $END-EXEC.
GO TO READ-LOOP.

END-OF-CLOB.
EXEC SQL WHENEVER NOT FOUND CONTINUE END-EXEC.

EXEC SQL FREE :CLOB1 END-EXEC.

次のコードは、バッファから内部CLOBへのデータの書込みの例です。初期書込み文のAMT (16文字)値は、書き込むデータ全体の長さと同じである必要があります。バッファの長さは5文字です。

初期読取りでEOFが読み取られた場合は、LOB WRITE ONEが行われます。EOFが読み込まれなかった場合は、バッファのLOB WRITE FIRSTによってポーリングが開始されます。データが読み込まれ、出力としてLOB WRITE NEXTが行われます。最後の書込みの後でデータが書き込まれるため、LOB WRITE NEXTにはオフセットは必要ありません。EOFが読み取られると、読取りループが終了し、LOB WRITE LASTが行われます。戻された量は、量の初期値(16)と等しくなっている必要があります。

MOVE 16 TO AMT.
PERFORM READ-NEXT-RECORD.
MOVE INREC TO BUFFER-ARR.
MOVE 5 TO BUFFER-LEN.
IF (END-OF-FILE = "Y")
EXEC SQL LOB WRITE ONE :AMT FROM :BUFFER INTO CLOB1
AT :OFFSET END-EXEC.
PERFORM DISPLAY-CLOB
ELSE
EXEC SQL LOB WRITE FIRST :AMT FROM :BUFFER INTO :CLOB1
AT :OFFSET END-EXEC.
PERFORM READ-NEXT-RECORD.
PERFORM WRITE-TO-CLOB
UNTIL END-OF-FILE = "Y".
MOVE INREC TO BUFFER-ARR.
MOVE 1 TO BUFFER-LEN.
EXEC SQL LOB WRITE LAST :AMT FROM :BUFFER INTO :CLOB1 END-EXEC.
PERFORM DISPLAY-CLOB.
...
WRITE-TO-CLOB.
MOVE INREC TO BUFFER-ARR.
MOVE 5 TO BUFFER-LEN.
EXEC SQL LOB WRITE NEXT :AMT FROM :BUFFER INTO :CLOB1 END-EXEC.
PERFORM READ-NEXT RECORD.

READ-NEXT-RECORD.
MOVE SPACES TO INREC.
READ INFILE NEXT RECORD
AT END
MOVE "Y" TO END-OF-FILE.
...

LOBサンプル・プログラム: LOBDEMO1.PCO

プログラムLOBDEMO1.PCOは、いくつかのLOB埋込みSQL文の例です。ソース・コードは、demoディレクトリ内にあります。このアプリケーションでは、社会保障番号列、名前列および交通違反の集計が格納されているCLOB列で構成されるlicense_tableという表を使用します。標準的な自動車部門の簡単なSQL操作を、いくつかモデル化します。

発生する可能性のあるアクションを示します。

- 新しいレコードを追加します。

- 社会保障番号別のレコード・リストを出力します。

- 特定の社会保障番号で指定して、レコード情報のリストを出力します。

- 既存のCLOBの内容に新しい交通違反を追加します。

LOBDEMO1.PCOの内容は次のとおりです。

*********************************************************************
* LOB Demo 1: DMV Database                                          *
*                                                                   *
* SCENARIO:                                                         *
*                                                                   *
* We consider the example of a database used to store driver's      *
* licenses. The licenses are stored as rows of a table containing   *
* three columns: the sss number of a person, his/her name and the   *
* text summary of the info found in his license.                    *
*                                                                   *
* The sss number and the name are the unique social security number *
* and name of an individual.  The text summary is a summary of the  *
* information on the individual, including his driving record,      *
* which can be arbitrarily long and may contain comments and data   *
* regarding the person's driving ability.                           *
*                                                                   *
* APPLICATION OVERVIEW:                                             *
*                                                                   *
* This example demonstrate how a Pro*COBOL client can handle the    *
* new LOB datatypes.  Demonstrated are the mechanisms for accessing *
* and storing lobs to/from tables.                                  *
*                                                                   *
*  To run the demo:                                                 *
*                                                                   *
*  1. Execute the script, lobdemo1.sql in Server Manager            *
*  2. Precompile using Pro*COBOL                                    *
*       procob lobdemo1                                             *
*  3. Compile/Link (This step is platform specific)                 *
*                                                                   *
* lobdemo1.sql contains the following SQL statements:               *
*                                                                   *
* connect scott/tiger;                                              *
*                                                                   *
* drop table license_table;                                         *
*                                                                   *
* create table license_table(                                       *
* sss char(9),                                                      *
* name varchar2(50),                                                *
* txt_summary clob);                                                *
*                                                                   *
* insert into license_table                                         *
*  values('971517006', 'Dennis Kernighan',                          *
*  'Wearing a Bright Orange Shirt');                                *
*                                                                   *
* insert into license_table                                         *
*  values('555001212', 'Eight H. Number',                           *
*  'Driving Under the Influence');                                  *
*                                                                   *
* insert into license_table                                         *
*  values('010101010', 'P. Doughboy',                               *
*  'Impersonating An Oracle Employee');                             *
*                                                                   *
* insert into license_table                                         *
*  values('555377012', 'Calvin N. Hobbes',                          *
*  'Driving Under the Influence');                                  *
*                                                                   *
* The main program provides the menu of actions that can be         *
* performed.  The program stops when the number 5 (Quit) option     *
* is entered.  Depending on the input, this main program calls      *
* the appropriate nested program to execute the chosen action.      *
*                                                                   *
*********************************************************************
IDENTIFICATION DIVISION.
PROGRAM-ID.  LOBDEMO1.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  USERNAME       PIC X(5).
01  PASSWD         PIC X(5).
01  CHOICE         PIC 9 VALUE 0.
01  SSS            PIC X(9).
01  SSSEXISTS      PIC 9 VALUE ZERO.
01  LICENSE-TXT    SQL-CLOB .
01  NEWCRIME       PIC X(35) VARYING.
01  SSSCOUNT       PIC S9(4) COMP.
01  THE-STRING    PIC X(200) VARYING.
01  TXT-LENGTH    PIC S9(9) COMP.
01  CRIMES.
05 FILLER PIC X(35) VALUE "Driving Under the Influence".
05 FILLER PIC X(35) VALUE "Grand Theft Auto".
05 FILLER PIC X(35) VALUE "Driving Without a License".
05 FILLER PIC X(35) VALUE
"Impersonating an Oracle Employee".
05 FILLER PIC X(35) VALUE "Wearing a Bright Orange Shirt".
01  CRIMELIST REDEFINES CRIMES.
05 CRIME  PIC X(35) OCCURS 5 TIMES.
01  CRIME-INDEX   PIC 9.
01  TXT-LEN       PIC S9(9) COMP.
01  CRIME-LEN     PIC S9(9) COMP.
01  NAME1         PIC X(50) VARYING.
01  NEWNAME         PIC X(50).
*********************************************************************

EXEC SQL INCLUDE SQLCA END-EXEC.

PROCEDURE DIVISION.
A000-CONTROL SECTION.
*********************************************************************
*  A000-CONTROL
*     Overall control section
*********************************************************************
A000-CNTRL.
EXEC SQL
WHENEVER SQLERROR DO PERFORM Z900-SQLERROR
END-EXEC.
PERFORM B000-LOGON.
PERFORM C000-MAIN UNTIL CHOICE = 5.
PERFORM D000-LOGOFF.
A000-EXIT.
STOP RUN.

B000-LOGON SECTION.
*********************************************************************
*  B000-LOGON
*    Log on to database.
*********************************************************************
B000-LGN.
DISPLAY '**************************************************'.
DISPLAY '*            Welcome to the DMV Database         *'.
DISPLAY '**************************************************'.
MOVE "scott" TO USERNAME.
MOVE "tiger" TO PASSWD.
EXEC SQL
CONNECT :USERNAME IDENTIFIED BY :PASSWD
END-EXEC.
DISPLAY " ".
DISPLAY "Connecting to license database account:  ",
USERNAME, "/", PASSWD.
DISPLAY " ".
B000-EXIT.
EXIT.
C000-MAIN SECTION.
*********************************************************************
*  C000-MAIN
*    Display the main menu and action requests
*********************************************************************
C000-MN.

DISPLAY " ".
DISPLAY "License Options:".
DISPLAY "1. List available records by SSS number".
DISPLAY "2. Get information on a particular record".
DISPLAY "3. Add crime to a record".
DISPLAY "4. Insert new record to database".
DISPLAY "5. Quit".
DISPLAY " ".

MOVE ZERO TO CHOICE.
PERFORM Z300-ACCEPT-CHOICE UNTIL CHOICE < 6
AND CHOICE > 0.
IF (CHOICE = 1)
PERFORM C100-LIST-RECORDS.
IF (CHOICE = 2)
PERFORM C200-GET-RECORD.
IF (CHOICE = 3)
PERFORM C300-ADD-CRIME.
IF (CHOICE = 4)
PERFORM C400-NEW-RECORD.
C000-EXIT.
EXIT.

C100-LIST-RECORDS SECTION.
*********************************************************************
*  C100-LIST-RECORDS
*   Select  Social Security Numbers from LICENCSE_TABLE
*   and display the list
*********************************************************************
C100-LST.

EXEC SQL DECLARE SSS_CURSOR CURSOR FOR
SELECT SSS FROM LICENSE_TABLE
END-EXEC.

EXEC SQL OPEN SSS_CURSOR END-EXEC.

DISPLAY "Available records:".

PERFORM C110-DISPLAY-RECORDS UNTIL SQLCODE = 1403.
EXEC SQL CLOSE SSS_CURSOR END-EXEC.
C100-EXIT.
EXIT.
C110-DISPLAY-RECORDS SECTION.
*********************************************************************
*  C110-DISPLAY-RECORDS
*    Fetch the next record from the cursor and display it.
*********************************************************************
C110-DSPLY.
EXEC SQL FETCH SSS_CURSOR INTO :SSS END-EXEC.
IF SQLCODE = 0 THEN
DISPLAY SSS.
C110-EXIT.
EXIT.

C200-GET-RECORD SECTION.
*******************************************************************
*  C200-GET-RECORD
*    Allocates the global clob LICENSE-TXT then selects
*    the name and text which corresponds to the client-supplied
*    sss.  It then calls Z200-PRINTCRIME to print the information and
*    frees the clob.
*******************************************************************
C200-GTRECRD.
PERFORM Z100-GET-SSS.
IF (SSSEXISTS = 1)
EXEC SQL ALLOCATE :LICENSE-TXT END-EXEC
EXEC SQL SELECT NAME, TXT_SUMMARY
INTO :NAME1, :LICENSE-TXT FROM LICENSE_TABLE
WHERE SSS = :SSS END-EXEC
DISPLAY "==================================================
-         "========================"
DISPLAY " "
DISPLAY "NAME:  ", NAME1-ARR, "SSS:  ", SSS
DISPLAY " "
PERFORM Z200-PRINTCRIME
DISPLAY " "
DISPLAY "==================================================
-         "========================"
EXEC SQL FREE :LICENSE-TXT END-EXEC
ELSE
DISPLAY "SSS Number Not Found".
C200-EXIT.
EXIT.
C310-GETNEWCRIME SECTION.
*******************************************************************
*  C310-GETNEWCRIME
*    Provides a list of the possible crimes to the user and
*    stores the user's correct response in the variable
*    NEWCRIME.
*******************************************************************
C310-GTNWCRM.

EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.

DISPLAY " ".
DISPLAY "Select from the following:".
PERFORM C311-DISPLAY-CRIME
VARYING CRIME-INDEX FROM 1 BY 1
UNTIL CRIME-INDEX > 5.
MOVE ZERO TO CHOICE.
PERFORM Z300-ACCEPT-CHOICE UNTIL CHOICE < 6
AND CHOICE > 0.
MOVE CRIME(CHOICE) TO NEWCRIME-ARR.
MOVE 35 TO NEWCRIME-LEN.
MOVE ZERO TO CHOICE.
C310-EXIT.
EXIT.
C311-DISPLAY-CRIME SECTION.
*******************************************************************
*   C311-DISPLAY-CRIME
*      Display an element of the crime table
*******************************************************************
C311-DSPLYCRM.
DISPLAY "(", CRIME-INDEX, ") ", CRIME(CRIME-INDEX).
C311-EXIT.
EXIT.
C320-APPENDTOCLOB SECTION.
*******************************************************************
* C320-APPENDTOCLOB
*    Obtains the length of the global clob LICENSE-TXT and
*    uses that in the LOB WRITE statement to append the NEWCRIME
*    character buffer to the global clob LICENSE-TXT.
*    The name corresponding the global SSS is then selected
*    and displayed to the screen along with value of LICENSE-TXT.
*    The caller to this function must allocate, select and later
*    free the global clob LICENSE-TXT.
*******************************************************************
C320-PPNDTCLB.

EXEC SQL
WHENEVER SQLERROR DO PERFORM Z900-SQLERROR
END-EXEC.

EXEC SQL LOB DESCRIBE :LICENSE-TXT GET LENGTH
INTO :TXT-LEN END-EXEC.

MOVE NEWCRIME-LEN TO CRIME-LEN.
IF (TXT-LEN NOT = 0)
ADD 3 TO TXT-LEN
ELSE
ADD 1 TO TXT-LEN.
EXEC SQL LOB WRITE :CRIME-LEN FROM :NEWCRIME
INTO :LICENSE-TXT AT :TXT-LEN END-EXEC.

EXEC SQL SELECT NAME INTO :NAME1 FROM LICENSE_TABLE
WHERE SSS = :SSS END-EXEC.
DISPLAY " ".
DISPLAY "NAME:  ", NAME1-ARR, "SSS:  ", SSS.
DISPLAY " ".
PERFORM Z200-PRINTCRIME.
DISPLAY " ".

C320-EXIT.
EXIT.

C300-ADD-CRIME SECTION.
*******************************************************************
* ADD-CRIME
*    Obtains a sss and crime from the user and appends
*    the crime to the list of crimes of the corresponding sss.
*******************************************************************
C300-DDCRM.

EXEC SQL
WHENEVER SQLERROR DO PERFORM Z900-SQLERROR
END-EXEC.

PERFORM Z100-GET-SSS.
IF (SSSEXISTS = 1)
EXEC SQL ALLOCATE :LICENSE-TXT END-EXEC
PERFORM C310-GETNEWCRIME
EXEC SQL SELECT TXT_SUMMARY INTO :LICENSE-TXT
FROM LICENSE_TABLE WHERE SSS = :SSS
FOR UPDATE END-EXEC
PERFORM C320-APPENDTOCLOB
EXEC SQL FREE :LICENSE-TXT END-EXEC
ELSE
DISPLAY "SSS Number Not Found".
C300-EXIT.
EXIT.

C400-NEW-RECORD SECTION.
*******************************************************************
* C400-NEW-RECORD
*    Obtains the sss and name of a new record and inserts them
*    along with an empty_clob() for the clob in the table.
*******************************************************************
C400-NWRCRD.

PERFORM Z100-GET-SSS.
IF (SSSEXISTS = 1)
DISPLAY "Record with that sss number already exists"
ELSE
DISPLAY "Name? " WITH NO ADVANCING
ACCEPT NEWNAME
DISPLAY " ".
EXEC SQL ALLOCATE :LICENSE-TXT END-EXEC
EXEC SQL INSERT INTO LICENSE_TABLE
VALUES (:SSS, :NEWNAME, EMPTY_CLOB()) END-EXEC
EXEC SQL SELECT TXT_SUMMARY INTO :LICENSE-TXT
FROM LICENSE_TABLE WHERE SSS = :SSS END-EXEC
DISPLAY "==================================================
-         "========================"
DISPLAY "NAME: ", NEWNAME,"SSS: ", SSS
PERFORM Z200-PRINTCRIME
DISPLAY "==================================================
-         "========================"
EXEC SQL FREE :LICENSE-TXT END-EXEC.
C400-EXIT.
EXIT.
D000-LOGOFF SECTION.
*******************************************************************
*  D000-LOGOFF
*    Commit the work done to the database and log off
*******************************************************************
D000-LGFF.
EXEC SQL COMMIT WORK RELEASE END-EXEC.
DISPLAY " ".
DISPLAY "HAVE A GOOD DAY!".
DISPLAY " ".
D000-EXIT.
STOP RUN.
Z100-GET-SSS SECTION.
*******************************************************************
*  Z100-GET-SSS
*    Fills the global variable SSS with the client-supplied sss.
*    Sets the global variable SSSEXISTS to 0 if the sss does not
*    correspond to any entry in the database, else sets it to 1.
*******************************************************************
Z100-GTSSS.
DISPLAY "Social Security Number? " WITH NO ADVANCING.
ACCEPT SSS.
DISPLAY " ".

EXEC SQL SELECT COUNT(*) INTO :SSSCOUNT FROM LICENSE_TABLE
WHERE SSS = :SSS END-EXEC.

IF (SSSCOUNT = 0)
MOVE 0 TO SSSEXISTS
ELSE
MOVE 1 TO SSSEXISTS.
Z100-EXIT.
EXIT.
Z200-PRINTCRIME SECTION.
*******************************************************************
*  Z200-PRINTCRIME
*    Obtains the length of the global clob LICENSE-TXT and
*    uses that in the LOB READ statement to read the clob
*    into a character buffer to display the contents of the clob.
*    The caller to this function must allocate, select and later
*    free the global clob LICENSE-TXT.
*******************************************************************
Z200-PRNTCRM.
DISPLAY "=====================".
DISPLAY " CRIME SHEET SUMMARY ".
DISPLAY "=====================".

MOVE SPACE TO THE-STRING-ARR.
EXEC SQL LOB DESCRIBE :LICENSE-TXT GET LENGTH
INTO :TXT-LENGTH END-EXEC.

IF (TXT-LENGTH = 0)
DISPLAY "Record is clean"
ELSE
EXEC SQL LOB READ :TXT-LENGTH FROM :LICENSE-TXT
INTO :THE-STRING END-EXEC
DISPLAY THE-STRING-ARR.

Z200-EXIT.
EXIT.
Z300-ACCEPT-CHOICE SECTION.
*******************************************************************
*   Z300-ACCEPT-CHOICE
*      Accept a choice between 1 and 5
*******************************************************************
Z300-CCPT.
DISPLAY "Your Selection (1-5)? " WITH NO ADVANCING.
ACCEPT CHOICE.
DISPLAY " ".
IF CHOICE >5 OR CHOICE < 1 THEN
DISPLAY "Invalid Selection"
DISPLAY "Please Choose from the indicated list".
Z300-EXIT.
EXIT.

Z900-SQLERROR SECTION.
*******************************************************************
* Z900-SQLERROR
*    Called whenever a SQLERROR occurs.
*    Display the Error, Roll Back any work done and Log Off
*******************************************************************
Z900-SQLRRR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
DISPLAY " ".
DISPLAY "ORACLE ERROR DETECTED:".
DISPLAY " ".
DISPLAY SQLERRMC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
Z900-EXIT.
STOP RUN.

14 プリコンパイラのオプション

この章ではPro*COBOLのプリコンパイラ・オプションを説明します。この章の内容は、次のとおりです。

- procobコマンド

- プリコンパイル時のアクション

- オプションについて

- プリコンパイラ・オプションの入力

- プリコンパイラ・オプションのスコープ

- クイック・リファレンス

- Pro*COBOLプリコンパイラ・オプションの使用

procobコマンド

Pro*COBOLは、システムごとに異なった場所に格納されます。通常は、システム管理者かDBAが、環境変数または別名を定義するか、あるいはオペレーティング・システム固有のその他の方法を使用して、Pro*COBOLの実行可能ファイルをアクセス可能にします。

Oracle Pro*COBOLプリコンパイラを実行するには、次のコマンドを使用します。

procob [option_name=value] [option_name=value] ...

オプション名とオプション値の間には必ず等号(=)を置きます。等号の前後には空白を入れないでください。

たとえば、プリコンパイルするソース・ファイルの指定には、INAMEオプションを使用します。次のコマンドを実行するとします。

procob INAME=test

Pro*COBOLはファイル拡張子を.pcoとみなすため、カレント・ディレクトリ内のファイルtest.pcoがプリコンパイルされます。

このように、INAMEの指定でファイル拡張子を使用する必要はありません(ただし、ファイル拡張子が標準以外の場合には拡張子を指定する必要があります)。

入力ファイル名および出力ファイル名を、それぞれのオプション名INAMEおよびONAMEとともに指定する必要はありません。オプション名を指定しない場合、Pro*COBOLはコマンドラインに指定された最初のファイル名を入力ファイル名とみなし、2番目のファイル名を出力ファイル名とみなします。

たとえば、次のコマンドを実行するとします。

procob MODE=ANSI myfile myfile.cob

これは、次と同等です。

procob MODE=ANSI INAME=myfile.pco ONAME=myfile.cob

大/小文字区別

一般に、コマンドライン・オプションの名前および値には、大文字と小文字のどちらも使用できます。ただし、大/小文字を区別するオペレーティング・システム(UNIXなど)を使用している場合は、Pro*COBOLの実行可能ファイルの名前も含めて、ファイル名は大文字と小文字を正しく組み合せて指定してください。

注意: ファイル名などのように、特定のオペレーティング・システム・オブジェクトを指定しないオプション名やオプション値では、大文字と小文字は区別されません。このマニュアル中の例では、オプション名は大文字または小文字で記述し、オプション値は通常は小文字で記述しています。ファイル名を指定する場合は、Pro*COBOLの実行可能ファイルも含めて、それを実行するオペレーティング・システムの大/小文字区別の規則に従ってください。

UNIX Cシェルなどの一部のオペレーティング・システムおよびユーザー・シェルでは、?の前にバックスラッシュ(\)などのエスケープ文字を指定する必要があります。たとえば、Pro*COBOLのオプション設定を示すには、procob?のかわりにprocob \?を使用する必要があります。

プラットフォーム固有のマニュアルを参照してください。

プリコンパイル時のアクション

Pro*COBOLは、プリコンパイル中に、ホスト・プログラムに埋め込まれたSQL文に置き換わるCOBOLのコードを生成します。生成されたコードには、各ホスト変数のデータ型、長さ、アドレスなどデータ構造の他、Oracleランタイム・ライブラリSQLLIBが必要とするその他の情報が組み込まれています。またこのコードには、埋込みSQLの処理を実行するSQLLIBルーチンのコールも入っています。

Pro*COBOLは警告やエラー・メッセージを発行することがあります。これらのメッセージは、『Oracle Databaseエラー・メッセージ』で説明されています。

オプションについて

プリコンパイル時には数多くの便利なオプションを使用できます。それらを使用して、リソースの使用、エラーの報告、入出力の書式化およびカーソルの管理を制御できます。

オプションの値はリテラルであり、テキストまたは数値を表します。たとえば、次のオプションを指定するとします。

... INAME=my_test

この値はファイル名を指定する文字列リテラルです。

また、次のオプションを指定するとします。

... PREFETCH=100

この値は数値です。

オプションの中にはブール値をとるものもあり、文字列のYESまたはNO、TRUEまたはFALSE、整数リテラルの1または0を指定できます。たとえば、次のオプションを指定するとします。

... SELECT_ERROR=YES

これは、次と同等です。

... SELECT_ERROR=TRUE

または

... SELECT_ERROR=1

等号(=)の前後に空白は入れません。空白によって個々のオプションが区切られるためです。たとえば、次のように、コマンドラインにオプションAUTO_CONNECTを指定できます。

... AUTO_CONNECT=YES

オプション名には略称を使用できますが、他と区別がつかなくなる略称は使用しないでください。たとえば、MAXの略称はMAXLITERALとMAXOPENCURSORSのどちらを表すのかわからないため、使用できません。

Pro*COBOLオプションの参考資料は、オンラインで簡単に見ることができます。オンライン表示するには、オペレーティング・システムのプロンプトから、引数を指定せずにPro*COBOLコマンドを入力します。

procob

オンライン画面には、各オプションの名前および、構文、デフォルト値および用途が表示されます。アスタリスク(*)が付いたオプションは、コマンドラインでもインラインでも指定できます。

オプション値の優先順位

オプションの値は、次の値によって決まります(下にいくほど優先順位が高くなります)。

- Pro*COBOLに組み込まれているデフォルト値

- システム構成ファイルに設定されている値

- ユーザー構成ファイルに設定されている値

- コマンドラインに入力された値

- インライン指定で設定された値セット

たとえば、MAXOPENCURSORSオプションでは、キャッシュ内のオープン・カーソルの最大数を指定します。このオプションのPro*COBOLに組み込まれたデフォルト値は10です。ただし、システム構成ファイルでMAXOPENCURSORS=32と指定されていると、値は32になります。ユーザー構成ファイルでは、これをさらに別の値に設定でき、これはシステム構成ファイルの値より優先されます。

MAXOPENCURSORSオプションをコマンドラインで設定した場合には、新しいコマンドラインの値が優先されます。最終的には、インライン指定が前述のすべてのデフォルト値よりも優先されます。詳細は、「プリコンパイラ・オプションの入力」を参照してください。

マクロ・オプションおよびマイクロ・オプション

オプションMODEはマクロ・オプションとも呼ばれます。END_OF_FETCHなどのより新しいオプションは1つの関数のみを制御し、マイクロ・オプションとして知られています。マクロ・オプションおよびマイクロ・オプションを設定するときは、マクロ・オプションがマイクロ・オプションより優先されることに注意してください。ただしこの点は、マクロ・オプションにマイクロ・オプションより高い優先順位が付いている場合のみ、注意する必要があります。(「オプション値の優先順位」の項に説明が記載されています。)この動作は、Pro*COBOL 8.0より前のリリースとは異なります。

たとえば、デフォルトはMODEはORACLEでEND_OF_FETCHは1403です。ユーザー構成ファイルにMODE=ANSIを指定した場合は、Pro*COBOLからフェッチの最後に値100が戻され、END_OF_FETCHのデフォルト値1403が上書きされます。この構成ファイルにMODE=ANSIおよびEND_OF_FETCH=1403を両方指定した場合は、1403を戻します。また、構成ファイルでEND_OF_FETCH=1403と指定し、コマンドラインでMODE=ANSIと指定した場合は、100が戻されます。

次の表に、マクロ・オプションの値によって設定されるマイクロ・オプションの値を示します。

表14-1 マクロ・オプション値によるマイクロ・オプション値の設定

マクロ・オプション

マイクロ・オプション

MODE=ANSI | ISO

CLOSE_ON_COMMIT=YES

DECLARE_SECTION=YES

END_OF_FETCH=100

DYNAMIC=ANSI

TYPE_CODE=ANSI

MODE=ANSI14 | ANSI13 | ISO14 | ISO13

CLOSE_ON_COMMIT=NO

DECLARE_SECTION=YES

END_OF_FETCH=100

MODE=ORACLE

CLOSE_ON_COMMIT=NO

DECLARE_SECTION=NO

END_OF_FETCH=1403

DYNAMIC=ORACLE

TYPE_CODE=ORACLE

カレント値の決定

コマンドラインで疑問符(?)を使用すると、複数のオプションのカレント値を対話形式で調べることができます。たとえば、次のコマンドを発行したとします。

procob ?

すべてのオプションの設定およびそのカレント値が端末に表示されます。この場合、表示される値はPro*COBOLに組み込まれている値ですが、システム構成ファイルに値が指定されている場合は構成ファイル内の値が表示されます。一方、次のコマンドを発行したとします。

procob CONFIG=my_config_file.cfg ?

これでカレント・ディレクトリにmy_config_file.cfgというファイルがあると、my_config_file.cfgファイルのオプションが、その他のデフォルト値とともに表示されます。不足している値はユーザー構成ファイル内の値によって補われ、これらの値はPro*COBOLに組み込まれている値や、システム構成ファイルで指定されている値に優先します。

次のようにオプション名の後に=?を指定して、シングル・オプションのカレント値を指定することもできます。

procob MAXOPENCURSORS=?

プリコンパイラ・オプションの入力

CONFIG以外のPro*COBOLのオプションはすべて、コマンドラインまたは構成ファイルから入力できます。また、インラインで入力できるオプションも多数あります。Pro*COBOLは実行時に、これら3つのソースのオプションをすべて受け入れます。

コマンドライン

... [option_name=value] [option_name=value] ...を使用して、コマンドラインからプリコンパイラ・オプションを入力できます。

オプションとオプションの間は、1つ以上の空白で区切ります。たとえば、次のようにオプションを入力できます。

... ERRORS=no LTYPE=short

インライン

次の構文を使用してEXEC ORACLE OPTION文を記述すると、オプションをインライン入力できます。

EXEC ORACLE OPTION (option_name=value) END-EXEC.

たとえば、次のような文をコーディングできます。

EXEC ORACLE OPTION (RELEASE_CURSOR=YES) END-EXEC.

インラインでオプションを入力すると、コマンドラインから入力された同じオプションは無効になります。

長所

EXEC ORACLE機能は、プリコンパイル中にオプション値を変更する場合に特に便利です。たとえば、文ごとにHOLD_CURSOR値およびRELEASE_CURSOR値を変更することがあります。インライン・オプションを使用して実行時のパフォーマンスを最適化する方法については、付録C「パフォーマンス・チューニング」を参照してください。

インラインでのオプションの指定は、オペレーティング・システムでコマンドラインでの入力文字数が制限されている場合にも便利であり、インライン・オプションは構成ファイルに格納できます。これらの制限を次の項で説明します。

EXEC ORACLEのスコープ

EXEC ORACLE文は、同一オプションを指定した別のEXEC ORACLE文によってオプション指定値(テキスト)が変更されるまで有効です。次の例では、HOLD_CURSOR=NOはHOLD_CURSOR=YESが指定されるまで有効です。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
01  EMP-NAME    PIC X(20) VARYING.
01  EMP-NUMBER  PIC S9(4) COMP VALUE ZERO.
01  SALARY      PIC S9(5)V99 COMP-3 VALUE ZERO.
01  DEPT-NUMBER PIC S9(4) COMP VALUE ZERO.
EXEC SQL END DECLARE SECTION END-EXEC.
...
EXEC SQL WHENEVER NOT FOUND GOTO NO-MORE END-EXEC.
...
EXEC ORACLE OPTION (HOLD_CURSOR=NO)END-EXEC.
...
EXEC SQL DECLARE emp_cursor CURSOR FOR
SELECT EMPNO, DEPTNO FROM EMP
END-EXEC.
EXEC SQL OPEN emp_cursor END-EXEC.

DISPLAY 'Employee Number  Dept'.
DISPLAY '---------------  ----'.
PERFORM
EXEC SQL
FETCH emp_cursor INTO :EMP-NUMBER, :DEPT-NUMBER
END-EXEC
DISPLAY EMP-NUMBER, DEPT-NUMBER END-EXEC
END-PERFORM.

NO-MORE.
EXEC SQL WHENEVER NOT FOUND CONTINUE END-EXEC.
PERFORM
DISPLAY 'Employee number? '
ACCEPT EMP-NUMBER
IF EMP-NUMBER IS NOT = 0
EXEC ORACLE OPTION (HOLD_CURSOR=YES) END-EXEC
EXEC SQL SELECT ENAME, SAL
INTO :EMP-NAME, :SALARY
FROM EMP
WHERE EMPNO = :EMP-NUMBER
DISPLAY 'Salary for ', EMP-NAME, ' is ', SALARY
END-EXEC
END-IF
END-PERFORM.
NEXT-PARA.
...

構成ファイル

構成ファイルは、プリコンパイラ・オプションを格納するテキスト・ファイルです。ファイルのそれぞれのレコード(行)には、1つのオプションおよび対応付けられた値が入ります。たとえば、構成ファイルに次のような行が入っているとします。

FIPS=YES
MODE=ANSI

これらの行によってFIPSオプションとMODEオプションの値が設定されています。

システムにはそれぞれ1つのシステム構成ファイルがあります。システム構成ファイルの名前は次のとおりです。

pcbcfg.cfg

システム構成ファイルの位置はオペレーティング・システムによって異なります。ほとんどのUNIXシステムでは、Pro*COBOL構成ファイルは通常、$ORACLE_HOME/precomp/adminディレクトリにあります($ORACLE_HOMEはデータベース・ソフトウェアの環境変数です)。

リリース8.0より前のPro*COBOLでは、構成ファイル名はpccob.cfgであることに注意してください。

Pro*COBOLのユーザーは1つ以上のユーザー構成ファイルを持つことができます。ユーザー構成ファイルの名前はCONFIGオプションを使用してコマンドラインで指定します。詳細は、「カレント値の決定」を参照してください。

注意: 構成ファイルはネストできません。つまり、CONFIGは構成ファイル内では有効なオプションではありません。

列プロパティのサポート

列プロパティは8バイトの値で戻され、各ビットが1つの列プロパティを示します。3つの列プロパティがサポートされています。

+---------------------------------------------------+
! 32 |..............| 10 | 9 | 8 |......| 3 | 2 | 1 |
+---------------------------------------------------+
|    |   |
|    |   |-> auto-increment column
|    |-> auto value always generated
|-> if generated by default when null

列プロパティは、新しいSQLDAメンバー(sqlda->CP[])を使用して動的文から取得できます。

01  SELDSC.
02  SQLDNUM             PIC S9(9) COMP VALUE 20.
02  SQLDFND             PIC S9(9) COMP.
02  SELDVAR             OCCURS 20 TIMES.
03 SELDV            PIC S9(9) COMP.
03 SELDFMT          PIC S9(9) COMP.
03 SELDVLN          PIC S9(9) COMP.
03 SELDFMTL         PIC S9(4) COMP.
03 SELDVTYP         PIC S9(4) COMP.
03 SELDI            PIC S9(9) COMP.
03 SELDH-VNAME      PIC S9(9) COMP.
03 SELDH-MAX-VNAMEL PIC S9(4) COMP.
03 SELDH-CUR-VNAMEL PIC S9(4) COMP.
03 SELDI-VNAME      PIC S9(9) COMP.
03 SELDI-MAX-VNAMEL PIC S9(4) COMP.
03 SELDI-CUR-VNAMEL PIC S9(4) COMP.
03 SELDFCLP         PIC S9(9) COMP.
03 SELDFCRCP        PIC S9(9) COMP.
02  SQLDSCCP            OCCURS 20 TIMES PIC S9(18) COMP-5.

このメンバーSQLDSCCPは、メタデータDESCRIBEの一部として更新されます。

列プロパティは、新しい関数SQLGetColProp()を使用した静的文で取得できます(この関数は最後に実行された文から列プロパティを取得します)。

void SQLGetColProp(
void  *uga,    --> IN -- run time context
text *coln,    --> IN -- column name
ub2  *colatr,  --> IN -- column attributes
ub8  *colprop  --> IN/OUT -- column attribute/ub8 value that holds column properties
)

SQLGetColProp()は、列属性colatrで決定された値を戻します。

- SQL_ATTR_COL_PROPERTIES:
指定した列の列プロパティを含む、8バイトの値(colprop)を戻します。

- SQL_ATTR_COL_PROPERTY_IS_IDENTITY
colpropは、指定した列がID列の場合にtrueになります。

- SQL_ATTR_COL_PROPERTY_IS_GEN_ALWAYS
colpropは、指定した列が常に自動増分値を生成する場合にtrueになります。

- SQL_ATTR_COL_PROPERTY_IS_GEN_BY_DEF_ON_NULL
colpropは、指定した列がデフォルトnull列制約である場合に自動増分値を生成するときは、trueになります。

プリコンパイラ・オプションのスコープ

プリコンパイル・ユニットは、COBOLコードおよび1つ以上の埋込みSQL文が入っている1つのファイルです。特定のプリコンパイル・ユニットに対して指定したオプションは、そのプリコンパイル・ユニットにのみ効力を持ちます。

たとえば、単位AにHOLD_CURSOR=YESおよびRELEASE_CURSOR=YESを指定し、単位Bには指定しなかった場合、単位AのSQL文は指定したHOLD_CURSORおよびRELEASE_CURSORの値で実行されますが、単位BのSQL文はデフォルト値で実行されます。ただし、Oracleに接続した時点で有効であったMAXOPENCURSORSの設定は、その接続を切り離すまで有効です。

インライン・オプションのスコープは論理的なものではなく、位置的なものです。つまり、インライン・オプションの影響を受けるのは、プログラム・ロジックの流れでそのインライン・オプションの後にくるSQL文ではなく、ソース・ファイル内でそのインライン・オプションの後に記述されているSQL文です。オプションの設定は、そのオプションを再指定しないかぎり、ファイルの終わりまで有効です。

クイック・リファレンス

表14-2は、Pro*COBOLオプションのクイック・リファレンスを示しています。アスタリスクが付いているオプションは、インラインで入力できます。

また、オンラインでも簡単な参照ができます。オンライン画面でPro*COBOLオプションを表示するには、オペレーティング・システムのプロンプトに、オプションを指定せずにPro*COBOLコマンドを入力します。オンライン画面には、各オプションの名前および、構文、デフォルト値および用途が表示されます。

注意:

プラットフォーム固有のオプションもいくつかあります。たとえば、バイトスワップ・プラットフォームでは、オプションCOMP5によってCOMPUTATIONAL項目の使用を管理します。使用しているシステム固有のOracleマニュアルを参照してください。

SPARC Solaris 64ビット・コンピュータでは、COMP5はサポートされません。かわりにCOMPを使用します。

表14-2 オプション・リスト

構文

デフォルト値

指定内容

ASACC={YES | NO}

NO

YESの場合は、リスト・ファイルにASAキャリッジ制御を使用します。

ASSUME_SQLCODE={YES | NO}

NO

YESの場合は、SQLCODE変数が存在するものとみなします。

AUTO_CONNECT={YES | NO}

NO

YESの場合は、最初の実行文の前に、ops$アカウントに自動的に接続できます。

CLOSE_ON_COMMIT*

NO

YESの場合は、COMMIT時にすべてのカーソルをクローズします。

CONFIG=filename

(なし)

ユーザー定義構成ファイルの名前を指定します。

CWH_SQL99={YES | NO}

YES

YESの場合は、使用しているカーソルをROLLBACK時にクローズします(標準SQLの動作)。

DATE_FORMAT

LOCAL

日付文字列フォーマットを指定します。

DBMS=NATIVE | V7 | V8

NATIVE

プリコンパイル時にみられるOracleのバージョン固有の動作です。

DECLARE_SECTION

NO

YESの場合は、DECLARE SECTIONが必須となります。

DEFINE=symbol *

(なし)

条件付きプリコンパイルで使用する記号を定義します。

DYNAMIC

ORACLE

SQL方法4で、OracleまたはANSI動的セマンティクスを指定します。

END_OF_FETCH

1403

フェッチ終了時のSQLCODEの値。

ERRORS={YES | NO} *

YES

YESの場合は、端末にエラーを表示します。

FIPS={YES | NO}

NO

YESの場合は、ANSI/ISOの拡張機能にフラグを付けます。

FORMAT={ANSI | TERMINAL | VARIABLE}

ANSI

入力ファイルのCOBOL文の書式。

HOLD_CURSOR={YES | NO}*

NO

YESの場合は、Oracleカーソルを保持します(再割当てしません)。

HOST={COBOL | COB74}

COBOL

入力ファイルで使用するCOBOLのバージョン(COBOL 85またはCOBOL 74)。

[INAME=]filename

(なし)

入力ファイルの名前。

INCLUDE=path*

(なし)

EXEC SQL INCLUDEファイルのパス名。

IRECLEN=integer

80

入力ファイルのレコード長。

LITDELIM={APOST | QUOTE}

QUOTE

COBOL文字列のデリミタ。

LNAME=filename

(なし)

リスト・ファイルの名前。

LRECLEN=integer

132

リスト・ファイルのレコード長。

LTYPE={LONG | SHORT | NONE} *

LONG

リスト・ファイルの型。

MAXLITERAL=integer*

256

文字列の最大長。
(IBM独自のS370 OSでは120)

MAXOPENCURSORS=integer *

10

キャッシュされるOracleカーソルの最大数(1)。

MODE={ORACLE | ANSI}

ORACLE

ANSIの場合は、ANSI/ISO SQL標準に準拠します。

NESTED={YES | NO}

YES

YESの場合は、ネストしたプログラムがサポートされます。

NLS_LOCAL={YES | NO}

NO

YESの場合は、Pro*COBOLの旧リリースのNCHAR方法を使用します。

[ONAME=]filename

iname.cob

出力ファイルの名前。

ORACA={YES | NO}*

NO

YESの場合は、ORACAコミュニケーション領域を使用します。

ORECLEN=integer

80

出力ファイルのレコード長。

PAGELEN=integer

66

リスト・ファイルの1ページ当たりの行数。

PICX

CHARF

PIC X COBOL変数のデータ型。

PLAN_BASELINE={module_name | YES | NO}

NO

モジュール名を指定してSQL計画ベースラインを作成します。

PLAN_PREFIX={prefix_name| none}

なし

計画名が30バイト以内であることを確認します。

PLAN_RUN={YES | NO}

NO

生成されたSQLファイルを実行します。

PLAN_FIXED={YES | NO}

YES

作成した計画ベースラインが固定であるか、非固定であるかを指定します。

PLAN_ENABLED={YES | NO}

YES

作成される計画ベースラインを有効にします。

MEMFORPREFETCH=0..4294967294

なし

指定メモリーに格納する行をプリフェッチすることで問合せを高速化します。

PREFETCH

1

一定数の行をプリフェッチして、問合せを高速化します。

RELEASE_CURSOR={YES | NO} *

NO

YESの場合は、実行後にOracleカーソルを解放します。

SELECT_ERROR={YES | NO}*

YES

YESの場合は、SELECT時にFOUNDエラーが発生します。

SQLCHECK={SEMANTICS | SYNTAX}*

SYNTAX

SQLチェックのレベル。

THREADS={YES | NO}

NO

マルチスレッド・アプリケーションを示します。

TYPE_CODE

ORACLE

動的SQL方法4の場合は、OracleまたはANSI型コードを使用します。

UNSAFE_NULL={YES | NO}

NO

YESの場合は、安全でないNULLのフェッチが可能になります(ORA-01405メッセージが発行されなくなります)。

USERID=username/password[@dbname]

(なし)

Oracleのユーザー名、パスワードおよびオプショナル・データベース。

VARCHAR={YES | NO}

NO

YESの場合は、ユーザー定義のVARCHARグループ項目を受け入れます。

XREF={YES | NO}*

YES

YESの場合は、リスト・ファイル内に記号のクロス・リファレンスを生成します。

Pro*COBOLプリコンパイラ・オプションの使用

この項は、プリコンパイラ・オプションを簡単に参照できるように構成されています。Pro*COBOLプリコンパイラ・オプションをアルファベット順に示し、各オプションごとに用途、構文およびデフォルト値を記載してあります。さらに「使用上の注意」で、オプションについて説明します。使用上の注意に特に記載がない場合、そのオプションはコマンドライン、インラインまたは構成ファイルのどの方法でも入力できます。

ASACC

用途

リスト・ファイルがASA規則に従って、キャリッジ制御のために各行の最初の桁を使用するかどうかを指定します。

構文

ASACC={YES | NO}

デフォルト値

NO

使用上の注意

インラインでは入力できません。

ASSUME_SQLCODE

用途

SQLCODEがプログラムで宣言されているかどうか、また、型が正しいかどうかに関係なく、SQLCODEが宣言されているとみなすようにPro*COBOLに指示します。

構文

ASSUME_SQLCODE={YES | NO}

デフォルト値

NO

使用上の注意

インラインでは入力できません。

DECLARE_SECTION=YESの場合にASSUME_SQLCODE=YESと指定すると、SQLCODEを宣言部の外で宣言できます。

DECLARE_SECTION=YESの場合にASSUME_SQLCODE=NOと指定すると、次の基準のうち1つ以上が満たされた場合にのみ、SQLCODEは状態変数として認識されます。

- 完全に正しいデータ型で宣言済の場合。

- Pro*COBOLが他の状態変数を見つけられない場合。Pro*COBOLは、(完全に正しい型の) SQLSTATE宣言を検出した場合や、SQLCAの組込みを検出した場合には、SQLCODEが宣言されているとはみなしません。

ASSUME_SQLCODE=YESと指定した場合は、SQLSTATEまたはSQLCAあるいはその両方が状態変数として宣言されると、SQLCODEが宣言されているかどうか、また正しい型かどうかに関係なく、Pro*COBOLはSQLCODEが宣言されているものとみなします。

AUTO_CONNECT

用途

プログラムをデフォルトのユーザー・アカウントに自動的に接続するかどうかを指定します。

構文

AUTO_CONNECT={YES | NO}

デフォルト値

NO

使用上の注意

インラインでは入力できません。

AUTO_CONNECT=YESと指定した場合、Pro*COBOLが実行SQL文を検出すると同時に、ユーザー・プログラムは自動的に次のユーザーIDでOracleにログインを試みます。

<prefix><username>

<prefix>にはOracle初期化パラメータOS_AUTHENT_PREFIXの値(デフォルト値はOPS$)を指定し、<username>には使用しているオペレーティング・システムのユーザー名またはタスク名を指定します。この場合、コマンドラインに別の値を指定しても、MAXOPENCURORS(10)のデフォルト値は変更できません。

AUTO_CONNECT=NO (デフォルト)の場合は、OracleにログインするにはCONNECT文を使用する必要があります。

CHARSET_PICX

用途

SELECT、INSERTまたはUPDATE文で使用されるPIC X変数に使用するキャラクタ・セットの形式を指定します。

構文

CHARSET_PICX={NCHAR_CHARSET | DB_CHARSET }

デフォルト値

DB_CHARSET

使用上の注意

コマンドラインまたは構成ファイルでは入力できますが、インラインでは入力できません。

CHARSET_PICX = NCHAR_CHARSETと指定した場合、PIC Xバインド・バッファまたは定義バッファは、サーバー側の各国語キャラクタ・セットに従って変換されます。ターゲット列がCHARの場合は、パフォーマンスに影響を及ぼす可能性があります。同様に、CHARSET_PICX = DB_CHARSETと指定した場合、PIC Xバインド・バッファまたは定義バッファは、サーバー側のデータベース・キャラクタ・セットに従って変換されます。ターゲット列がNCHARの場合は、一部のデータが失われる可能性があります。

CHARSET_PICN

用途

SELECT、INSERTまたはUPDATE文で使用されるPIC N変数に使用するキャラクタ・セットの形式を指定します。

構文

CHARSET_PICN={NCHAR_CHARSET | DB_CHARSET }

デフォルト値

NCHAR_CHARSET

使用上の注意

コマンドラインまたは構成ファイルでは入力できますが、インラインでは入力できません。

CHARSET_PICN = DB_CHARSETと指定した場合、PIC Nバインド・バッファまたは定義バッファは、サーバー側のデータベース・キャラクタ・セットに従って変換されます。ターゲット列がNCHARの場合は、一部のデータが失われる可能性があります。同様に、CHARSET_PICN = NCHAR_CHARSETと指定した場合、PIC Nバインド・バッファまたは定義バッファは、サーバー側の各国語キャラクタ・セットに従って変換されます。ターゲット列がCHARの場合は、パフォーマンスに影響を及ぼす可能性があります。

CLOSE_ON_COMMIT

用途

WITH HOLD句なしで宣言されたカーソルを、コミット時にすべてクローズするかどうかを指定します。

構文

CLOSE_ON_COMMIT={YES | NO}

デフォルト値

NO

使用上の注意

コマンドラインまたは構成ファイルからのみ入力できます。

このオプションは、DECLARE CURSOR文でWITH HOLD句を使用せずに宣言されたカーソルがある場合にのみ有効です(WITH HOLD句が指定されていると、このオプションも、MODEオプションに対応するそれまでの動作も無効になります)。CLOSE_ON_COMMITより高いレベルでMODEが指定されていると、MODEが優先されます。たとえば、デフォルトはMODE=ORACLEおよびCLOSE_ON_COMMIT=NOです。コマンドラインでMODE=ANSIと指定した場合は、WITH HOLD句を使用せずに宣言されているカーソルはすべて、コミット時にクローズされます。

CLOSE_ON_COMMIT=NO (MODE=ORACLEの場合)の場合、COMMITまたはROLLBACKを発行しても、クローズされるのはFOR UPDATE句を使用して宣言されたカーソルまたはCURRENT OF句で参照されるカーソルのみです。その他のカーソルはCOMMITまたはROLLBACK文による影響を受けず、オープンされている場合はオープンされたままです。ただし、CLOSE_ON_COMMIT=YES (MODE=ANSIの場合)のときにCOMMITまたはROLLBACKを発行すると、すべてのカーソルがクローズします。

このオプションの優先順位の詳細は、「マクロ・オプションおよびマイクロ・オプション」を参照してください。

COMMON_PARSER

用途

SQL99構文のSELECT、INSERT、DELETE、UPDATEおよびDECLARE CURSOR文のカーソル本体がサポートされます。

構文

COMMON_PARSER={YES | NO}

デフォルト値

NO

使用上の注意

コマンドラインで入力できます。

CONFIG

用途

ユーザー構成ファイルの名前を指定します。

構文

CONFIG=filename

デフォルト値

なし

使用上の注意

コマンドラインでのみ入力できます。

Pro*COBOLは、コマンドライン・オプションがあらかじめ設定されている構成ファイルを使用できます。ユーザー構成ファイルと呼ばれる代替ファイルも指定できます。詳細は、「プリコンパイラ・オプションの入力」を参照してください。

構成ファイルはネストできません。したがって、構成ファイルはオプションCONFIGを指定できません。

DATE_FORMAT

用途

日付が戻される文字列フォーマットを指定します。

構文

DATE_FORMAT={ISO | USA | EUR | JIS | LOCAL | 'fmt' (デフォルトLOCAL)

デフォルト値

LOCAL

使用上の注意

コマンドラインまたは構成ファイルからのみ入力できます。指定できる日付文字列を次の表に示します。

表14-3 日付文字列用の書式

書式名

略称

日付書式

国際標準化機構規格

ISO

yyyy-mm-dd

USA標準

USA

mm/dd/yyyy

ヨーロッパ標準

EUR

dd.mm.yyyy

日本工業規格

JIS

yyyy-mm-dd

インストール定義

LOCAL

インストール時に定義した任意の書式。

'fmt'は、「Month dd, yyyy」などの日付書式モデルです。日付書式モデル要素の一覧は、『Oracle Database SQL言語リファレンス』を参照してください。

DATE_FORMATオプションの使用において、制約が1つあります。互いにリンクされたコンパイル・ユニットはすべて、同じDATE_FORMAT値を使用する必要があります。コンパイル・ユニットのDATE_FORMATの値が一致しない場合、エラーが発生します。

DB2_ARRAY

用途

このオプションに基づいて、プリコンパイラは追加の配列INSERTおよび配列SELECT構文をアクティブにします。

構文

DB2_ARRAY={YES |NO}

デフォルト値

NO

使用上の注意

このオプションをNOに設定すると、Oracleプリコンパイラの構文がサポートされます。それ以外の場合は、DB2の配列INSERTおよび配列SELECT構文がサポートされます。

DBMS

用途

Oracleの意味上および構文上の規則を、Oracle7データベース、Oracle8iまたはOracleのネイティブ・バージョン(アプリケーションが接続されているバージョン)のうちどの規則に合わせるかを指定します。

構文

DBMS={V7 | V8 | NATIVE}

デフォルト値

NATIVE

使用上の注意

インラインでは入力できません。

DBMSオプションを使用して、Oracleのバージョン固有の動作を制御できます。DBMS=NATIVE (デフォルト)の場合、Oracleは、Oracleのネイティブ・バージョンの意味および構文上の規則に従います。

DECLARE_SECTION

用途

宣言部内の宣言のみホスト変数として使用するかどうかを指定します。

構文

DECLARE_SECTION={YES | NO}

デフォルト値

NO

使用上の注意

コマンドラインまたは構成ファイルからのみ入力できます。

Pro*COBOLリリース8.0以降では、MODE=ORACLEであれば、BEGIN DECLARE SECTION文とEND DECLARE SECTION文は省略できます。DECLARE_SECTIONオプションは、旧リリースとの下位互換性のために用意されています。DECLARE_SECTIONはMODEのマイクロ・オプションです。

このオプションを使用すると、MODE=ORACLEとDECLARE_SECTION=YESを一緒に指定でき、旧リリースでMODE=ORACLEのみ指定した場合と同じ結果が得られます。(DECLARE文で宣言した変数のみ、ホスト変数として使用できます。)このオプションの優先順位の詳細は、「オプション値の優先順位」を参照してください。

DEFINE

用途

条件付きプリコンパイル時にソース・コードの一部組込みまたは除外を行うために使用する、ユーザー定義の記号を指定します。詳細は、「条件付きプリコンパイル」を参照してください。

構文

DEFINE=symbol

デフォルト値

なし

使用上の注意

DEFINEをインラインで入力する場合のEXEC ORACLE文の書式は次のとおりです。

EXEC ORACLE DEFINE symbol END-EXEC.

DYNAMIC

用途

このMODEマイクロ・オプションは、動的SQL方法4の記述子の動作を指定します。

構文

DYNAMIC={ORACLE | ANSI}

デフォルト値

ORACLE

使用上の注意

EXEC ORACLE OPTION文を使用してインラインで入力することはできません。

DYNAMICオプションの設定については、「ANSI動的SQLのプリコンパイラ・オプション」を参照してください。

END_OF_FETCH

用途

このMODEマイクロ・オプションは、SQL文の実行後にEND-OF-FETCH条件が発生した場合に戻されるSQLCODE値を指定します。

構文

END_OF_FETCH={100 | 1403}

デフォルト値

1403

使用上の注意

コマンドラインまたは構成ファイルからのみ入力できます。

END_OF_FETCHはMODEのマイクロ・オプションです。詳細は、「マクロ・オプションおよびマイクロ・オプション」を参照してください。

構成ファイルでMODE=ANSIと指定した場合、END_OF_FETCH条件が発生すると、Pro*COBOLはSQLCODE値100を戻し、END_OF_FETCHのデフォルト値である1403をオーバーライドします。

構成ファイルでMODE=ANSIとEND_OF_FETCH=1403の両方を指定した場合は、END_OF_FETCH条件が発生すると、Pro*COBOLはSQLCODE値1403を戻します。

構成ファイルでMODE=ANSIと指定し、構成ファイルよりも優先順位の高いコマンドラインでEND_OF_FETCH=1403と指定した場合も、END_OF_FETCH条件が発生するとPro*COBOLはSQLCODE値1403を戻します。

ERRORS

用途

Pro*COBOLのエラー・メッセージを、端末およびリスト・ファイルの両方に送るか、リスト・ファイルにのみ送るかを指定します。

構文

ERRORS={YES | NO}

デフォルト値

YES

使用上の注意

ERRORS=YESと指定すると、エラー・メッセージは端末とリスト・ファイルの両方に送られます。

ERRORS=NOのときは、エラー・メッセージはリスト・ファイルにのみ送られます。

File_ID

用途

生成されたCOBOLファイルの一意の識別子を示します。生成されたファイルには、「SQLCTX」変数と関連付けられた一意の数値が含まれます。file_idオプションを使用すると、SQLCTX変数の値を設定できます。このオプションは、複数のソース・ファイルをプリコンパイルする際に有効で、ユーザーは生成された異なるファイルと関連付けられた一意のSQLCTX値を確保できます。

構文

FILE_ID=0から65535

デフォルト値

0

使用上の注意

file_idオプションを使用すると、生成されたCOBOLファイルの「SQLCTX」変数に直接値を割り当てることができます。

FIPS

用途

ANSI/ISO SQLの拡張機能に(FIPSフラガーによって)フラグを付けるかどうかを指定します。拡張機能とは、ANSI/ISOの形式または構文規則(権限付与規則は除く)に従っていないSQL要素のことです。

構文

FIPS={YES | NO}

デフォルト値

NO

使用上の注意

FIPS=YESの場合は、エントリ・レベルのSQL-92に対してOracle拡張機能を使用したり、エントリ・レベルのSQL-92の機能を規格に準拠しない方法で使用すると、FIPSフラガーは警告メッセージを発行します(エラー・メッセージではありません)。

プリコンパイル時に、次に示すANSI/ISO SQLの拡張機能にフラグが付きます。

- FOR句を含む配列インタフェース

- SQLCA、ORACAおよびSQLDAデータ構造体

- DESCRIBE文を含む動的SQL

- 埋込みPL/SQLブロック

- 自動データ型変換

- DATE、COMP-3、NUMBER、RAW、LONG RAW、VARRAW、ROWIDおよびVARCHARデータ型

- 実行時オプションを指定するためのORACLE OPTION文

- ユーザー・イグジットでのEXEC TOOLS文

- CONNECT文

- TYPEおよびVARデータ型の同値化文

- AT db_name句

- DECLARE...DATABASE文、...STATEMENT文および...TABLE文

- WHENEVER文でのSQLWARNING条件

- WHENEVER文のDO処置およびSTOP処置

- COMMIT文のCOMMENT句およびFORCE TRANSACTION句

- ROLLBACK文でのFORCE TRANSACTION句およびTO SAVEPOINT句

- COMMIT文およびROLLBACK文でのRELEASEパラメータ

- INTO句のWHENEVER...DOラベルおよびホスト変数の前に付けるオプションのコロン

FORMAT

用途

COBOL文の書式を指定します。

構文

FORMAT={ANSI | TERMINAL | VARIABLE}

デフォルト値

ANSI

使用上の注意

インラインでは入力できません。

入力行の書式はシステムによって異なります。システム固有のOracleのマニュアルまたはCOBOLコンパイラをチェックしてください。

FORMAT=ANSIと指定した場合、入力行の書式はCOBOLに関する現行のANSI規格にできるかぎり準拠しているものと解釈されます。FORMAT=TERMINALと指定した場合、入力行は列1から始まります。このマニュアルのサンプル・コードはTERMINAL書式内にあります。FORMAT=VARIABLEを使用すると、B領域な長さの柔軟性が許可されます。詳細は、「コーディング領域」を参照してください。

HOLD_CURSOR

用途

カーソル・キャッシュでのSQL文およびPL/SQLブロック用カーソルの取扱い方法を指定します。

構文

HOLD_CURSOR={YES | NO}

デフォルト値

NO

使用上の注意

HOLD_CURSORを使用すると、プログラムのパフォーマンスを改善できます。詳細は、付録C「パフォーマンス・チューニング」を参照してください。

SQLデータ操作文を実行すると、その文に関連付けられたカーソルが、カーソル・キャッシュ内のエントリにリンクされます。そのカーソル・キャッシュ・エントリは、文の処理に必要な情報が格納されるOracleプライベートSQL領域にリンクされます。HOLD_CURSORは、カーソルとカーソル・キャッシュの間のリンクで発生する処理を制御します。

HOLD_CURSOR=NOと指定した場合、OracleがSQL文を実行してカーソルがクローズされた後、Pro*COBOLはそのリンクを再使用可能としてマークします。このリンクは、それが示すカーソル・キャッシュ・エントリが別のSQL文に必要になると、すぐに再利用されます。これにより、プライベートSQL領域に割り当てられたメモリーが解放され、解析ロックが解除されます。

HOLD_CURSOR=YESを指定した場合は、リンクは維持され、Pro*COBOLはリンクを再利用しません。これによって、以降の実行をスピードアップし、文を再解析したり、OracleプライベートSQL領域にメモリーを割り当てる必要がなくなるため、実行頻度の高いSQL文に使用すると便利です。

暗黙カーソルをインラインで使用する場合は、SQL文の実行前にHOLD_CURSORを設定してください。明示カーソルをインラインで使用する場合は、カーソルをオープンする前にHOLD_CURSORを設定してください。

HOLD_CURSORおよびRELEASE_CURSORオプションの相互動作に関する詳細は、付録C「パフォーマンス・チューニング」の表C-1「HOLD_CURSORおよびRELEASE _CURSORの相互関係」を参照してください。

HOST

用途

使用するホスト言語を指定します。

構文

HOST={COB74 | COBOL}

デフォルト値

COBOL

使用上の注意

インラインでは入力できません。

COB74は、ANSI承認COBOLの1974版を表します。COBOLは、1985版を表します。プラットフォームによっては、これ以外の値も使用できます。

IMPLICIT_SVPT

用途

新しくバッチ処理された挿入を開始する前に、暗黙的なセーブポイントを設定するかどうかを制御します。

構文

implicit_svpt={YES|NO}

デフォルト値

NO

使用上の注意

YESの場合は、新しい行のバッチを開始する前に、セーブポイントが設定されます。挿入時にエラーが発生すると、暗黙的な「セーブポイントへのロールバック」が実行されます。このオプションは、DB2との互換性のために用意されていますが、余分なラウンドトリップとなるためマイナス面であることは明らかです。

NOの場合は、暗黙的なセーブポイントが設定されません。バッファ済INSERTでエラーが発生すると、アプリケーションに通知されますが、ロールバックは実行されません。

INAME

用途

入力ファイル名を指定します。

構文

INAME=filename

デフォルト値

なし

使用上の注意

インラインでは入力できません。

プリコンパイル時は、すべての入力ファイル名を一意にする必要があります。

コマンドラインから入力ファイルの名前を指定する場合は、キーワードINAMEは省略できます。たとえば、Pro*COBOLでは、INAME=myprog.pcoと指定するかわりにmyprog.pcoと指定できます。

このように、INAMEの指定でファイル拡張子を使用する必要はありません(ただし、ファイル拡張子が標準以外の場合には拡張子を指定する必要があります)。UNIXプラットフォームでは、Pro*COBOLはデフォルトの入力ファイル拡張子pcoを使用します。

INCLUDE

用途

EXEC SQL INCLUDEファイルのディレクトリ・パスを指定します。このオプションは、ディレクトリを使用するオペレーティング・システム専用です。

構文

INCLUDE=path

デフォルト値

カレント・ディレクトリ

使用上の注意

Pro*COBOLは、最初にカレント・ディレクトリを検索し、次にINCLUDEで指定されたディレクトリを検索して、最後に標準INCLUDEファイル用のディレクトリを検索します。このため、標準ファイルのディレクトリ・パスを指定する必要はありません。

しかし、標準以外のファイルについては、カレント・ディレクトリに格納されている場合を除いて、INCLUDEを使用してディレクトリ・パスを指定する必要があります。次に示すように、コマンドラインに複数のパスを指定できます。

... INCLUDE=path1 INCLUDE=path2 ...

Pro*COBOLは、最初にカレント・ディレクトリを検索し、次にpath1で指定されたディレクトリを検索し、続いてpath2で指定されたディレクトリを検索して、最後に標準INCLUDEファイル用のディレクトリを検索します。

注意: ディレクトリ・パスを指定しても、Pro*COBOLは最初にカレント・ディレクトリを検索します。このため、INCLUDEするファイルがカレント・ディレクトリ以外の場所に存在する場合は、同じ名前のファイルがカレント・ディレクトリに存在しないことを確認してください。

ディレクトリ・パスを指定するための構文はシステムによって異なります。使用しているオペレーティング・システムの規則に従って指定してください。

IRECLEN

用途

入力ファイルのレコード長を指定します。

構文

IRECLEN=integer

デフォルト値

80

使用上の注意

インラインでは入力できません。

IRECLENには、ORECLENの値より大きい値は指定できません。指定可能な最大値はシステムによって異なります。

LITDELIM

用途

LITDELIMオプションは、Pro*COBOLが生成するCOBOLコード内の文字列定数およびリテラルのデリミタを指定します。

構文

LITDELIM={APOST | QUOTE}

デフォルト値

QUOTE

使用上の注意

LITDELIM=APOSTと指定すると、Pro*COBOLはCOBOLコードを生成するときに引用符を使用します。LITDELIM=QUOTEを指定すると、次に示すように二重引用符が使用されます。

CALL "SQLROL" USING SQL-TMP0.

SQL文では、次の例に示すように、特殊文字または小文字を含む識別子は二重引用符で区切る必要があります。

EXEC SQL CREATE TABLE "Emp2" END-EXEC.

また、文字列定数を区切る場合は、次の例のように引用符を使用します。

EXEC SQL SELECT ENAME FROM EMP WHERE JOB = 'CLERK' END-EXEC.

Pro*COBOLは、Pro*COBOLソース・ファイルで使用されているデリミタに関係なく、LITDELIMの値で指定されたデリミタを使用します。

LNAME

用途

リスト・ファイルのデフォルト以外の名前を指定します。

構文

LNAME=filename

デフォルト値

入力します。

使用上の注意

インラインでは入力できません。

デフォルトでは、リスト・ファイルはカレント・ディレクトリに作成されます。

LRECLEN

用途

リスト・ファイルのレコード長を指定します。

構文

LRECLEN=integer

デフォルト値

132

使用上の注意

インラインでは入力できません。

LRECLENの値の範囲は、80から132です。80未満の値を指定した場合は、80がセットされます。この範囲より大きい値を指定すると、エラーが発生します。行番号を挿入できるように、LRECLENの値がIRECLENより8以上大きくなるように指定してください。

LTYPE

用途

リスト・ファイルの型を指定します。

構文

LTYPE={LONG | SHORT | NONE}

デフォルト値

LONG

使用上の注意

インラインでは入力できません。

表14-4 リスト・ファイルの型

リスト・ファイルの型

説明

LTYPE=LONG

リスト・ファイルに入力行が表示されます。

LTYPE=SHORT

リスト・ファイルに入力行は表示されません。

LTYPE=NONE

リスト・ファイルが作成されません。

MAX_ROW_INSERT

用途

INSERT文の実行前にバッファする必要がある行の数を制御します。

構文

max_row_insert={0から1000}

デフォルト値

0

使用上の注意

0よりも大きい任意の値を指定すると、バッファ済INSERT機能が有効化され、INSERT文の実行前に多くの行がバッファされます。

MAXLITERAL

用途

コンパイラの制限を超えないように、Pro*COBOLが生成する文字列リテラルの最大長を指定します。たとえば、コンパイラが132文字より長い文字列リテラルを処理できない場合は、コマンドラインにMAXLITERAL=132と指定します。

構文

MAXLITERAL=integer

デフォルト値

1024

使用上の注意

MAXLITERALの最大値は、コンパイラによって異なります。デフォルト値は言語によって異なりますが、このデフォルト値より小さい値を指定する必要がある場合があります。たとえば、一部のCOBOLコンパイラでは、132文字より長い文字列リテラルを処理できないため、その場合はMAXLITERAL=132と指定します。

MAXLITERALで指定した長さを超える文字列はプリコンパイル中に分割され、実行時に再び結合(連結)されます。

インラインでMAXLITERALを入力することはできますが、プログラムで値を設定できるのは1回のみで、EXEC ORACLE文を最初のEXEC SQL文の前に指定する必要があります。指定しない場合、Pro*COBOLは警告メッセージを発行し、余分または誤って指定したEXEC ORACLE文を無視して、処理を続行します。

MAXOPENCURSORS

用途

Pro*COBOLがキャッシュに保存しておける、同時にオープンされるカーソル数を指定します。

構文

MAXOPENCURSORS=integer

デフォルト値

10

使用上の注意

MAXOPENCURSORSを使用すると、プログラムのパフォーマンスを改善できます。詳細は、付録C「パフォーマンス・チューニング」を参照してください。

個別にプリコンパイルする場合は、「分割プリコンパイル」の説明に従ってMAXOPENCURSORSを指定してください。

MAXOPENCURSORSオプションには、SQLLIBカーソル・キャッシュの初期サイズを指定します。

HOLD_CURSOR=NOのときに、暗黙的な文が実行されるか明示カーソルがクローズされると、カーソル・エントリは再利用可能とマークされます。この文が再び発行された時にカーソル・エントリが別の文に使用されていなければ、カーソルは再利用されます。

割当て済のカーソル数がMAXOPENCURSORSに満たない場合に新しいカーソルが必要になると、キャッシュに格納された次のカーソルが割り当てられます。MAXOPENCURSORSが上限を超えると、Oracleはまず1つ前のエントリの再利用を試みます。空きエントリがない場合は、追加のキャッシュ・エントリが割り当てられます。Oracleはプログラムがメモリー不足になるか、データベース・パラメータOPEN_CURSORSが上限を超えるまで、この作業を続けます。

通常の処理では、HOLD_CURSORS=NOでRELEASE_CURSOR=NO (デフォルト)を使用するときには、データ・ディクショナリで使用されるカーソルが文を処理できるように、MAXOPENCURSORSの値をOPEN_CURSORSデータベース・パラメータの値より6以上小さい値に設定しないことをお薦めします。

プログラムが同時に必要とするオープン・カーソルの数が増えて、MAXOPENCURSORSを再指定する必要がある場合もあります。45から50の値を指定することは珍しくありませんが、ユーザー・プロセスのメモリー領域にカーソル1つにつき、1つのプライベートSQL領域が必要なことに注意してください。デフォルト値の10は、大半のプログラムには適切な値です。

MODE

用途

このマクロ・オプションは、プログラムがOracleの基準に従うか、現行のANSI SQL規格に準拠するかを指定します。

構文

MODE={ANSI | ISO | ANSI14 | ISO14 | ANSI13 | ISO13 | ORACLE}

デフォルト値

ORACLE

使用上の注意

インラインでは入力できません。

MODE値のANSIとISO、ANSI14とISO14、ANSI13とISO13それぞれのペアの値は等価です。

MODE=ORACLE (デフォルト)のとき、埋込みSQLプログラムはOracleの動作規則に従います。

MODE={ANSI14 | ANSI13}と指定した場合、プログラムはほぼ現行のANSI SQL規格に準拠します。

MODE=ANSIと指定した場合、プログラムは完全にANSI規格に準拠し、次のような変更が加えられます。

- すでにオープンされているカーソルをOPENしたり、すでにクローズされているカーソルをCLOSEすることはできません。(MODE=ORACLEの場合は、再解析を避けるためにオープンされているカーソルを再オープンできます。)

- Oracleが切り捨てられた列値を出力ホスト変数に割り当てた場合、エラー・メッセージは発行されません。

MODE={ANSI | ANSI14}と指定した場合、SQLCODEの4バイトの整変数またはSQLSTATEの5バイトの文字変数を宣言する必要があります。詳細は、「エラー処理の代替手段」を参照してください。

NESTED

用途

ネストしたプログラムのGLOBAL句が生成されたかどうかを示します。コンパイラがネストしたプログラムをサポートしている場合は、NESTED値としてYESを使用します。

構文

NESTED={YES | NO}

デフォルト値

YES

使用上の注意

インラインでは入力できません。

NLS_LOCAL

用途

NLS_LOCALオプションは、グローバリゼーション・サポート(旧称「NLS」)文字変換がPro*COBOLランタイム・ライブラリまたはOracleサーバーのどちらかによって実行されるかを指定します。

構文

NLS_LOCAL={YES | NO}

デフォルト値

NO

使用上の注意

インラインでは入力できません。

このオプションは、サーバーとの間で各国語キャラクタ・セット変数を受け渡しするのに使用します。

NLS_LOCAL=YESと指定した場合、マルチバイト・グローバリゼーション・サポート・データ型を持つホスト変数の空白埋込みおよび空白削除はランタイム・ライブラリ(SQLLIB)によってローカルに実行されます。リリース8.0以前のリリース用に記述されたPro*COBOLアプリケーションの場合は、引き続きこの値を使用します。

NLS_LOCAL=YESの場合、動的SQL文はプリコンパイル時には処理されないので、このオプションは動的SQL文に対して効力を持ちません。

また、NLS_LOCAL=YESのときは、マルチバイト・グローバリゼーション・サポート・データを格納する列は、埋込みデータ定義言語(DDL)文で使用できません。この制限はプリコンパイル時には適用されないため、このような列型を埋込みDDL文で使用すると、プリコンパイル・エラーではなく実行エラーが発生します。

NLS_LOCAL=NOと指定した場合は、マルチバイト・グローバリゼーション・サポート・データ型を持つホスト変数の空白埋込みおよび空白削除の操作はOracleサーバーによって行われます。新しいOracle8.0以上のアプリケーションについては、すべてこの値を使用してください。

環境変数NLS_NCHARでは、各国語キャラクタ・セット・データに使用するキャラクタ・セットを指定します。(NCHAR、NVARCHAR2、NCLOB)。キャラクタ・セットを指定しない場合は、定義済、あるいはNLS_LANGで間接的に定義済のキャラクタ・セットが使用されます。詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』のNLS_LANGの項を参照してください。

ONAME

用途

出力ファイル名を指定します。

構文

ONAME=filename

デフォルト値

システムによって異なります。

使用上の注意

インラインでは入力できません。

このオプションは、出力ファイルの名前が入力ファイルの名前と異なる場合に、出力ファイルの名前を指定するために使用します。たとえば、次のコマンドを発行したとします。

procob INAME=my_test

デフォルト出力ファイル名は、my_test.cobです。出力ファイル名をmy_test_1.cobにする場合は、次のコマンドを発行します。

procob INAME=my_test ONAME=my_test_1.cob

ONAMEを使用して指定するファイルには、.cob拡張子を付けてください。ONAMEオプションにはデフォルトの拡張子はありません。

注意: 出力ファイルにはデフォルト名を使用するのではなく、ONAMEオプションで明示的に指定してください。

ORACA

用途

プログラムがOracle通信領域(ORACA)を使用できるかどうかを指定します。

構文

ORACA={YES | NO}

デフォルト値

NO

使用上の注意

ORACA=YESと指定した場合は、プログラムにINCLUDE ORACA文を記述する必要があります。

ORECLEN

用途

出力ファイルのレコード長を指定します。

構文

ORECLEN=integer

デフォルト値

80

使用上の注意

インラインでは入力できません。

ORECLENに指定する値は、IRECLENの値と同じか、それより大きい値にする必要があります。指定可能な最大値はシステムによって異なります。

OUTLINE

用途

SQL文に対してアウトラインSQLファイルを生成する必要があることを示します。

構文

outline={yes | no | category_name}

デフォルト値

無効

使用上の注意

値がyesの場合、アウトラインSQLファイルはDEFAULTカテゴリに含まれている必要があります。生成されるアウトライン書式は次のとおりです。

DEFAULT_<filename>_<filetype>_<sequence_no>

カテゴリ名が示されている場合は、そのカテゴリにSQLファイルを生成する必要があります。この場合、生成されるアウトライン書式は次のようになります。

<category_name>_<filename>_<filetype>_<sequence_no>

値がnoの場合、アウトラインSQLファイルは生成されません。

このオプションを有効にする場合は、意味検査をフルにする必要があり、つまりオプションsqlcheck=full/semanticsを意味します。sqlcheck=syntax/limited/noneの場合は、エラーが生成されます。

OUTLNPREFIX

用途

アウトライン名の生成を制御します。

構文

outlnprefix={none | prefix_name}

デフォルト値

無効

使用上の注意

outlnprefix=prefix_nameの場合、アウトライン書式は次のとおりです。

<category_name>_<filename>_<filetype>

この書式は、アウトライン名の<prefix_name>に置き換えられます。

アウトライン名が30バイトを超える場合、このオプションは接頭辞名を指定する際に有効です。

outlnprefix=noneの場合、アウトライン名はシステムによって生成されます。次の書式で生成されます。

<category_name>_<filename>_<filetype>_<sequence_no>

このオプションを有効にする場合は、意味検査をフルにする必要があり、つまりオプションsqlcheck=full/semanticsを意味します。sqlcheck=syntax/limited/noneまたはoutline=false(あるいはその両方)の場合、エラーが生成されます。

PAGELEN

用途

リスト・ファイルの物理ページ当たりの行数を指定します。

構文

PAGELEN=integer

デフォルト値

66

使用上の注意

インラインでは入力できません。指定可能な最大値はシステムによって異なります。

PICN_ENDIAN

用途

PIC N変数にプラットフォームのエンディアン形式(LinuxおよびWindowsの場合はリトル・エンディアン形式、Solarisの場合はビッグ・エンディアン形式)を保持します。

構文

picn_endian={BIG | OS}

デフォルト値

BIG

使用上の注意

picn_endian=bigの場合、PIC N変数はキャラクタ・セットID AL16UTF16にバインドされます。

picn_endian=osの場合、PIC N変数はキャラクタ・セットID UCS2にバインドされます。

このオプションのデフォルト値は「big」で、現行の動作が保持されます。NLS_NCHARがAL16UTF16でない場合、このオプションは無視されます。

PIC N変数のキャラクタ・セットの形式は、既存のPro*Cobolコマンドライン・オプション(charset_picn={nchar_charset | db_charset})を使用して設定できます。

PICX

用途

PIC X変数のデフォルトのデータ型を指定します。

構文

PICX={CHARF | VARCHAR2}

デフォルト値

CHARF

使用上の注意

コマンドラインまたは構成ファイルからのみ入力できます。

Pro*COBOL 8.0からは、PIC X、NまたはG変数のデフォルトのデータ型がVARCHAR2からCHARFに変わりました。PICXは、下位互換性を維持するために用意されているオプションです。

新しいデフォルトの動作は、COBOLの標準の移動規則と整合がとれています。新しい方式により、PIC X変数を(MODE=ORACLEと指定して) VARCHAR2列に挿入した場合の動作が変わります。以前は後続ブランクは切り捨てられましたが、切り捨てられなくなります。また、新しいデフォルトにより、バインド変数の後続ブランクが比較の前に切り捨てられるので、WHERE句で後続ブランク付きで初期化したPIC Xバインド変数を使用すると、char列に格納された同数の後続ブランクを持つ値と一致しないという状態が少なくなります。

PICX=VARCHAR2と指定した場合、OracleはPL/SQLブロック内のローカルCHAR変数を可変長文字値のように扱います。PICX=CHARFと指定した場合は、OracleはCHAR変数をANSI準拠の固定長文字値のように扱います。詳細は、「PIC Xのデフォルト」を参照してください。

PLAN_BASELINE

用途

モジュール名を指定してSQL計画ベースラインを作成します。

構文

PLAN_BASELINE={module_name | YES | NO}

デフォルト値

NO

使用上の注意

このモジュール名の後にファイル名、ファイル・タイプおよび順序番号が付いて、一意の計画名が生成されます。

PLAN_PREFIX

用途

計画名が30バイト以内であることを確認します。

構文

PLAN_PREFIX={prefix_name| none}

デフォルト値

なし

使用上の注意

これはオプションです。デフォルトはnoneで、接頭辞名が使用されないことを意味し、計画名が30バイトを超えるとエラー・メッセージが生成されます。

PLAN_RUN

用途

生成されたSQLファイルを実行します。

構文

PLAN_RUN={YES | NO}

デフォルト値

NO

使用上の注意

PLAN_RUNオプションを設定しない場合、生成されるSQLファイルは実行されません。

PLAN_FIXED

用途

作成した計画ベースラインが固定であるか、非固定であるかを指定します。

構文

PLAN_FIXED={ YES | NO }

デフォルト値

YES

使用上の注意

NOを設定すると、非固定の計画ベースラインが作成されます。

PLAN_ENABLED

用途

作成された計画ベースラインの使用を有効にします。

構文

PLAN_ENABLED={ YES | NO }

デフォルト値

YES

使用上の注意

デフォルトの設定では、計画の選択時に、作成された計画ベースラインが使用されます。NOを設定すると、計画ベースラインが作成されますが、手動で有効にするまで使用されません。

MEMFORPREFETCH

用途

このオプションを使用すると、指定したメモリーに格納可能な行数をプリフェッチすることによって、問合せが高速化します。

構文

MEMFORPREFETCH=integer

デフォルト値

値は設定されていません。

使用上の注意

このオプションは、構成ファイルまたはコマンドラインで使用できます。優先順位の規則に従い、明示カーソルを使用するすべての問合せの実行に、整数の値が使用されます。

インラインで使用するときは、明示カーソルを使用し、OPEN文の前に配置する必要があります。OPEN文が実行されたときにプリフェッチされる行数は、有効な最後のインラインMEMFORPREFETCHオプションによって決まります。

MEMFORPREFETCHは、デフォルトでは値が設定されていません。プリフェッチをオフにするには、コマンドラインでMEMFORPREFETCH=0を使用します。

LONG列およびLOB列へのアクセス中もプリフェッチはオフになります。MEMFORPREFETCHを使用すると、単一行フェッチのパフォーマンスが向上します。配列フェッチを実行する場合、MEMFORPREFETCHの値は割り当てた値に関係なく無効になります。

アプリケーションにおけるすべてのフェッチを支援できる完全なプリフェッチ・メモリー値はありません。

したがって、MEMFORPREFETCHオプションを使用する場合は、様々な値をテストし、プログラム内のすべての文にわたってパフォーマンスが向上する値を選択してください。いくつかの文を個別にチューニングする必要がある場合は、EXEC ORACLE OPTIONを使用してMEMFORPREFETCHオプションをインラインで指定します。この操作は、このコマンドの後のすべてのフェッチ文に影響を与えます。特定のFETCH文のパフォーマンスが向上するようにプリフェッチ・メモリーを選択してください。この個別プリフェッチ・カウントを実現するには、(コマンドラインからではなく)インラインのプリフェッチ・オプションを指定します。

PREFETCH

用途

このオプションを使用して一定の行数をプリフェッチすると、問合せが高速化します。

構文

PREFETCH=integer

デフォルト値

1

使用上の注意

構成ファイルまたはコマンドラインで入力できます。優先順位の規則に従い、明示カーソルを使用するすべての問合せの実行に、整数の値が使用されます。

インラインで使用するときは、明示カーソルを使用し、OPEN文の前に配置する必要があります。OPEN文が実行されたときにプリフェッチされる行数は、有効な最後のインラインPREFETCHオプションによって決まります。

PREFETCHのデフォルトは1です。プリフェッチをオフにするには、コマンドラインでPREFETCH=0を指定します。

LONG列およびLOB列へのアクセス中もプリフェッチはオフになります。PREFETCHを使用すると、単一行フェッチのパフォーマンスが向上します。配列フェッチを実行する場合、PREFETCHの値は割り当てた値に関係なく無効になります。

アプリケーションにおけるすべてのフェッチを支援できる完全なプリフェッチ番号はありません。

したがって、PREFETCHオプションを使用する場合は、様々な値をテストし、プログラム内の文全般にわたってパフォーマンスを向上させるものを選択してください。特定の文を個別にチューニングする必要がある場合は、EXEC ORACLE OPTIONを使用してPREFETCHオプションをインラインで指定します。この操作は、プログラム内でこのコマンドに続くすべてのフェッチ文に影響を与えます。特定のFETCH文のパフォーマンスが向上するようにプリフェッチ番号を選択してください。この個別プリフェッチ・カウントを実現するには、インラインのプリフェッチ・オプションを指定します。(コマンドラインからではなく。)

最大値は9999です。詳細は、「PREFETCHプリコンパイラ・オプション」を参照してください。

RELEASE_CURSOR

用途

カーソル・キャッシュでのSQL文およびPL/SQLブロック用カーソルの取扱い方法を指定します。

構文

RELEASE_CURSOR={YES | NO}

デフォルト値

NO

使用上の注意

RELEASE_CURSORを使用すると、プログラムのパフォーマンスを改善できます。詳細を参照してください。

SQLデータ操作文を実行すると、その文に関連付けられたカーソルが、カーソル・キャッシュ内のエントリにリンクされます。そのカーソル・キャッシュ・エントリは、文の処理に必要な情報が格納されるOracleプライベートSQL領域にリンクされます。RELEASE_CURSORは、カーソル・キャッシュとプライベートSQL領域の間のリンクで発生する処理を制御します。

RELEASE_CURSOR=YESと指定した場合、OracleがSQL文を実行してカーソルがクローズされると、Pro*COBOLはただちにリンクを削除します。これにより、プライベートSQL領域に割り当てられたメモリーが解放され、解析ロックが解除されます。カーソルのCLOSE時に関連リソースが確実に解放されるようにするには、RELEASE_CURSOR=YESを指定する必要があります。

RELEASE_CURSOR=NOを指定すると、リンクは保持されます。オープンされているカーソルの数がMAXOPENCURSORSの値を超えないかぎり、Pro*COBOLはリンクを再利用しません。この設定によって後に続く処理の実行速度が向上するため、これは実行頻度の高いSQL文には便利です。文を解析しなおしたり、OracleプライベートSQL領域にメモリーを割り当てる必要がないためです。

暗黙カーソルをインラインで使用する場合は、SQL文の実行前にRELEASE_CURSORを設定してください。明示カーソルをインラインで使用する場合は、カーソルをオープンする前にRELEASE_CURSORを設定してください。

RELEASE_CURSOR=YESはHOLD_CURSOR=YESをオーバーライドすることに注意してください。前述の2つのオプションの相互動作に関する詳細は、付録C「パフォーマンス・チューニング」の表C-1「HOLD_CURSORおよびRELEASE _CURSORの相互関係」を参照してください。

RUNOUTLINE

用途

プリコンパイラを使用して、または後で開発者が手動で「CREATE OUTLINE」文を実行するオプションを提供します。

構文

runoutline={yes | no}

デフォルト値

無効

使用上の注意

runoutline=yesの場合は、プリコンパイルが正常に完了した後で、プリコンパイラ/トランスレータによって、生成された「CREATE OUTLINE」文が実行されます。

RUNOUTLINEを使用する場合は、アウトライン・オプションをtrueまたはcategory_nameに設定する必要があります。このオプションを有効にする場合は、意味検査をフルにする必要があり、つまりオプションsqlcheck=full/semanticsを意味します。sqlcheck=syntax/limited/noneの場合は、エラーが生成されます。

SELECT_ERROR

用途

SELECT文で複数の行が戻されたり、ホスト配列に入りきらない数の行が戻された場合に、プログラムがエラーを発行するかどうかを指定します。

構文

SELECT_ERROR={YES | NO}

デフォルト値

YES

使用上の注意

SELECT_ERROR=YESと指定すると、1行を戻す選択で複数行が戻された場合や、配列の選択でホスト配列に入りきらない数の行が戻された場合にはエラーが発生します。

SELECT_ERROR=NOと指定すると、1行を戻す選択で複数行が戻された場合や、配列の選択でホスト配列に入りきらない数の行が戻された場合でも、エラーは発生しません。

YESを指定してもNOを指定しても、行は表から無作為に選択されます。選択する行の順序を特定するには、SELECT文にORDER BY句を指定します。SELECT_ERROR=NOのときORDER BY句を指定すると、配列からの選択時にOracleは先頭行または先頭のn行を戻します。SELECT_ERROR=YESを指定すると、ORDER BY句の有無を問わず、戻る行数が多すぎる場合にエラーが生成されます。

SQLCHECK

用途

構文および意味チェックのタイプとレベルを指定します。

SQLCHECK=SEMANTICSまたはFULLの場合、SQL文は、解析中に一般的な文法を使用してIDLオブジェクトにパッケージ化またはバンドルされます。一般的な文法では、SQL構文は解釈されず、ホスト変数、標識変数および可能なSQL識別子のみが識別されます。意味フェーズ中に、SQLに対して行われると同じ方法で、ホスト変数および標識変数の妥当性がチェックされます。SQLに対して処理されるのと同じ方法で、表名、列名、タイプなどのセマンティクスがチェックされます。

新しく統合されたパーサーには、次の特徴があります。

1. 既存のすべてのプリコンパイラ・アプリケーションをプリコンパイルします。

2. 次のSQL文を完全に(SQL文のすべての句を対象に)サポートします。

1. SELECT文

2. INSERT文

3. DELETE文

4. UPDATE文

5. DECLARE CURSOR文のカーソル本体

構文

SQLCHECK={SEMANTICS | FULL | SYNTAX | LIMITED}

デフォルト値

SYNTAX

使用上の注意

値SEMANTICSとFULLは等価で、SYNTAXとLIMITEDも等価です。

Pro*COBOLは、埋込みSQL文およびPL/SQLブロックの構文と意味をチェックすると、プログラムのデバッグを支援します。検出されたエラーはプリコンパイル時にレポートされます。

チェックのレベルを制御するには、コマンドラインまたはインライン、あるいはその両方でSQLCHECKオプションを入力します。ただし、インラインで指定するチェックのレベルを、コマンドラインで指定する(またはデフォルトによって受け入れる)レベルよりも高くすることはできません。

PL/SQLの予約語がSQL文で使用されていると、そのSQL文がPL/SQLでない場合でも、Pro*COBOLはエラーを発行します。PL/SQLの予約語を識別子として使用する必要がある場合は、二重引用符(")で囲んでください。

SQLCHECK=SEMANTICSと指定した場合、Pro*COBOLは次の項目を対象として構文および意味上のチェックを行います。

- INSERTやUPDATEなどのDML文

- PL/SQLブロック

ただし、リモートDML文(AT db_name句を使用するDML文)については、Pro*COBOLにより構文上のチェックのみ行われます。

Pro*COBOLは、意味検査に必要な情報を、埋め込まれたDECLARE TABLE文から取得します。また、オプションUSERIDが指定されている場合は、Oracleに接続してデータ・ディクショナリにアクセスするとこの情報を取得します。データ操作文やPL/SQLブロックで参照する表がすべてDECLARE TABLE文で定義されている場合は、Oracleに接続する必要があります。

Oracleに接続してデータ・ディクショナリにアクセスしても見つからない情報があった場合は、DECLARE TABLE文を使用して欠けている情報を提供する必要があります。プリコンパイル時にDECLARE TABLE文の定義とデータ・ディクショナリの定義の内容が矛盾する場合は、DECLARE TABLE文の定義が使用されます。

新しいプログラムをプリコンパイルするときは、SQLCHECK=SEMANTICSを指定してください。ホスト・プログラムにPL/SQLブロックを埋め込む場合は、SQLCHECK=SEMANTICSと指定し、オプションUSERIDを指定する必要があります。

SQLCHECK=SEMANTICSまたはFULLの場合、SQL文は最初にローカルで解析されます。ホスト変数と標識変数の検証、およびSQL識別子の妥当性のチェックは、埋込みDECLARE TABLE文を使用するか、またはコマンドラインでユーザーIDを指定する際にサーバーに接続することによって実行されます。SQLCHECK = SEMANTICSまたはFULLの場合、解析は2回(プリコンパイラによって1回およびPL/SQLによって1回)実行されます。SQLで新しい構文が使用可能になった際に、新しい構文を受け入れるようにSQLのローカルの文法が更新されていないと、PL/SQLインタフェースをコールする前に新しい構文でプリコンパイラが失敗します。

SQLCHECK=SYNTAXと指定した場合、Pro*COBOLはDML文の構文チェックを行います。SQL文はローカルで解析されます。このコマンドライン・オプションで、プリコンパイラは表名または列名を検証しません。SQLCHECK=SYNTAXの場合は、クライアント側SQLインタフェースを使用してSQL文の構文がチェックされます。

意味上のチェックは行いません。DECLARE TABLE文は無視され、PL/SQLブロックは使用できません。DML文のチェックには、Pro*COBOLは下位互換性のあるOracle構文規則を使用します。プリコンパイル済のプログラムを移行する場合は、SQLCHECK=SYNTAXを指定してください。

表14-5に、SQLCHECKで行われる検査を示します。構文検査および意味検査の詳細は、付録D「構文および意味検査」を参照してください。

表14-5 SQLCHECKによる検査

-

SQLCHECK=
SEMANTICS

-

SQLCHECK=SYNTAXの指定

-

-

構文

意味

構文

意味

DML

可

可

可

-

リモートDML

可

-

可

-

PL/SQL

可

可

-

-

統合されたパーサーの制限

Pro*COBOLの統合されたパーサーの制限事項は、次のとおりです。

- Pro*COBOLでは、':'(コロン)を含まない変数はサポートされません。

- 表の定義は使用できません。CSFモードでは、plsqlはDECLARE TABLE文が渡されると失敗します。

- 次の例で、sqlcheck=syntaxおよびcommon_parser=yesを使用すると失敗します。

select ename into :empname from emp@dblink;

以前のバージョンでは、sqlcheck=syntaxを使用すると、ローカル解析のみが実行されました。現在は、sqlcheck=syntaxおよびcommon_parser=yesの場合に、文はバンドルされてpcisyn()に送信されます。dblinkを使用する際に接続が存在しないと、PLSQLが失敗します。

前述の文は、次の形式でプリコンパイルされます。

sqlcheck=full userid=<userid> common_parser=yes

- INSERTのエラー処理は、通常の順序で実行されません。XYZがグループ項目である次の文を考えてみます。

insert into emp (empno, ename) values (:XYZ)

PLSQLでは、INSERT文の構文チェック中にグループ項目または構造が許可されません(PLSQLの制限)。INSERT用にグループ項目を個々の要素に分割する必要があります。このため、プリコンパイラは、構文フェーズ自体で上述の文をinsert into emp (empno, ename) values (:b1,:b2)に展開する必要があります。

この展開は、構文フェーズでは実行できません。このため、プリコンパイラの構文フェーズでは、他の文に対して行われるようにpcisyn()はコールされません。文は、INSERT文のみのプリコンパイラの意味フェーズまで遅延します。最終的な影響として、エラー・メッセージは通常の順序で実行されない可能性があります。次に例を示します。

EXEC SQL insert into emp (empno, ename) alues (:XYZ) END-EXEC.
^^^^^ syntax error at 'alues'
EXEC SQL select ename into :empname fro emp END-EXEC.
^^^ syntax error at 'fro'

理想的なエラーの順序は、次のとおりです。

syntax error at 'alues' in INSERT
syntax error at 'fro' in SELECT

前述の制限のために、エラーの順序は次のようになります。

syntax error at 'fro' in SELECT
syntax error at 'alues' in INSERT

注意:
報告されるエラーには、行番号が付けられます。このため、プログラムで使用される順序と異なっても、Pro*Cobolプログラマは簡単に行を識別できます。

STMT_CACHE

用途

動的SQL文の文のキャッシュ・サイズを示します。

構文

STMT_CACHE = 0から65535

デフォルト値

0

使用上の注意

stmt_cacheオプションを設定すると、アプリケーションでそれぞれの動的SQL文の予測数を保持できます。

TYPE_CODE

用途

このMODEマイクロ・オプションでは、ANSI動的SQL方法4でANSIまたはOracleデータ型コードのどちらを使用するかを決定します。この設定は、MODEオプションの設定と同じです。

構文

TYPE_CODE={ORACLE | ANSI}

デフォルト値

ORACLE

使用上の注意

インラインでは入力できません。

設定できるオプションの詳細は、表10-3を参照してください。

UNSAFE_NULL

用途

UNSAFE_NULL=YESを指定すると、標識変数を使用せずにNULLをフェッチしてもORA-01405メッセージは生成されません。

構文

UNSAFE_NULL={YES | NO}

デフォルト値

NO

使用上の注意

インラインでは入力できません。

MODE=ORACLEの場合のみ、UNSAFE_NULL=YESを設定できます。

埋込みPL/SQLブロックのホスト変数ではUNSAFE_NULLオプションは何の効果もありません。ORA-01405エラーの発生を避けるために、必ず標識変数を使用してください。

UNSAFE_NULL=YESと指定すると、SELECT文またはFETCH文でNULLが選択され、出力ホスト変数に対応する標識変数がない場合でも、エラーは戻されません。UNSAFE_NULL=NOと指定した場合、対応する標識変数のないホスト変数にNULLの列または式を選択またはフェッチすると、エラーが発生します(SQLSTATEは22002に、SQLCODEはORA-01405に設定されます)。

USERID

用途

Oracleユーザー名およびパスワードを指定します。

構文

USERID=username/password[@dbname]

デフォルト値

なし

使用上の注意

インラインでは入力できません。

SQLCHECK=SEMANTICSと指定した場合に、Oracleに接続してデータ・ディクショナリにアクセスすることによりPro*COBOLが必要な情報を得られるようにする場合は、USERIDも指定してください。データベース別名はオプションです。大カッコは、入力しないでください。

VARCHAR

用途

VARCHARオプションは、第5章「埋込みSQL」で説明したCOBOLのグループ項目をVARCHARデータ型として扱うようにPro*COBOLに指示します。

構文

VARCHAR={YES | NO}

デフォルト値

NO

使用上の注意

インラインでは入力できません。

VARCHAR=YESと指定した場合、第5章「埋込みSQL」で説明した暗黙的なグループ項目を、長さフィールドおよび文字列フィールドを持つVARCHAR外部データ型として受け入れます。

VARCHAR=NOと指定した場合、Pro*COBOLは暗黙的なグループ項目をVARCHAR外部データ型として受け入れません。

XREF

用途

リスト・ファイルに相互参照セクションを組み込むかどうかを指定します。

構文

XREF={YES | NO}

デフォルト値

YES

使用上の注意

XREF=YESと指定すると、ホスト変数、カーソル名および文名にクロス・リファレンスが組み込まれます。クロス・リファレンスは、個々のオブジェクトがプログラム内のどこで定義され、どこで参照されているかを示します。

XREF=NOと指定した場合は、相互参照セクションは組み込まれません。

A オペレーティング・システムの依存性

COBOLプログラミングの詳細は、システムによって異なります。この付録は、Pro*COBOLに関するシステム固有の問題をまとめたものです。マニュアル・セット内の他の資料を参照できる場合は、適宜記載してあります。

このマニュアルにあるシステム固有の参照情報

システム固有の参照情報を、項目ごとに分類して次の項で説明します。

COBOLのバージョン

Pro*COBOLプリコンパイラは、オペレーティング・システムで使用される標準的なCOBOL (通常はCOBOL-85またはCOBOL-74)の導入をサポートしています。両方のCOBOLをサポートするプラットフォームもあります。使用しているシステム固有のOracleマニュアルを参照してください。

ホスト変数

ホスト変数の宣言方法およびネーミング方法は、使用しているCOBOLコンパイラによって異なります。ホスト変数の宣言およびネーミングの詳細は、使用しているCOBOLのユーザーズ・ガイドを参照してください。

宣言

ホスト変数の宣言は、COBOLの規則に従って、OracleでサポートされるCOBOLデータ型を使用して行います。表4-6「ホスト変数の宣言」は、指定できるCOBOLデータ型および擬似型を示しています。ただし、使用しているCOBOLによっては、すべての型が指定可能とはかぎりません。

ネーミング

ホスト変数名には英文字、数字およびハイフン以外は使用できません。また、英文字で始める必要があります。長さは任意ですが、有効なのは先頭の30文字までです。コンパイラによっては、最大長が異なるものもあります。

Pro*COBOLの制限により、SQLLIB (Cルーチン)と対話したとき、ホスト変数の境界の位置が正しくない場合、予期しない結果が発生する可能性があります。ホスト変数の境界位置の定義の詳細は、COBOLのマニュアルを参照してください。次のような処置が考えられます。

- FILLERを使用して手動で境界位置を指定

- 01レベル・エントリを使用して境界をFORCE

- データ・ソースがサード・パーティのコードである場合は、77レベル・エントリまたは01レベル・エントリの一時変数をホスト変数として使用。

INCLUDE文

INCLUDEは、どのファイルに対しても実行できます。Pro*COBOLプログラムをプリコンパイルすると、EXEC SQL INCLUDE文はそれぞれ、その文で指定されたファイルのコピーに置き換えられます。

システムでファイル拡張子を使用するがその拡張子を指定しない場合、Pro*COBOLプリコンパイラはソース・ファイルのデフォルトの拡張子(通常はCOB)を使用します。デフォルトの拡張子はシステムによって異なります。使用しているシステム固有のOracleマニュアルを参照してください。

システムがディレクトリを使用する場合は、プリコンパイラ・オプションINCLUDE=pathを指定すると、含まれるファイルのディレクトリ・パスを設定できます。しかし、標準以外のファイルについては、カレント・ディレクトリに格納されている場合を除いて、INCLUDEを使用してディレクトリ・パスを指定する必要があります。ディレクトリ・パスを指定するための構文はシステムによって異なります。使用しているシステム固有のOracleマニュアルを参照してください。

MAXLITERALのデフォルト

MAXLITERALプリコンパイラ・オプションを使用して、プリコンパイラが生成する文字列リテラルの最大長を指定し、コンパイラの制限を超えないようにできます。MAXLITERALのデフォルト値は256ですが、これより小さい値を指定する必要がある場合もあります。

たとえば、ご使用のCOBOLコンパイラで、132文字以上の文字列リテラルを扱えない場合は、「MAXLITERAL=132」を指定します。ご使用のCOBOLコンパイラのユーザーズ・ガイドをチェックしてください。MAXLITERALオプションの詳細は、第14章「プリコンパイラ・オプション」を参照してください。

マルチバイト・グローバリゼーション・サポート文字に対するPIC N句またはPIC G句

COBOLコンパイラの中には、マルチバイト・グローバリゼーション・サポート文字変数の宣言でPIC N句またはPIC G句を使用できないものがあります。ソース・コードを書くときにマルチバイト・キャラクタ変数を宣言するためにこれらの句を使用する場合は、COBOLのユーザーズ・ガイドを確認してください。

予測できないRETURN-CODE特殊レジスタ。

SQL文またはSQLLIB関数の後のRETURN-CODE特殊レジスタ(システムがサポートしている場合)の内容は予測できません。

バイナリ・データのバイト順序

一部のプラットフォームでは、COBOLコンパイラを使用するとバイナリ・データのバイト順序が逆転します。COMP5プリコンパイラ・オプションの詳細は、ご使用のプラットフォームのマニュアルを参照してください。

B 予約語、キーワードおよびネームスペース

この付録の構成は、次のとおりです。

- 予約語およびキーワード

- 予約済ネームスペース

予約語およびキーワード

一部の語はOracleで予約されています。予約語はOracleにおいて特別な意味を持っているため、再定義はできません。したがって、予約語は列、表または索引などのデータベース・オブジェクト名としては使用できません。SQLおよびPL/SQLのOracle予約語リストは、『Oracle Database SQL言語リファレンス』および『Oracle Database PL/SQL言語リファレンス』を参照してください。

Pro*COBOLキーワードは、COBOLキーワードと同様、プログラムで変数としては使用できません。変数として使用するとエラーが発生します。キーワードを列などのデータベース・オブジェクト名として使用すると、エラーが発生することがあります。Pro*COBOLで使用されるキーワードを次に示します。

キーワード

キーワード

キーワード

all

allocate

alter

analyze

and

any

append

arraylen

as

asc

assign

at

audit

authorization

avg

begin

between

bind

both

break

buffer

buffering

by

call

cast

char

character

character_set_name

charf

charz

check

chunksize

close

collection

comment

commit

connect

constraint

constraints

context

continue

convbufsz

copy

count

create

current

currval

cursor

data

database

date

dateformat

datelang

datetime_interval_code

datetime_interval_precision

day

deallocate

dec

decimal

declare

デフォルト

define

delete

deref

desc

describe

記述子

directory

disable

表示

distinct

do

double

drop

eject

else

enable

end

endif

end-exec

erase

escape

exec

execute

exists

explain

extract

fetch

file

fileexists

filename

first

float

flush

for

force

found

free

from

function

get

global

go

goto

grant

group

having

hold

host_stride_length

hour

iaf

identified

ifdef

ifndef

immediate

in

include

indicator

indicator_stride_length

input

insert

整数

internal_length

intersect

interval

into

is

isopen

istemporary

last

leading

length

level

like

list

load

lob

local

ロック

long

max

message

min

minus

minute

mode

month

multiset

name

national_character

nchar

nchar_cs

next

nextval

noaudit

not

notfound

nowait

NULL

nullable

number

numeric

nvarchar

nvarchar2

object

ocibfilelocator

ocibloblocator

ocicloblocator

ocidate

ociextproccontext

ocinumber

ociraw

ocirowid

ocistring

octet_length

of

one

only

open

option

または

oracle

order

output

overlaps

overpunch

package

partition

perform

precision

prepare

prior

procedure

put

raw

read

real

ref

参照

register

release

rename

replace

return

returned_length

returned_octet_length

returning

revoke

role

ロールバック

rowid

rownum

savepoint

位取り

second

section

select

設定

skip1

skip2

skip3

smallint

some

sql

sql_context

sql_cursor

sqlerror

sqlwarning

start

statement

stddev

stop

string

sum

sysdate

sysdba

sysoper

表

temporary

threads

time

timestamp

timezone_hour

timezone_minute

これを次のように変更します。

tools

title

trailing

transaction

trigger

trim

truncate

type

uid

ulong_varchar

union

unique

unsigned

user_defined_type_name

user_defined_type_name_length

user_defined_type_schema

user_defined_type_schema_length

user_defined_type_version

update

使用

user

using

validate

value

values

var

varchar

varchar2

variables

variance

varnum

varraw

view

whenever

この場合、各変数の意味は次のとおりです。

with

work

write

year

zone

予約されているネームスペース

表B-1に、Oracleにより予約されているネームスペースを示します。Oracleライブラリでは、サブプログラム名の最初の文字は、次に示す文字列に制限されます。名前が競合する可能性があるため、サブプログラムにはこれらの文字で始まらない名前を付けてください。

たとえば、Oracle Net Transparent Network Serviceの機能はすべて「NS」文字で始まるため、名前が「NS」で始まるサブプログラムを書かないようにします。

表B-1 予約されているネームスペース

ネームスペース

ライブラリ

XA

XAアプリケーション専用の外部関数

SQ

OracleプリコンパイラおよびSQL*モジュール・アプリケーションが使用する外部SQLLIB関数

O、OCI

外部OCI関数、内部OCI関数

UPI、KP

Oracle UPIレイヤーの関数名

NA

NC

ND

NL

NM

NR

NS

NT

NZ

OSN

TTC

Oracle Netネイティブ・サービス・プロダクト

Oracle Net RPCプロジェクト

Oracle Netディレクトリ

Oracle Netネットワーク・ライブラリ・レイヤー

Oracle Net管理プロジェクト

Oracle Netインターチェンジ

Oracle Netトランスペアレント・ネットワーク・サービス

Oracle Netドライバ

Oracle Netセキュリティ・サービス

Oracle Net V1

Oracle Net 2タスク

GEN、L、ORA

Coreライブラリ関数

LI、LM、LX

Oracleグローバリゼーション・サポート・レイヤーの関数名

S

システム依存ライブラリの関数名

C パフォーマンス・チューニング

この付録では、アプリケーションのパフォーマンス(性能)が向上する簡単な適用方法をいくつか紹介します。これらの方法を使用すると、多くの場合、処理時間を25%以上削減できます。内容は次のとおりです。

- パフォーマンスを低下させる原因

- パフォーマンスの向上

- ホスト表の使用方法

- PL/SQLおよびJavaの使用

- SQL文の最適化

- 索引の使用

- 行レベル・ロックの利用

- 不要な解析の排除

パフォーマンスを低下させる原因

パフォーマンスを低下させる原因の1つは、Oracleの通信オーバーヘッドが高いことです。Oracleは一度にSQL文を1つずつ処理する必要があります。つまり、各SQL文がOracleをコールするので、オーバーヘッドが増加します。ネットワーク化された環境下では、ネットワークを介してSQL文を送信する必要があるため、ネットワークの通信量が増加することになります。ネットワークの通信量が多いと、アプリケーションの処理速度は著しく低下します。

パフォーマンスを低下させるもう1つの原因は、非効率的なSQL文です。SQLは柔軟性があるため、2 つの異なる文から同一の結果を得ることもできます。1つの文を使用すると、効率が悪くなる場合もあります。たとえば、次の2つのSELECT文は同じ行(少なくとも従業員が1人いる部門ごとの名称および番号)を戻します。

EXEC SQL SELECT DNAME, DEPTNO
FROM DEPT
WHERE DEPTNO IN (SELECT DEPTNO FROM EMP)
END-EXEC.

次の文と比較してください。

EXEC SQL SELECT DNAME, DEPTNO
FROM DEPT
WHERE EXISTS
(SELECT DEPTNO FROM EMP WHERE DEPT.DEPTNO = EMP.DEPTNO)
END-EXEC.

最初の文はDEPT表内のすべての部門番号を探してEMP表全体をスキャンするため、処理に時間がかかります。EMP表内のDEPTNO列に索引を付けていても、この副問合せにはDEPTNOを指定するWHERE句がないので、索引は使用されません。

パフォーマンスを低下させるもう1つの原因は、不要な解析およびバインドです。SQL文を実行する前にOracleがこのSQL文を解析しバインドする必要があることに注意してください。解析とは、SQL文を調べて、これが構文規則に従って正しいデータベース・オブジェクトを参照していることを確認する作業です。バインドとは、SQL文内のホスト変数をOracleがその値に対して読取りまたは書込みができるようにそれぞれのアドレスに対応付ける作業です。

大部分のアプリケーションにおいて、カーソルの管理を十分に行っているとはいえません。このため不要な解析またはバインドが発生し、結果的に処理のオーバーヘッドが著しく増加します。

パフォーマンスの向上

プリコンパイルしたプログラムのパフォーマンスがよくない場合でも、オーバーヘッドを減少させる方法はあります。

ネットワーク化された環境下では、次の方法で、Oracleの通信オーバーヘッドを大幅に削減できます。

- ホスト表の使用

- 埋込みPL/SQLの使用

次の方法で、処理のオーバーヘッドを場合によっては大幅に削減できます。

- SQL文の最適化

- SQL文のキャッシング

- 索引の使用

- 行レベル・ロックの利用

- 不要な解析の排除

- 不要な再解析の回避

次の項目では、オーバーヘッドを削減するための方法を検討します。

ホスト表の使用方法

ホスト表を使用すると、単一のSQL文でデータの集合全体を操作できるため、パフォーマンスが向上します。たとえば、300人の従業員の給与をEMP表に挿入する場合を考えてみます。表を使用しないと、プログラムでは従業員ごとに1回ずつ、合計300回INSERTを実行する必要があります。配列を使用すると、必要なINSERTは1回のみになります。次の文を考えてみましょう。

EXEC SQL INSERT INTO EMP (SAL) VALUES (:SALARY) END-EXEC.

SALARYが通常のホスト変数の場合は、OracleはINSERT文を1回実行し、EMP表に1行を挿入します。この行のSAL列にはSALARYの値が格納されます。この方法で300行を挿入するには、このINSERT文を300回実行する必要があります。

これに対して、SALARYがサイズ300のホスト表の場合は、Oracleは300行全部を一度にEMP表に挿入します。各行のSAL列にはSALARY表の要素の値が格納されます。

詳細は、第7章「ホスト表」を参照してください。

PL/SQLおよびJavaの使用

図C-1に示すように、データベース処理が中心のアプリケーションの場合は、制御構造を使用して複数のSQL文を1つのPL/SQLブロックにまとめ、そのブロック全体をOracleに送信できます。これにより、使用しているアプリケーションとデータベースとの通信量を大幅に削減できます。

また、PL/SQLおよびJavaサブプログラムを使用してアプリケーションからデータベースへのコールを少なくすることもできます。たとえば、10個のSQL文を個々に実行するには、10回のコールが必要ですが、10個のSQL文を含む1つのサブプログラムを実行する場合、コールは1回で済みます。

無名ブロックとは異なり、PL/SQLおよびJavaサブプログラムは別々にコンパイルし、データベースに格納できます。コールされたPL/SQLサブプログラムは、ただちにPL/SQLエンジンに渡されます。さらに、複数のユーザーが1つのサブプログラムを実行する場合でも、メモリーにロードするコピーは1つで済みます。

図C-1 PL/SQLによるパフォーマンスの向上

SQL文の最適化

オプティマイザにより、すべてのSQL文について実行計画(その文を実行するためにOracleが行う一連の手順)が生成されます。これらの手順は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』に記載されているルールによって決まります。これらのルールに従うと、最適なSQL文を作成できます。

オプティマイザ・ヒント

オプティマイザにより、すべてのSQL文について実行計画(その文を実行するためにOracleが行う一連の手順)が生成されます。場合によっては、SQL文を最適化する方法を提示することもできます。このようにして示す内容はヒントと呼ばれ、これによりオプティマイザによる決定に運用側から影響を与えることができます。

ヒントはディレクティブではなく、オプティマイザによるジョブの実行を助けるだけです。一部のヒントはSQL文を最適化するために使用される情報の範囲を制限し、他のヒントは全体的な戦略を提案します。ヒントを使用して、次の事項を指定できます。

- SQL文の最適化アプローチ

- 参照されているそれぞれの表へのアクセス・パス

- 結合のための結合順序

- 表を結合する方法

ヒントの渡し方

ヒントをオプティマイザに渡すには、SELECT文、UPDATE文またはDELETE文の動詞の直後にC言語形式のコメントの中に入れます。ルール重視の最適化またはコスト重視の最適化のどちらかを選択できます。コスト重視の最適化では、ヒントはスループットの最大化または応答時間に寄与します。次の例では、ALL_ROWSヒントによって問合せのスループットが最大になります。

EXEC SQL SELECT /*+ ALL_ROWS (cost-based) */ EMPNO, ENAME, SAL
INTO :EMP-NUMBER, :EMP-NAME, :SALARY
FROM EMP
WHERE DEPTNO = :DEPT-NUMBER
END-EXEC.

プラス記号(+)はコメント先頭の直後に置く必要があり、コメントが1つ以上のヒントを含むことを示します。コメントにはヒントだけでなく注釈も含まれることがあることに注意してください。

オプティマイザ・ヒントの詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

トレース機能

SQLトレース機能およびEXPLAIN PLAN文を使用すると、アプリケーションの処理速度を低下させるおそれのあるSQL文を特定できます。トレース機能で、Oracleで実行するすべてのSQL文に対する統計表示を生成します。この統計表示で、最も処理時間のかかる文がどれか判断できます。このため、それらの文の処理効率のチューニングに専念できます。

EXPLAIN PLAN文はアプリケーション内の各SQL文に対する実行計画を示します。実行計画を使用すると、非効率的なSQL文を特定できます。

関連項目: トレース・ツールの使用方法および出力の分析方法は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

SQL文のキャッシング

文キャッシングを使用すると、プリコンパイラ・アプリケーションのパフォーマンスが向上します。動的SQL文を使用するすべてのプログラムは、文の再解析にカーソルを使用する必要があるため、文キャッシングによってパフォーマンスが向上します。この新機能によって、全体的に実行時間が減少します。

stmt_cacheオプションを設定すると、アプリケーションでそれぞれの動的SQL文の予測数を保持できます。stmt_cacheサイズは、新しいプリコンパイラ・コマンドライン・オプションを使用して設定できます。stmt_cacheの最適な値は、入力プログラムの動作に依存するため設定できません。

パフォーマンスは、(文キャッシングを使用した場合と使用しない場合の)実行時間の変化によって測定できます。

索引の使用

索引は、ROWIDを使用して、表の列のそれぞれの値をその値が入っている行に対応付けます。索引はCREATE INDEX文で作成します。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

表の15%未満の行しか戻さない問合せでは、索引を使用することによりパフォーマンスが向上します。表の15%以上の行を戻す問合せは、フル・スキャンによる方法、つまり、すべての行を順番に読み込む方法の方が速く処理されます。WHERE句内で索引の付いた列を指定する問合せは、その索引を使用します。どの列に索引を付けるかを選択するためのガイドラインは、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。

行レベル・ロックの利用

デフォルトでは、Oracleは表レベルではなく行レベルでデータをロックします。行レベルでロックすると、複数のユーザーが同一の表の別の行に同時にアクセスできます。その結果、パフォーマンスが大幅に向上します。

表レベルでのロックも指定できますが、これはトランザクション処理オプションの効果を低下させます。表ロックの詳細は、「LOCK TABLE文の使用方法」を参照してください。

オンラインのトランザクション処理を実行するアプリケーションには、行レベル・ロックが最も有効です。アプリケーションで表レベル・ロックを指定している場合は、行レベル・ロックを利用できるように変更してください。通常、明示的な表レベル・ロックは使用しないようにします。

不要な解析の排除

不要な解析を排除するには、カーソルを正しく操作すること、および次に示すカーソル管理オプションを選択して使用することが必要です。

- MAXOPENCURSORS

- HOLD_CURSOR

- RELEASE_CURSOR

これらのオプションは、暗黙的なカーソルと明示カーソル、カーソル・キャッシュおよびプライベートSQL領域に影響します。

注意: カーソル・キャッシュの統計情報は、ORACAを使用して取得できます。「Oracle通信領域の使用」を参照してください。

明示カーソルの操作

カーソルには暗黙カーソルおよび明示カーソルの2種類があることに注意してください(「エラーおよび警告」を参照してください)。Oracleはデータ定義文およびDML文のすべてを暗黙的にカーソルを宣言します。ただし、複数の行を戻す問合せでは、明示的にカーソルを宣言し、1つのホスト表の中に選択するのではなく一括でフェッチする必要があります。DECLARE CURSOR文を使用すると、明示カーソルを宣言できます。明示カーソルのオープンとクローズの方法によって、パフォーマンスに影響があります。

アクティブ・セットの再評価が必要なときは、そのカーソルを再度オープンするだけでかまいません。OPEN文では、任意の新しいホスト変数の値が使用されます。最初にカーソルをクローズせずにオープンのままにしておくと、処理時間を節約できます。

カーソルのOPENによって取得したリソース(メモリーおよびロック)を解放するときにのみ、そのカーソルをCLOSEします。たとえば、プログラムでは終了前にすべてのカーソルをクローズする必要があります。

注意: パフォーマンスをチューニングしやすいように、プリコンパイラではすでにオープンされているカーソルを再オープンできます。ただし、これはANSI/ISOの埋込みSQL規格に対するOracle拡張機能です。したがって、MODE=ANSIのときは、カーソルを再オープンする前にクローズする必要があります。

カーソルの制御

一般的に、明示的に宣言されたカーソルの制御には次のような3つの要素が影響します。

- DECLARE、OPEN、FETCHおよびCLOSE文の使用。

- PREPARE、DECLARE、OPEN、FETCHおよびCLOSE文の使用

- MODE=ANSIの場合の、COMMITによるカーソルのクローズ

最初の方法を使用する場合は、不要な解析に注意する必要があります。OPEN文は、カーソルをクローズしたか、まだオープンしていないために、解析された文を使用できないときにかぎり解析を実行します。プログラムはカーソルを宣言し、ホスト変数の値が変わるたびにこれを再オープンし、このSQL文が必要なくなったときにのみこれをクローズする必要があります。

動的SQLの方法3および4で使用されている2番目の方法を使用する場合は、PREPAREで解析が実行され、解析された文はCLOSEを実行するまで使用できます。プログラムはSQL文を用意してカーソルを宣言し、ホスト変数の値が変わるたびにこれを再オープンし、SQL文に変更があったときはSQL文を再度準備してカーソルを再オープンし、このSQL文が必要なくなったときにのみこれをクローズする必要があります。

OPEN文およびCLOSE文をループの中に配置するのはできるだけ避けてください。SQL文の不要な再解析の原因になります。次の例では、OPEN文とCLOSE文がどちらも外側のループの中にあります。MODE=ANSIの場合、示されているようにCLOSE文を配置する必要があります。ANSIでは、カーソルをクローズしてから再オープンする必要があるためです。

EXEC SQL DECLARE emp_cursor CURSOR FOR
SELECT ENAME, SAL FROM EMP
WHERE SAL >  :SALARY
AND SAL <= :SALARY + 1000
END-EXEC.
MOVE 0 TO SALARY.
TOP.
EXEC SQL OPEN emp_cursor END-EXEC.
LOOP.
EXEC SQL FETCH emp_cursor INTO ....
...
IF SQLCODE = 0
GO TO LOOP
ELSE
ADD 1000 TO SALARY
END-IF.
EXEC SQL CLOSE emp_cursor END-EXEC.
IF SALARY < 5000
GO TO TOP.

MODE=ORACLEでCLOSE文を外側のループの外に指定すると、OPEN文が繰り返されるたびに再解析されるのを回避できます。

TOP.
EXEC SQL OPEN emp_cursor END-EXEC.
LOOP.
EXEC SQL FETCH emp_cursor INTO ....
...
IF SQLCODE = 0
GO TO LOOP
ELSE
ADD 1000 TO SALARY
END-IF.
IF SALARY < 5000
GO TO TOP.
EXEC SQL CLOSE emp_cursor END-EXEC.

カーソル管理オプションの使用

SQL文の解析は、構成を変更しないかぎり一度のみで十分です。たとえば、選択リストまたはWHERE句に列を追加して問合せの構成を変更するとします。HOLD_CURSOR、RELEASE_CURSORおよびMAXOPENCURSORSオプションによって、SQL文の解析および再解析をOracleがどのように管理するかを制御できます。明示カーソルを宣言すると、解析を最大限に制御できます。

プライベートSQL領域およびカーソル・キャッシュ

どの文を実行しても、その文に対応しているカーソルがカーソル・キャッシュ内のエントリにリンクされます。カーソル・キャッシュとはカーソル管理のために使用されて連続的に更新されるメモリー領域です。カーソル・キャッシュ・エントリは、次々に1つのプライベートSQL領域にリンクされます。

プライベートSQL領域とは、Oracleが実行時に動的に作成する作業領域であり、この領域には解析されたSQL文、ホスト変数のアドレスおよびその文の処理に必要なその他の情報が保存されます。動的方法3を使用すると、SQL文のネーミング、プライベートSQL領域に保存されている情報へのアクセス、およびある程度の処理の制御を行うことができます。

図C-2は、プログラムでINSERTおよびDELETEが実行された後のカーソル・キャッシュを表しています。

図C-2 カーソル・キャッシュでリンクされたカーソル

リソースの使用

ユーザー・セッションごとのオープン・カーソルの最大数は、初期化パラメータOPEN_CURSORSによって設定します。

MAXOPENCURSORSは、カーソル・キャッシュの初期サイズを指定します。新しいカーソルが必要で、空きのキャッシュ・エントリがない場合、Oracleはエントリを再利用しようとします。再利用の可能性はHOLD_CURSORとRELEASE_CURSORの値によって決まり、また明示カーソルの場合には、カーソル自体の状態によって決まります。

プログラム実行中にキャッシュする必要がある文の数よりMAXOPENCURSORSの値が少ない場合は、MAXOPENCURSORSキャッシュ・エントリがなくなると、Oracleは再利用できるカーソル・キャッシュ・エントリを探します。たとえば、INSERT文のキャッシュ・エントリE(1)が再利用可能とマークされていて、キャッシュ・エントリの数がすでにMAXOPENCURSORSに達しているとします。プログラムが新しい文を実行する場合、キャッシュ・エントリE(1)とそのプライベートSQL領域は新しい文に再度割り当てられることがあります。INSERT文を再実行するには、Oracleはそれをもう一度解析し、別のキャッシュ・エントリを再度割り当てる必要があります。

再利用できるキャッシュ・エントリが見つからない場合、Oracleは追加のキャッシュ・エントリを割り当てます。たとえば、MAXOPENCURSORS=8で、8エントリすべてがアクティブな場合、9番目のエントリが作成されます。Oracleは、空きメモリーがなくなるかOPEN_CURSORSで設定された限界に達するまで、必要に応じてキャッシュ・エントリの割当てを続行します。この動的割当ては、処理オーバーヘッドを増大させます。

したがって、HOLD_CURSOR=NO (デフォルト)を指定してMAXOPENCURSORSの値を小さく設定すると、メモリーの節約にはなりますが、新しいキャッシュ・エントリの動的割当ておよび割当て解除のコストが高くなる場合があります。MAXOPENCURSORSの値を大きく設定すると、実行は確実に速くなりますが、より大きなメモリーを使用することになります。

実行回数の少ない場合

実行回数の少ないSQL文とそのプライベートSQL領域間のリンクは、一時的なものにした方がよい場合もあります。

HOLD_CURSOR=NO (デフォルト値)と指定した場合は、OracleがそのSQL文を実行してカーソルがクローズされた後、プリコンパイラはこのカーソルとカーソル・キャッシュ間のリンクに再利用可能のマークを付けます。このリンクは、それが示すカーソル・キャッシュ・エントリが別のSQL文に必要になると、すぐに再利用されます。これにより、プライベートSQL領域に割り当てられたメモリーが解放され、解析ロックが解除されます。ただし、PREPAREしたカーソルは実行状態のままである必要があるので、HOLD_CURSOR=NOと指定した場合でもそのリンクは維持されます。

RELEASE_CURSOR=YESと指定した場合は、OracleがそのSQL文を実行してカーソルがクローズされた後、プライベートSQL領域が自動的に解放され、解析した文はなくなります。これは、メモリーを節約する場合などに必要になる可能性があります。

RELEASE_CURSOR=YESを指定した場合は、プライベートSQL領域とキャッシュ・エントリ間のリンクはただちに削除され、このプライベートSQL領域は解放されます。HOLD_CURSOR=YESを指定している場合でも、OracleではSQL文を実行する前にプライベートSQL領域のためにメモリーを再度割り当て、このSQL文を再解析する必要があります。したがって、RELEASE_CURSOR=YESを指定すると、HOLD_CURSOR=YESはオーバーライドされます。

実行回数の多い場合

プライベートSQL領域にはSQL文の実行に必要なすべての情報が格納されるため、頻繁に実行されるSQL文では、そのプライベートSQL領域とのリンクを維持する必要があります。この情報へのアクセスを上手に管理すると、後続の文の実行速度をさらに向上させることができます。

HOLD_CURSOR=YESの場合、OracleがSQL文を実行した後にカーソルとカーソル・キャッシュのリンクが維持されます。したがって、解析された文および割り当てられたメモリーが、利用可能なまま維持されます。これは、不要な再解析を避けるために、アクティブな状態にしておくSQL文で有効です。

共有SQL領域への影響

Oracleでは、解析されたSQL文およびPL/SQLの表現を共有SQLキャッシュにキャッシュします。これらの表現は、他の文をキャッシュするために領域が必要になってエージ・アウトするまで保持されます。詳細は『Oracle Database概要』を参照してください。この面でのOracleサーバーの動作は、プリコンパイラのカーソル管理設定の影響を受けないため、次のような効果をもたらします。

- RELEASE_CURSOR=YESを設定して文を再実行すると、要求がサーバーに送られて解析されますが、文はまだキャッシュに格納されているので全解析を行う必要はありません。

- HOLD_CURSOR=YESを使用すると、文で参照されるオブジェクトのロックは保持されません。したがって、文のオブジェクトの1つが再定義されると、キャッシュされた文が無効になり、サーバーは自動的に文を再解析します。これは予想しない結果をもたらすことがあります。

- ただし、RELEASE_CURSOR=YESを指定した場合は、OracleはSQL文およびPL/SQLブロックの解析した表現を共有SQLキャッシュに入れておくため、これ以上再解析で処理する必要がないこともあります。カーソルをクローズしても、解析された表現はキャッシュの内容が書き換えられるまで効力を持ちます。

埋込みPL/SQLに関する考慮事項

カーソルを管理するために、埋込みPL/SQLブロックはSQL文と同様に扱われます。埋込みPL/SQLブロックが実行されると、親カーソルがPL/SQLブロック全体に対応付けられ、埋込みPL/SQLブロック用にキャッシュ・エントリとPGAのプライベートSQL領域の間にリンクが作成されます。埋込みブロック内の各SQL文にも、PGAのプライベートSQL領域が必要なことに注意してください。これらのSQL文は、PL/SQLが管理する子カーソルを使用します。子カーソルの性質は、対応付けられた親カーソルによって決まります。つまり、子カーソルが使用するプライベートSQL領域は、親カーソルのプライベートSQL領域が解放された後解放されます。

注意:

デフォルトのHOLD_CURSOR=YESおよびRELEASE_CURSOR=NOを使用した場合、Oracleの旧バージョンでSQL文を実行すると、解析された表現は実行後も使用可能です。これと同じ条件でOracleでSQL文を実行すると、解析された表現は、共有SQLキャッシュがエージ・アウトされるまで使用可能です。通常、これが問題となることはありませんが、SQL文が再解析される前に参照されたオブジェクトの定義が変更されると、予期しない結果をもたらす場合があります。

パラメータの相互作用

表C-1は、HOLD_CURSORとRELEASE_CURSORの相互関係を示しています。HOLD_CURSOR=NOを指定すると、RELEASE_CURSOR=NOはオーバーライドされ、RELEASE_CURSOR=YESを指定すると、HOLD_CURSOR=YESがオーバーライドされることに注意してください。

表C-1 HOLD_CURSORおよびRELEASE _CURSORの相互関係

HOLD_CURSOR

RELEASE_CURSOR

リンク

NO

NO

再利用可能としてマーク

YES

NO

維持

NO

YES

ただちに削除

YES

YES

ただちに削除

不要な再解析の回避

埋込みSQL文をループで実行した場合、解析は1回のみ行われます。ただし、SQL文の実行フェーズでエラーが発生した結果、文を再解析した場合は次の例外が発生することがあります。

- ORA-1403 (見つからない)

- ORA-1405 (切捨て)

- ORA-1406 (NULL値)

これらのエラーを修正すると、不要な再解析を避けることができます。

D 構文および意味検査

埋込みSQL文およびPL/SQLブロックの構文および意味を検査すると、Oracleプリコンパイラはコーディングの誤りをすみやかに発見し修正できるよう支援します。この付録では、プリコンパイラ・オプションのSQLCHECKを使用して検査の種類および範囲を制御する方法を説明します。

内容は次のとおりです。

- 構文および意味検査の基礎

- 検査の種類および範囲の制御

- SQLCHECK=SEMANTICSの指定

構文および意味検査の基礎

構文規則は、言語要素を並べて正しい文を作成する基準を示します。つまり、構文検査はキーワード、オブジェクト名、演算子、デリミタなどがSQL文に正しく配置されていることを検証します。PL/SQLブロックからコールされたプロシージャおよび関数にも適用されます。たとえば、次の埋込みSQL文には構文上のエラーがあります。

* --  misspelled keyword WHERE
EXEC SQL DELETE FROM EMP WERE DEPTNO = 20 END-EXEC.
* --  missing parentheses around column names COMM and SAL
EXEC SQL
INSERT INTO EMP COMM, SAL VALUES (NULL, 1500)
END-EXEC.

意味上の規則は、有効な外部参照を行う方法を示しています。つまり、意味検査では、データベース・オブジェクトおよびホスト変数への参照が正しいこととホスト変数のデータ型が正しいことを検証します。たとえば、次の埋込みSQL文には意味上のエラーがあります。

* --  nonexistent table, EMPP
EXEC SQL DELETE FROM EMPP WHERE DEPTNO = 20 END-EXEC.
* --  undeclared host variable, EMP-NAME
EXEC SQL SELECT * FROM EMP WHERE ENAME = :EMP-NAME END-EXEC.

SQL構文および意味の規則の定義は、『Oracle Database SQL言語リファレンス』を参照してください。

検査の種類および範囲の制御

コマンドラインでプリコンパイラ・オプションのSQLCHECKを指定すると、検査の種類および範囲を制御します。SQLCHECKでは、検査の種類は、構文、または構文および意味の2種類があります。検査の範囲には、DML文とPL/SQLブロックを含めることができます。ただし、動的SQL文は実行時まで完全に定義されないため、SQLCHECKで動的SQL文はチェックできません。

SQLCHECKについて次の値を指定できます。

- SEMANTICS | FULL

- SYNTAX | LIMITED

値SEMANTICSとFULLは等価で、SYNTAXとLIMITEDも等価です。デフォルト値はSYNTAXです。

SQLCHECK=SEMANTICSの指定

SQLCHECK=SEMANTICSの場合、プリコンパイラは次の内容について構文および意味の検査を行います。

- INSERT文やUPDATE文などのDML文。

- PL/SQLブロック。

ただし、AT db_name句を使用するDML文については、意味検査のみが行われます。

プリコンパイラは、意味検査に必要な情報を、埋め込まれたDECLARE TABLE文から取得します。また、オプションUSERIDが指定されている場合は、データベースに接続してデータ・ディクショナリにアクセスするとこの情報を取得します。

データベースに接続し、データ・ディクショナリで表情報が検出されない場合は、DECLARE TABLE文を使用し、不足している情報を提供する必要があります。DECLARE TABLE文とデータ・ディクショナリの定義が矛盾する場合は、DECLARE TABLEの定義が使用されます。

DML文を検査する場合、プリコンパイラは『Oracle Database SQL言語リファレンス』に掲載されているOracleの構文規則を使用しますが、意味検査にはさらに厳密な規則を使用します。その結果、SQLCHECK=SEMANTICSのときは、Oracleの以前のバージョン用に作成した既存のアプリケーションを正常にプリコンパイルできない場合があります。

新しいプログラムをプリコンパイルするときは、SQLCHECK=SEMANTICSを指定してください。ホスト・プログラム内にPL/SQLブロックを埋め込むときは、必ずSQLCHECK=SEMANTICSを指定してください。

意味検査の使用許可

SQLCHECK=SEMANTICSを指定すると、プリコンパイラは意味検査に必要な情報を、次の方法のどれかで入手できます。

- Oracleに接続し、そのデータ・ディクショナリにアクセス

- 埋込みDECLARE TABLE文を使用

Oracleへの接続

意味検査を行うために、プリコンパイラはホスト・プログラム内で参照される表およびビューの定義が保存されているデータベースに接続できます。接続した後、プリコンパイラはデータ・ディクショナリにアクセスして必要な情報を探します。データ・ディクショナリには、表および列の名前、表および列の制約、列の長さ、列のデータ型などが格納されています。

必要な情報の一部をデータ・ディクショナリ内で検出できない場合(たとえば、プログラムが未作成の表を参照するときなど)は、DECLARE TABLE文を使用して足りない情報を指定する必要があります。

データベースに接続するには、次の構文を使用して、コマンドラインでUSERIDオプションを指定します。

USERID=username/password

usernameおよびpasswordは有効なOracleユーザーIDを構成します。パスワードを省略すると、パスワードの入力が求められます。仮に、ユーザー名とパスワードのかわりに、次のように指定したとします。

USERID=/

プリコンパイラは、自動的に次のユーザーIDを使用してデータベースに接続しようとします。

<prefix><username>

prefixは初期化パラメータOS_AUTHENT_PREFIXの値(デフォルト値はOPS$)、usernameはオペレーティング・システムのユーザー名またはタスク名です。

(データベースが使用不能などの理由で)接続に失敗すると、プリコンパイラは処理を停止し、エラー・メッセージを発行します。オプションUSERIDが指定されないと、プリコンパイラは埋込みDECLARE TABLE文から必要な情報を取得することになります。

DECLARE TABLEの使用

プログラムで無名PL/SQLブロックからストアド・プロシージャまたは関数をコールしないかぎり、プリコンパイラはデータベースに接続しなくても意味検査を実行できます。プリコンパイラは、意味検査に必要な表やビューに関する情報を、埋込みDECLARE TABLEディレクティブから取得する必要があります。つまり、DML文またはPL/SQLブロック内で参照する表をすべてDECLARE TABLE文内で定義する必要があります。

DECLARE TABLE文の構文は次のとおりです。

EXEC SQL DECLARE table_name TABLE
(col_name col_datatype [DEFAULT expr] [NULL|NOT NULL], ...)
END-EXEC.

exprは、CREATE TABLE文でデフォルトの列値として使用できる任意の式です。col_datatypeは、Oracleの列宣言です。整数のみ使用することができ、式は使用できません。「DECLARE TABLE(Oracle埋込みSQLディレクティブ)」を参照してください。

DECLARE TABLEを使用して既存のデータベースの表を定義した場合、プリコンパイラはその定義に従います。このときデータ・ディクショナリの定義は無視されます。

E 埋込みSQL文およびプリコンパイラ・ディレクティブ

この付録では、Oracleの埋込みSQL文およびディレクティブについて説明します。これらの文およびディレクティブをソース・コードで使用するときは、キーワードEXEC SQLを前に付けます。

注意: この付録では、非埋込みSQLと構文が異なる文のみ説明します。非埋込みSQL文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

この付録の構成は、次のとおりです。

- プリコンパイラ・ディレクティブおよび埋込みSQL文の概要

- 文記述子

- 構文図の読み方

- ALLOCATE (実行可能埋込みSQL拡張機能)

- ALLOCATE DESCRIPTOR (実行可能埋込みSQL)

- CALL (実行可能埋込みSQL)

- CLOSE (実行可能埋込みSQL)

- COMMIT (実行可能埋込みSQL)

- CONNECT (実行可能埋込みSQL拡張機能)

- CONTEXT ALLOCATE (実行可能埋込みSQL拡張機能)

- CONTEXT FREE (実行可能埋込みSQL拡張機能)

- CONTEXT USE (Oracle埋込みSQLディレクティブ)

- DECLARE CURSOR (埋込みSQLディレクティブ)

- DECLARE DATABASE (Oracle埋込みSQLディレクティブ)

- DECLARE STATEMENT (埋込みSQLディレクティブ)

- DECLARE TABLE (Oracle埋込みSQLディレクティブ)

- DELETE (実行可能埋込みSQL)

- DESCRIBE (実行可能埋込みSQL)

- DESCRIBE DESCRIPTOR (実行可能埋込みSQL)

- ENABLE THREADS (実行可能埋込みSQL拡張機能)

- EXECUTE ...END-EXEC (実行可能埋込みSQL拡張機能)

- EXECUTE (実行可能埋込みSQL)

- EXECUTE DESCRIPTOR (実行可能埋込みSQL)

- EXECUTE IMMEDIATE (実行可能埋込みSQL)

- FETCH (実行可能埋込みSQL)

- FETCH DESCRIPTOR (実行可能埋込みSQL)

- FREE (実行可能埋込みSQL拡張機能)

- GET DESCRIPTOR (実行可能埋込みSQL)

- INSERT (実行可能埋込みSQL)

- LOB APPEND (実行可能埋込みSQL拡張機能)

- LOB ASSIGN (実行可能埋込みSQL拡張機能)

- LOB CLOSE (実行可能埋込みSQL拡張機能)

- LOB COPY (実行可能埋込みSQL拡張機能)

- LOB CREATE TEMPORARY (実行可能埋込みSQL拡張機能)

- LOB DESCRIBE (実行可能埋込みSQL拡張機能)

- LOB DISABLE BUFFERING (実行可能埋込みSQL拡張機能)

- LOB ENABLE BUFFERING (実行可能埋込みSQL拡張機能)

- LOB ERASE (実行可能埋込みSQL拡張機能)

- LOB FILE CLOSE ALL (実行可能埋込みSQL拡張機能)

- LOB FILE SET (実行可能埋込みSQL拡張機能)

- LOB FLUSH BUFFER (実行可能埋込みSQL拡張機能)

- LOB FREE TEMPORARY (実行可能埋込みSQL拡張機能)

- LOB LOAD (実行可能埋込みSQL拡張機能)

- LOB OPEN (実行可能埋込みSQL拡張機能)

- LOB READ (実行可能埋込みSQL拡張機能)

- LOB TRIM (実行可能埋込みSQL拡張機能)

- LOB WRITE (実行可能埋込みSQL拡張機能)

- OPEN (実行可能埋込みSQL)

- OPEN DESCRIPTOR (実行可能埋込みSQL)

- PREPARE (実行可能埋込みSQL)

- ROLLBACK (実行可能埋込みSQL)

- SAVEPOINT (実行可能埋込みSQL)

- SET DESCRIPTOR (実行可能埋込みSQL)

- SELECT (実行可能埋込みSQL)

- UPDATE (実行可能埋込みSQL)

- VAR (Oracle埋込みSQLディレクティブ)

- WHENEVER (埋込みSQLディレクティブ)

プリコンパイラ・ディレクティブおよび埋込みSQL文の概要

埋込みSQL文は、DDL、DMLおよびトランザクション制御文を手続き型言語プログラムに挿入します。Oracleプリコンパイラでは、埋込みSQLをサポートしています。表E-2は、埋込みSQL文およびディレクティブの機能の概要です。

表E-2の「ソース/型」列は、ソース/型の形式で、次のように記載されています。

表E-1 「ソース/型」列の意味

SQL文

ディレクティブ

ソース

標準SQL (S)またはOracleの拡張機能(O)。

型

実行文(E)またはディレクティブ(D)。

表E-2 プリコンパイラ・ディレクティブおよび埋込みSQL文および句

EXEC SQL文

ソース/型

用途

ALLOCATE

O/E

カーソル変数、LOBロケータまたはROWIDにメモリーを割り当てます。

ALLOCATE DESCRIPTOR

S/E

記述子をANSI動的SQLに割り当てます。

CALL

S/E

ストアド・プロシージャをコールします。

CLOSE

S/E

カーソルを使用禁止にします。

COMMIT

S/E

データベースの変更をすべて確定します。

CONNECT

O/E

データベースのインスタンスにログインします。

CONTEXT ALLOCATE

O/E

メモリーをSQLLIBランタイム・コンテキストに割り当てます。

CONTEXT FREE

O/E

メモリーをSQLLIBランタイム・コンテキストから解放します。

CONTEXT USE

O/E

SQLLIBランタイム・コンテキストを指定します。

DEALLOCATE DESCRIPTOR

S/E

記述子領域の割当てを解除し、メモリーを解放します。

DECLARE CURSOR

S/D

問合せに対応付けてカーソルを宣言します。

DECLARE DATABASE

O/D

後続の埋込みSQL文でアクセスされるデフォルト以外のデータベースの識別子を宣言します。

DECLARE STATEMENT

S/D

SQL文にSQL変数名を割り当てます。

DECLARE TABLE

O/D

Oracleプリコンパイラで埋込みSQL文の意味検査に使用される表構造を宣言します。

DELETE

S/E

表またはビューの実表から行を削除します。

DESCRIBE

S/E

記述子(ホスト変数の説明を保持している構造体)を初期化します。

DESCRIBE DESCRIPTOR

S/E

ANSI SQL文の情報を取得し、記述子に格納します。

ENABLE THREADS

O/E

複数のスレッドをサポートするプロセスを初期化します。

EXECUTE...END-EXEC

O/E

無名PL/SQLブロックを実行します。

EXECUTE

S/E

準備済の動的SQL文を実行します。

EXECUTE DESCRIPTOR

S/E

ANSI動的SQLを使用して準備済の文を実行します。

EXECUTE IMMEDIATE

S/E

ホスト変数を持たないSQL文を準備して実行します。

FETCH

S/E

問合せで選択した行を取り出します。

FETCH DESCRIPTOR

S/E

ANSI動的SQLを使用する問合せにより、選択された行を取り出します。

FREE

S/E

カーソル変数、LOBロケータまたはROWIDが使用するメモリーを解放します。

GET DESCRIPTOR

S/E

ANSI SQLの記述子領域の情報をホスト変数に移動します。

INSERT

S/E

表またはビューの実表に行を追加します。

LOB APPEND

O/E

LOBを別のLOBの最後に追加します。

LOB ASSIGN

O/E

LOBまたはBFILEロケータを別のロケータに割り当てます。

LOB CLOSE

O/E

オープンされているLOBまたはBFILEをクローズします。

LOB COPY

O/E

LOB値の全部または一部を別のLOBにコピーします。

LOB CREATE TEMPORARY

O/E

一時LOBを作成します。

LOB DESCRIBE

O/E

LOBから属性を取り出します。

LOB DISABLE BUFFERING

O/E

LOBバッファリングを使用禁止にします。

LOB ENABLE BUFFERING

O/E

LOBバッファリングを有効にします。

LOB ERASE

O/E

指定されたオフセットから始まる指定された量のLOBデータを消去します。

LOB FILE CLOSE ALL

O/E

オープンしているBFILEをすべてクローズします。

LOB FILE SET

O/E

BFILEロケータのDIRECTORYおよびFILENAMEを設定します。

LOB FLUSH BUFFER

O/E

LOBのバッファをデータベース・サーバーに書き込みます。

LOB FREE TEMPORARY

O/E

LOBロケータ用に一時領域を解放します。

LOB LOAD

O/E

BFILEの全部または一部を、内部LOBにコピーします。

LOB OPEN

O/E

読取りまたは読取り/書込みアクセスするために、LOBまたはBFILEをオープンします。

LOB READ

O/E

LOBまたはBFILEの一部をバッファに読み込みます。

LOB TRIM

O/E

LOB値を切り捨てます。

LOB WRITE

O/E

バッファの内容をLOBに書き込みます。

OPEN

S/E

カーソルに対応付けられた問合せを実行します。

OPEN DESCRIPTOR

S/E

ANSI動的SQLのカーソルに対応付けられた問合せを実行します。

PREPARE

S/E

動的SQL文を解析します。

ROLLBACK

S/E

カレント・トランザクションを終了し、すべての変更を破棄します。

SAVEPOINT

S/E

後でロールバックする位置をトランザクション内に指定します。

SELECT

S/E

選択した値をホスト変数に割り当てて、1つ以上の表、ビューまたはスナップショットからデータを取り出します。

SET DESCRIPTOR

S/E

ホスト変数からANSI SQL記述子領域に情報を設定します。

UPDATE

S/E

表またはビューの実表の既存の値を変更します。

VAR

O/D

デフォルトのデータ型をオーバーライドして、特定のOracleの外部データ型をホスト変数に割り当てます。

WHENEVER

S/D

エラー状態および警告状態の処置を指定します。

文記述子

ディレクティブおよび文はアルファベット順で示します。各コマンドの説明には、次の項目があります。

ディレクティブ

説明

用途

コマンドの基本的な用途を示します。

前提条件

必要な権限、および文を使用する前に実行する必要のある手順を示します。特記していないかぎり、ほとんどの文では、データベースがユーザーのインスタンスによってオープンされている必要があります。

構文

文のキーワードおよびパラメータの構文図を示します。

キーワードおよびパラメータ

各キーワードおよびパラメータの用途を示します。

使用上の注意

文の使用方法および条件を示します。

前提条件

必要な権限、および文を使用する前に実行する必要のある手順を示します。特記していないかぎり、ほとんどの文では、データベースがユーザーのインスタンスによってオープンされている必要があります。

構文

文のキーワードおよびパラメータの構文図を示します。

構文図の読み方

埋込みSQLの構文は、わかりやすいように構文図を使用して説明します。構文図とは、有効な構文を示す図です。

構文図は、左から右に矢印が指す方向にたどってください。

文のキーワードは、四角形の中に大文字で表記されています。これらの文字は、四角形の中に表示されているとおり正確に入力してください。パラメータは、楕円形の中に小文字で表記されています。パラメータには変数が使用されます。演算子、デリミタおよび終了記号は、円の中に表示されています。

構文図に複数のパスがある場合は、任意のパスを選択できます。

キーワード、演算子またはパラメータの選択肢が複数ある場合は、オプションを縦に並べて示します。次の例では、まず縦方向を選択した後、横方向に進めます。

この図は、次の文がすべて有効であることを示しています。

EXEC SQL WHENEVER NOT FOUND ...
EXEC SQL WHENEVER SQLERROR ...
EXEC SQL WHENEVER SQLWARNING ...

文の終了記号

Pro*COBOL EXEC SQLの構文図はすべて、文がトークンEND-EXECで終了するものと解釈してください。

必須のキーワードおよびパラメータ

必須のキーワードおよびパラメータは、単一または代替の選択肢を縦に並べた状態で示します。必須のキーワードまたはパラメータが1つしかない場合は、メイン・パス、つまり現在たどっている横線上に示します。次の例では、cursorは必須パラメータです。

したがって、EMPCURSORの名前のカーソルがある場合、前述の構文図によると次の文は有効です。

EXEC SQL CLOSE EMPCURSOR END-EXEC.

複数のキーワードまたはパラメータがメイン・パス上に縦に並んでいる場合は、その中のいずれかが必須になります。つまり、キーワードやパラメータを1つ選択する必要がありますが、それはメイン・パス上にあるものでなくてもかまいません。次の例では、4つのアクションのうち1つを選択する必要があります。

オプションのキーワードおよびパラメータ

キーワードおよびパラメータがメイン・パスの上に並べられている場合は、オプションです。次の例では、上方向にたどらずに、メイン・パスを続けることができます。

この図では、oracle2の名前のデータベースが存在する場合、次の文はすべて有効です。

EXEC SQL ROLLBACK END-EXEC.
EXEC SQL ROLLBACK WORK END-EXEC.
EXEC SQL AT ORACLE2 ROLLBACK END-EXEC.

構文ループ

ループは、その中の構文を何回でも繰り返せることを示します。次の例では、column_nameがループの中にあります。このため、列名を1つ選択した後で、繰り返し戻って別の列名を選択できます。

DEBIT、CREDITおよびBALANCEが列名の場合、この図では次の文がすべて有効です。

EXEC SQL SELECT DEBIT INTO ...
EXEC SQL SELECT CREDIT, BALANCE INTO ...
EXEC SQL SELECT DEBIT, CREDIT, BALANCE INTO ...

複数パーツの図

複数パーツの図では、メイン・パスがすべて端から端まで続いていると考えます。次の例は2パーツの図です。

この図は、次の文が有効であることを示しています。

EXEC SQL PREPARE statement_name FROM :host_string END-EXEC.

Oracleオブジェクト名

表および列などのOracle Databaseオブジェクトの名前は、30文字以内であることが必要です。先頭文字は英文字であることが必要ですが、残りの文字には、英文字、数字、ドル記号($)、ポンド記号(#)およびアンダースコア(_)を任意に組み合せて使用できます。

ただし、名前を二重引用符(")で囲むと、有効な文字を任意に組み合せて使用できます。この場合、空白は有効な文字ですが、引用符は無効です。

Oracleの名前は、引用符で囲んだ場合を除いて大/小文字の区別がありません。

ALLOCATE (実行可能埋込みSQL拡張機能)

用途

PL/SQLブロックで参照するカーソル変数、LOBロケータまたはROWIDを割り当てます。

前提条件

SQL-CURSOR型のカーソル変数(第6章「埋込みPL/SQL」を参照)は、カーソル変数のメモリーを割り当てる前に宣言する必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

cursor_variable

SQL_CURSOR型のカーソル変数

host_ptr

ROWIDの場合はSQL-ROWID型、LOBの場合はSQL-BLOB、SQL-CLOBまたはSQL-NCLOB型の変数

使用上の注意

カーソルが静的であるのに対して、カーソル変数は特定の問合せに結び付けられていないため、動的です。カーソル変数は、型の互換性のある任意の問合せに対してオープンできます。

この文の詳細は、『Oracle Database PL/SQL言語リファレンス』および『Oracle Database SQL言語リファレンス』を参照してください。

例

この例では、ALLOCATE文の使用方法を示します。

...
01  EMP-CUR       SQL-CURSOR.
01  EMP-REC.
...
EXEC SQL ALLOCATE :EMP-CUR END-EXEC.
...

関連項目

CLOSE (実行可能埋込みSQL)。

EXECUTE (実行可能埋込みSQL)。

FETCH (実行可能埋込みSQL)。

FREE (実行可能埋込みSQL拡張機能)。

ALLOCATE DESCRIPTOR (実行可能埋込みSQL)

用途

記述子を割り当てるANSI動的SQL文です。

前提条件

なし。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

array_size
integer

処理される行数を格納するホスト変数。
処理される行数。

descriptor_name
descriptor name

処理される行数を格納するホスト変数。
処理される行数。

GLOBAL | LOCAL

LOCAL (デフォルト)はファイルのスコープで、GLOBALはアプリケーションのスコープです。

WITH MAX integer

ホスト変数の最大数。デフォルトは100です。

使用上の注意

DYNAMIC=ANSIプリコンパイラ・オプションを使用してください。この文の使用の詳細は、「ALLOCATE DESCRIPTOR」を参照してください。

例

EXEC SQL
FOR :batch ALLOCATE DESCRIPTOR GLOBAL :binddes WITH MAX 25
END-EXEC.

関連項目

DESCRIBE DESCRIPTOR (実行可能埋込みSQL)。

GET DESCRIPTOR (実行可能埋込みSQL)。

SET DESCRIPTOR (実行可能埋込みSQL)。

CALL (実行可能埋込みSQL)

用途

ストアド・プロシージャをコールします。

前提条件

アクティブなデータベース接続が存在している必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

schema

プロシージャを格納するスキーマ。省略した場合、Oracleはプロシージャが固有のスキーマ内にあるとみなします。

pkg

プロシージャが格納されているパッケージ。

st_proc

コールするストアド・プロシージャ。

db_link :

プロシージャが格納されているリモート・データベースへのデータベース・リンクの、完全または一部の名前。データベース・リンク参照の情報は、『Oracle Database SQL言語リファレンス』を参照してください。

expr

プロシージャのパラメータ式のリスト。

ret_var :

関数からの戻り値を受け取るホスト変数。

ret_ind

ret_var用の標識変数。

使用上の注意

この文の詳細は、「ストアドPL/SQLまたはJavaサブプログラムのコール」を参照してください。

ストアド・プロシージャの詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』(「外部ルーチン」の章)を参照してください。

例

...
05  EMP-NAME      PIC X(10) VARYING.
05  EMP-NUMBER    PIC S9(4) COMP VALUE ZERO.
05  SALARY        PIC S9(5)V99 COMP-3 VALUE ZERO.
...
05  D-EMP-NUMBER  PIC 9(4).
...
ACCEPT D-EMP-NUMBER.
EXEC SQL
CALL mypkge.getsal(:EMP-NUMBER, :D-EMP-NUMBER, :EMP-NAME) INTO :SALARY
END-EXEC.
...

関連項目

なし

CLOSE (実行可能埋込みSQL)

用途

カーソルのオープン時に取得したリソースを解放し、解析ロックを解除して、カーソルを使用禁止にします。

前提条件

カーソルまたはカーソル変数をオープンしている必要があります。またMODE=ANSIであることが必要です。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

cursor

クローズするカーソル。

cursor_variable

クローズするカーソル変数。

使用上の注意

クローズしたカーソルからは行をフェッチできません。カーソルを再オープンするには、そのカーソルがクローズされている必要はありません。HOLD_CURSORおよびRELEASE_CURSORのプリコンパイラ・オプションによって、CLOSE文の結果は異なります。これらのオプションの詳細は、第14章「プリコンパイラ・オプション」を参照してください。

例

この例では、CLOSE文の使用方法を示します。

EXEC SQL CLOSE EMP-CUR END-EXEC.

関連項目

DECLARE CURSOR (埋込みSQLディレクティブ)。

OPEN (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)。

COMMIT (実行可能埋込みSQL)

用途

データベースの変更内容をすべて確定し、オプションですべてのリソースを解放してデータベース・サーバーから切断し、カレント・トランザクションを終了します。

前提条件

カレント・トランザクションをコミットするために必要な権限はありません。

ユーザーがコミットしたインダウトの分散トランザクションを手動でコミットするには、FORCE TRANSACTIONのシステム権限が必要です。他のユーザーがコミットしたインダウトの分散トランザクションを手動でコミットするには、FORCE ANY TRANSACTIONのシステム権限が必要です。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

AT

どのデータベースに対してCOMMIT文を発行するかを指定します。次のいずれかを使用してデータベースを指定します。

db_name

すでにDECLARE DATABASE文で宣言されているデータベース識別子、またはCONNECT文で使用されているデータベース識別子。

host_variable

この句を省略した場合、Oracleはデフォルトのデータベースに対して文を発行します。

WORK

標準SQLへの準拠のためにのみサポートされています。COMMIT文とCOMMIT WORK文は同等です。

COMMENT

カレント・トランザクションに対応付けるコメントを指定します。text'は、50文字以内の引用リテラルで、トランザクションがインダウトになると、Oracleではデータ・ディクショナリ・ビューDBA_2PC_PENDINGに、トランザクションIDとともに格納されます。

RELEASE

リソースをすべて解放し、アプリケーションをOracleサーバーから切断します。

FORCE

インダウトの分散トランザクションを手動でコミットできます。トランザクションは、ローカルまたはグローバル・トランザクションIDを格納する'text'によって識別されます。このようなトランザクションのIDを検索するには、データ・ディクショナリ・ビューDBA_2PC_PENDINGに問合せをします。また、オプションのintegerを使用してトランザクションにシステム変更番号(SCN)を明示的に割り当てることができます。integerを省略した場合、トランザクションはカレントSCNを使用してコミットされます。

使用上の注意

プログラムの最後のトランザクションは、COMMITコマンドまたはROLLBACK文およびRELEASEオプションを使用して、必ず明示的にコミットまたはロールバックしてください。プログラムが異常終了すると、Oracleは自動的に変更をロールバックします。

COMMIT文は、ホスト変数やプログラムの制御の流れには影響しません。この文の詳細は、「COMMIT文の使用」を参照してください。

例

この例では、埋込みSQL COMMIT文の使用方法を示します。

EXEC SQL AT SALESDB COMMIT RELEASE END-EXEC.

関連項目

ROLLBACK (実行可能埋込みSQL)。

SAVEPOINT (実行可能埋込みSQL)。

CONNECT (実行可能埋込みSQL拡張機能)

用途

Oracle Databaseにログインします。

前提条件

指定するデータベースに対してCREATE SESSIONのシステム権限が必要です。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

user
password

ユーザー名およびパスワードを個別に指定します。

user_password

接続文字列username/password[@dbname]を含む1つのホスト変数。
Oracleで、使用しているオペレーティング・システムとの接続を検証するには、「/」をuser_password値として指定します。

AT

接続先のデータベースを指定します。次のいずれかを使用してデータベースを指定します。

db_name

すでにDECLARE DATABASE文で宣言されているデータベース識別子。

host_variable

すでに宣言されているdb_name値のホスト変数。

USING

デフォルト以外のデータベースへの接続に使用するOracle Net Servicesデータベース指定を指定します。この句を省略した場合は、デフォルトのデータベースに接続します。

ALTER AUTHORIZATION

パスワードを次の文字列に変更します。

new_password

新パスワードの文字列です。

IN SYSDBA MODE
IN SYSOPER MODE

SYSDBAまたはSYSOPERシステム権限で接続します。ALTER AUTHORIZATIONが使用されているとき、またはプリコンパイラ・オプションのAUTO_CONNECTがYESに設定されているときは、接続が許可されません。

使用上の注意

プログラムは複数の接続を持つことができますが、デフォルト・データベースには1度しか接続できません。この文の詳細は、「同時ログイン」を参照してください。

例

次の例では、CONNECTの使用方法を示します。

EXEC SQL CONNECT :USERNAME
IDENTIFIED BY :PASSWORD
END-EXEC.

さらにこの文を使用して、useridの値をusernameの値にしたり、SCOTT/TIGERのようにpasswordを「/」で区切ったものを設定できます。

EXEC SQL CONNECT :USERID END-EXEC.

関連項目

COMMIT (実行可能埋込みSQL)。

DECLARE DATABASE (Oracle埋込みSQLディレクティブ)。

ROLLBACK (実行可能埋込みSQL)。

CONTEXT ALLOCATE (実行可能埋込みSQL拡張機能)

用途

EXEC SQL CONTEXT USE文で参照されているSQLLIBランタイム・コンテキストを初期化します。

前提条件

ランタイム・コンテキストは、SQL-CONTEXT型で宣言されている必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

context

メモリーが割り当てられるSQLLIBランタイム・コンテキスト。

使用上の注意

この文の詳細は、「ランタイム・コンテキストの埋込みSQL文およびディレクティブ」を参照してください。

例

この例では、Pro*COBOL埋込みSQLプログラムでCONTEXT ALLOCATE文を使用する方法を示します。

EXEC SQL CONTEXT ALLOCATE :ctx1 END-EXEC.

関連項目

CONTEXT FREE (実行可能埋込みSQL拡張機能)。

CONTEXT USE (Oracle埋込みSQLディレクティブ)。

CONTEXT FREE (実行可能埋込みSQL拡張機能)

用途

ランタイム・コンテキストに関連付けられたすべてのメモリーを解放し、NULLポインタをホスト・プログラム変数に代入します。

前提条件

CONTEXT FREE文を使用してランタイム・コンテキストに割り当てられたメモリーを解放する前に、CONTEXT ALLOCATE文を使用して、指定されているランタイム・コンテキストにメモリーを割り当てる必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

context

メモリーの割当てを解除する、割当て済ランタイム・コンテキスト。

使用上の注意

この文の詳細は、「ランタイム・コンテキストの埋込みSQL文およびディレクティブ」を参照してください。

例

この例では、Pro*COBOL埋込みSQLプログラムでCONTEXT FREE文を使用する方法を示します。

EXEC SQL CONTEXT FREE :ctx1 END-EXEC.

関連項目

CONTEXT ALLOCATE (実行可能埋込みSQL拡張機能)。

CONTEXT USE (Oracle埋込みSQLディレクティブ)。

CONTEXT USE (Oracle埋込みSQLディレクティブ)

用途

後続の実行SQL文の前提条件で指定されたSQLLIBランタイム・コンテキストを使用するように、プリコンパイラに指示します。

前提条件

CONTEXT USEディレクティブによって指定されたランタイム・コンテキストは、事前に宣言されている必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

context

後続の実行SQL文によって使用される、割当て済ランタイム・コンテキストです。たとえば、使用するコンテキストをソース・コードに指定した後(複数のコンテキストを割り当てることができます)、Oracleサーバーに接続し、コンテキストのスコープ内でデータベースを操作できます。

DEFAULT

グローバル・コンテキストが使用されることを示します。

使用上の注意

この文はEXEC SQL INCLUDEやEXEC ORACLE OPTIONなどの宣言文では無効です。この文は、EXEC SQL WHENEVERディレクティブと同様に、指定したソース・ファイル内でこのディレクティブの後に続くすべての実行SQL文に影響し、C言語の標準のスコープ規則には従いません。

この文の詳細は、「ランタイム・コンテキストの埋込みSQL文およびディレクティブ」を参照してください。

例

この例では、Pro*COBOLプログラムでCONTEXT USEディレクティブを使用する方法を示します。

EXEC SQL CONTEXT USE :ctx1 END-EXEC.

関連項目

CONTEXT ALLOCATE (実行可能埋込みSQL拡張機能)。

CONTEXT FREE (実行可能埋込みSQL拡張機能)。

DEALLOCATE DESCRIPTOR (埋込みSQL文)

用途

記述子領域の割当てを解除し、メモリーを解放するANSI動的SQL文です。

前提条件

DEALLOCATE DESCRIPTOR文で指定されている記述子は、ALLOCATE DESCRIPTOR文を使用して事前に割り当てる必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

GLOBAL | LOCAL

LOCAL (デフォルト)はファイルのスコープで、GLOBALはアプリケーションのスコープです。

descriptor_name
'descriptor name'

割り当てられたANSI記述子名を格納するホスト変数。
割り当てられたANSI記述子の名前。

使用上の注意

DYNAMIC=ANSIプリコンパイラ・オプションを使用してください。

この文の詳細は、「DEALLOCATE DESCRIPTOR」を参照してください。

例

EXEC SQL DEALLOCATE DESCRIPTOR GLOBAL 'SELDES'  END-EXEC.

関連項目

ALLOCATE DESCRIPTOR (実行可能埋込みSQL)。

DESCRIBE DESCRIPTOR (実行可能埋込みSQL)。

GET DESCRIPTOR (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)。

SET DESCRIPTOR (実行可能埋込みSQL)。

DECLARE CURSOR (埋込みSQLディレクティブ)

用途

カーソルを宣言するためにカーソルに名前を付け、それをSQL文またはPL/SQLブロックに対応付けます。

前提条件

SQL文またはPL/SQLブロックの識別子を使用してカーソルを対応付けるには、DECLARE STATEMENT文を使用してこの識別子を事前に宣言する必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

AT

カーソルを宣言するデータベースを指定します。次のいずれかを使用してデータベースを指定します。

db_name

DECLARE DATABASE文を使用してすでに宣言されているデータベース識別子。

host_variable

すでに宣言されているdb_name値のホスト変数。
この句を省略した場合、Oracleはデフォルトのデータベースに対してこのカーソルを宣言します。

cursor

宣言するカーソルの名前。

WITH HOLD

カーソルはCOMMITの実行後もオープン状態のままです。UPDATEの場合は、カーソルを宣言しないでください。

SELECT文

カーソルに対応付けるSELECT文。直後の文にINTO句を含めないでください。

statement_name

カーソルに対応付けるSQL文またはPL/SQLブロックを指定します。statement_nameまたはblock_nameは、DECLARE STATEMENT文を使用して事前に宣言する必要があります。

使用上の注意

カーソルは、他の埋込みSQL文で参照する前に、宣言する必要があります。カーソル宣言のスコープはプリコンパイル・ユニット内全体になるため、各カーソルの名前はスコープ内で一意であることが必要です。1つのプリコンパイル・ユニット内で同じ名前のカーソルを複数宣言することはできません。

カーソルは、UPDATE文またはDELETE文のWHERE句内でCURRENT OF構文を使用して参照できます。このとき、カーソルはOPEN文を使用してオープンし、FETCH文を使用して行に位置付けられている必要があります。この文の詳細は、「DECLARE CURSOR文でのWITH HOLD句の使用」を参照してください。

標準SQLの動作に適合するように、デフォルトでは使用中のカーソルはROLLBACKの後でクローズされます。下位互換性を維持するため、ロールバック後も使用中のカーソルをオープン状態のままにするには、コマンドライン・オプションCWH_SQL99をNOに設定します。

例

この例では、DECLARE CURSOR文の使用方法を示します。

EXEC SQL DECLARE EMPCURSOR CURSOR
FOR SELECT ENAME, EMPNO, JOB, SAL
FROM EMP
WHERE DEPTNO = :DEPTNO
END-EXEC.

関連項目

CLOSE (実行可能埋込みSQL)。

DECLARE DATABASE (Oracle埋込みSQLディレクティブ)。

DECLARE STATEMENT (埋込みSQLディレクティブ)。

DELETE (実行可能埋込みSQL)。

FETCH (実行可能埋込みSQL)。

OPEN (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)。

SELECT (実行可能埋込みSQL)。

UPDATE (実行可能埋込みSQL)。

DECLARE DATABASE (Oracle埋込みSQLディレクティブ)

用途

後続の埋込みSQL文でアクセスされるデフォルト以外のデータベースの識別子を宣言します。

前提条件

デフォルト以外のデータベースのユーザー名にアクセスできる必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

db_name

デフォルト以外のデータベースに対して設定する識別子。

使用上の注意

デフォルト以外のデータベースに対してdb_nameを宣言するのは、他の埋込みSQL文がAT句を使用してそのデータベースを参照できるようにするためです。AT句を指定してCONNECT文を発行する前に、DECLARE DATABASE文を使用してデフォルト以外のデータベースに対してdb_nameを宣言する必要があります。

この文の詳細は、「ユーザー名/パスワードの使用方法」を参照してください。

例

この例では、DECLARE DATABASEディレクティブの使用方法を示します。

EXEC SQL DECLARE ORACLE3 DATABASE END-EXEC.

関連項目

COMMIT (実行可能埋込みSQL)

CONNECT (実行可能埋込みSQL拡張機能)。

DECLARE CURSOR (埋込みSQLディレクティブ)。

DECLARE STATEMENT (埋込みSQLディレクティブ)。

DELETE (実行可能埋込みSQL)。

EXECUTE (実行可能埋込みSQL)。

EXECUTE IMMEDIATE (実行可能埋込みSQL)。

INSERT (実行可能埋込みSQL)。

SELECT (実行可能埋込みSQL)。

UPDATE (実行可能埋込みSQL)。

DECLARE STATEMENT (埋込みSQLディレクティブ)

用途

SQL文またはPL/SQLブロックの識別子を宣言し、他の埋込みSQL文で使用できるようにします。

前提条件

なし。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

AT

SQL文またはPL/SQLブロックをどのデータベースに対して宣言するかを指定します。次のいずれかを使用してデータベースを指定します。

db_name

DECLARE DATABASE文を使用してすでに宣言されているデータベース識別子。

host_variable

すでに宣言されているdb_name値のホスト変数。この句を省略した場合、Oracle Databaseはデフォルトのデータベースに対してSQL文またはPL/SQLブロックを宣言します。

statement_name

文またはPL/SQLブロックに対して宣言されている識別子。

使用上の注意

DECLARE STATEMENT文を使用してSQL文またはPL/SQLブロックの識別子を宣言する必要があるのは、その識別子を参照するDECLARE CURSOR文の埋込みSQLプログラム内での位置が、文またはブロックを解析して識別子と対応付けるPREPARE文よりも物理的に(論理的ではなく)前になっているときのみです。

文の宣言のスコープは、カーソルの宣言と同様に、プリコンパイル・ユニット内全体です。この文の詳細は、「DECLARE」を参照してください。

例I

この例では、DECLARE STATEMENT文の使用方法を示します。

EXEC SQL AT REMOTEDB
DECLARE MYSTATEMENT STATEMENT
END-EXEC.
EXEC SQL PREPARE MYSTATEMENT FROM :MY-STRING
END-EXEC.
EXEC SQL EXECUTE MYSTATEMENT END-EXEC.

例II

この例では、DECLARE CURSOR文がPREPARE文の前にあるため、DECLARE STATEMENT文が必要です。

EXEC SQL DECLARE MYSTATEMENT STATEMENT END-EXEC.
...
EXEC SQL DECLARE EMPCURSOR CURSOR FOR MYSTATEMENT END-EXEC.
...
EXEC SQL PREPARE MYSTATEMENT FROM :MY-STRING END-EXEC.
...

関連項目

CLOSE (実行可能埋込みSQL)。

DECLARE DATABASE (Oracle埋込みSQLディレクティブ)。

FETCH (実行可能埋込みSQL)。

OPEN (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)。

DECLARE TABLE (Oracle埋込みSQLディレクティブ)

用途

オプションがSQLCHECK=SEMANTICS (またはFULL)の場合に、プリコンパイラによって、それぞれの列のデータ型、デフォルト値および意味検査のためのNULLかNOT NULL指定など、表またはビューの構造を定義します。

前提条件

なし。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

table

宣言した表の名前。

column

tableの列。

datatype

columnのデータ型。Oracleデータ型の詳細は、「Oracle Databaseのデータ型」を参照してください。

NOT NULL

columnにはNULLを入れることができません。

使用上の注意

データ型の場合、長さ、精度および位取りに使用できるのは(式ではなく)整数のみです。この文の使用方法の詳細は、「SQLCHECK=SEMANTICSの指定」を参照してください。

例

次の文では、PARTNO、BINおよびQTYの列を含むPARTSという表を宣言しています。

EXEC SQL DECLARE PARTS TABLE
(PARTNO  NUMBER  NOT NULL,
BIN     NUMBER,
QTY     NUMBER)
END-EXEC.

関連項目

なし。

DELETE (実行可能埋込みSQL)

用途

表またはビューの実表から行を削除します。

前提条件

表から行を削除するには、表がユーザーのスキーマ内にあるか、表に対してDELETEの権限を持っている必要があります。

ビューの実表から行を削除するには、ビューが属するスキーマの所有者が、実表に対してDELETEの権限を持っている必要があります。また、ビューがユーザー所有のスキーマ以外のスキーマにある場合は、ビューに対するDELETEの権限を付与されている必要があります。

DELETE ANY TABLEシステム権限を持っていれば、すべての表またはビューの実表から行を削除できます。

構文

DML RETURNING句の構文を示します。

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

AT

どのデータベースに対してDELETE文を発行するかを指定します。次のいずれかを使用してデータベースを指定します。

db_name

すでにDECLARE DATABASE文で宣言されているデータベース識別子。

host_variable

すでに宣言されているdb_name値のホスト変数。この句を省略した場合、DELETE文はデフォルトのデータベースに対して発行されます。

host_integer
integer

WHERE句に配列ホスト変数が含まれる場合に、文を実行する回数を制限します。この句を省略した場合、Oracleは最小の配列の各コンポーネントにつき1回ずつ文が実行されます。

schema

表またはビューを含むスキーマ。schemaを省略した場合、Oracleは表またはビューがユーザーのスキーマ内にあるとみなします。

table view

行を削除する表の名前。viewを指定すると、Oracleはビューの実表から行を削除します。

dblink

表またはビューがあるリモート・データベースへのデータベース・リンクの完全または部分的な名前。データベース・リンク参照の情報は、『Oracle Database SQL言語リファレンス』の第2章を参照してください。分散オプションでOracleを使用している場合のみ、リモートの表またはビューから行を削除できます。
dblinkを省略した場合、Oracleは表またはビューがローカル・データベースにあるとみなします。

part_name

表内のパーティションの名前。

alias

表に割り当てられている別名。別名は一般に、DELETE文で相関問合せのために使用します。

WHERE

削除する行を指定します。

condition

CURRENT OF

この句を完全に省略した場合、Oracleは表またはビューからすべての行を削除します。

DML RETURNING句

詳細は、「DML RETURNING句」を参照してください。

使用上の注意

WHERE句のホスト変数は、すべてスカラーか、すべて配列であることが必要です。変数がスカラーの場合、OracleはDELETE文を1回のみ実行します。変数が配列の場合、Oracleは配列のコンポーネント・セットごとに1回ずつこの文を実行します。1回の実行で0行、1行または複数行を削除できます。

WHERE句の配列ホスト変数は、サイズが異なっていてもかまいません。この場合、Oracleが文を実行する回数は、次のうちの小さい方の値によって決定します。

- 最小の配列のサイズ

- オプションのFOR句のhost_integerの値

この条件を満たす行が存在しない場合、行は削除されず、SQLCODEはNOT_FOUND条件を戻します。

削除された行の累積数はSQLCAを介して戻されます。WHERE句に配列ホスト変数が指定されていると、DELETE文によって処理された配列のすべてのコンポーネントにおよぶ削除行数の合計がこの値に設定されます。

条件を満たす行がない場合、OracleはSQLCAのSQLCODEを介してエラーを戻します。WHERE句を省略した場合、OracleはSQLCAのSQLWARNの第5コンポーネントに警告フラグを設定します。この文およびSQLCAの詳細は、「SQLコミュニケーション領域の使用」を参照してください。

DELETE文ではコメントを使用して、指示またはヒントをOracleのオプティマイザに渡すことができます。オプティマイザはヒントを使用して文の実行計画を選択します。ヒントの詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください。

例

この例では、DELETE文の使用方法を示します。

EXEC SQL DELETE FROM EMP
WHERE DEPTNO = :DEPTNO
AND JOB = :JOB
END-EXEC.
EXEC SQL DECLARE EMPCURSOR CURSOR
FOR SELECT EMPNO, COMM
FROM EMP
END-EXEC.
EXEC SQL OPEN EMPCURSOR END-EXEC.
EXEC SQL FETCH EMPCURSOR
INTO :EMP-NUMBER, :COMMISSION
END-EXEC.
EXEC SQL DELETE FROM EMP
WHERE CURRENT OF EMPCURSOR
END-EXEC.

関連項目

DECLARE DATABASE (Oracle埋込みSQLディレクティブ)。

DECLARE STATEMENT (埋込みSQLディレクティブ)。

DESCRIBE (実行可能埋込みSQL)

用途

Oracle動的SQL文またはPL/SQLブロックのホスト変数の記述を保持する記述子を初期化します。

前提条件

埋込みSQLのPREPARE文を使用して、SQL文またはPL/SQLブロックを事前に準備しておく必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

BIND VARIABLES FOR

SQL文またはPL/SQLブロックの入力変数に関する情報を保持する記述子を初期化します。

SELECT LIST FOR

SELECT文の選択リストに関する情報を保持する記述子を初期化します。

-

デフォルトはSELECT LIST FORです。

statement_name

PREPARE文を使用して事前に準備したSQL文またはPL/SQLブロックを指定します。

descriptor

初期化する記述子の名前です。

使用上の注意

埋込みSQLプログラム内のバインド記述子または選択記述子を操作するには、その前にDESCRIBE文を発行する必要があります。

入力変数と出力変数の両方を同じ記述子に記述することはできません。

DESCRIBE文で検出される変数の数は、一意に名前が指定されたプレースホルダの合計数ではなく、準備するSQL文またはPL/SQLブロックのプレースホルダの合計数です。この文の詳細は、「DESCRIBE文」を参照してください。

例

この例では、Pro*COBOL埋込みSQLプログラムでDESCRIBE文を使用する方法を示します。

EXEC SQL PREPARE MYSTATEMENT FROM :MY-STRING END-EXEC.
EXEC SQL DECLARE EMPCURSOR
FOR SELECT EMPNO, ENAME, SAL, COMM
FROM EMP
WHERE DEPTNO = :DEPT-NUMBER
END-EXEC.
EXEC SQL DESCRIBE BIND VARIABLES FOR MYSTATEMENT
INTO BINDDESCRIPTOR
END-EXEC.
EXEC SQL OPEN EMPCURSOR
USING BINDDESCRIPTOR
END-EXEC.
EXEC SQL DESCRIBE SELECT LIST FOR MY-STATEMENT
INTO SELECTDESCRIPTOR
END-EXEC.
EXEC SQL FETCH EMPCURSOR
INTO SELECTDESCRIPTOR
END-EXEC.

関連項目

PREPARE (実行可能埋込みSQL)。

DESCRIBE DESCRIPTOR (実行可能埋込みSQL)

用途

ANSI SQL文の情報を取得し、記述子に格納します。

前提条件

埋込みSQLのPREPARE文を使用して、SQL文を事前に準備しておく必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

statement_id

事前に準備されているSQL文またはPL/SQLブロックの名前。OUTPUTはデフォルトです。

desc_name

SQL文の情報を保持する記述子名を格納するホスト変数。

'descriptor name'

記述子の名前。

GLOBAL | LOCAL

LOCALがデフォルトです。これはファイルのスコープであり、GLOBALはアプリケーションのスコープです。

使用上の注意

DYNAMIC=ANSIプリコンパイラ・オプションを使用してください。INPUT記述子では、COUNTおよびNAMEのみインプリメントされます。

DESCRIBE文で検出される変数の数は、一意に名前が指定されたプレースホルダの合計数ではなく、準備するSQL文またはPL/SQLブロックのプレースホルダの合計数です。この文の詳細は、第10章「ANSI動的SQL」を参照してください。

例

EXEC SQL PREPARE s FROM :my_stament END-EXEC.
EXEC SQL DESCRIBE INPUT s USING DESCRIPTOR 'in' END-EXEC.

関連項目

ALLOCATE DESCRIPTOR (実行可能埋込みSQL)。

DEALLOCATE DESCRIPTOR (埋込みSQL文)。

GET DESCRIPTOR (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)。

SET DESCRIPTOR (実行可能埋込みSQL)。

ENABLE THREADS (実行可能埋込みSQL拡張機能)

用途

複数のスレッドをサポートするプロセスを初期化します。

前提条件

マルチスレッド・アプリケーションをサポートするプラットフォーム用にプリコンパイラ・アプリケーションを開発し、このプラットフォームでコンパイルを実行して、コマンドラインにTHREADS=YESを指定する必要があります。

構文

キーワードおよびパラメータ

なし。

使用上の注意

ENABLE THREADS文を実行するのは一度、それも他の実行SQL文の前やスレッドの起動前にしてください。この文にはホスト変数を指定する必要はありません。

例

この例では、Pro*COBOLプログラムでENABLE THREADS文を使用する方法を示します。

EXEC SQL ENABLE THREADS END-EXEC.

関連項目

CONTEXT ALLOCATE (実行可能埋込みSQL拡張機能)。

CONTEXT FREE (実行可能埋込みSQL拡張機能)。

CONTEXT USE (Oracle埋込みSQLディレクティブ)。

EXECUTE ...END-EXEC (実行可能埋込みSQL拡張機能)

用途

Oracle Pro*COBOLプログラムに無名PL/SQLブロックを埋め込みます。

前提条件

なし。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

AT

PL/SQLブロックをどのデータベースに対して実行するかを指定します。次のいずれかを使用してデータベースを指定します。

db_name

すでにDECLARE DATABASE文で宣言されているデータベース識別子。

host_variable

すでに宣言されているdb_name値のホスト変数。

この句を省略した場合、PL/SQLブロックはデフォルトのデータベースに対して実行されます。

pl/sql_block

PL/SQLブロックの作成方法など、PL/SQLの詳細は『Oracle Database PL/SQL言語リファレンス』を参照してください。

END-EXEC

埋込みPL/SQLブロックの後に配置する必要があります。

使用上の注意

Oracleプリコンパイラは埋込みPL/SQLブロックを1つの埋込みSQL文のように扱うため、PL/SQLブロックはOracleプリコンパイラ・プログラムでSQL文を埋め込める場所であればどこにでも埋め込めます。Oracleプリコンパイラ・プログラムへのPL/SQLブロックの埋込みに関する詳細は、第6章「埋込みPL/SQL」を参照してください。

例

Oracleプリコンパイラ・プログラムにこのEXECUTE文を挿入すると、プログラムにPL/SQLブロックが埋め込まれます。

EXEC SQL EXECUTE
BEGIN
SELECT ENAME, JOB, SAL
INTO :EMP-NAME:IND-NAME, :JOB-TITLE, :SALARY
FROM EMP
WHERE EMPNO = :EMP-NUMBER;
IF :EMP-NAME:IND-NAME IS NULL
THEN RAISE NAME-MISSING;
END IF;
END;
END-EXEC.

関連項目

EXECUTE IMMEDIATE (実行可能埋込みSQL)。

EXECUTE (実行可能埋込みSQL)

用途

Oracle動的SQLでは、埋込みSQLのPREPARE文によって準備済のDELETE文、INSERT文またはUPDATE文、あるいはPL/SQLブロックを実行します。

前提条件

埋込みSQLのPREPARE文を使用して、SQL文またはPL/SQLブロックを先に準備しておく必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

FOR :array_size
FOR integer

処理される行の数を格納するホスト変数。
処理される行数。

USING句が配列ホスト変数を含む場合に、文の実行回数を制限します。この句を省略した場合、Oracleは最小の配列の各コンポーネントに対してこの文を1回ずつ実行します。

statement_id

実行するSQL文またはPL/SQLブロックに対応付けられているプリコンパイラ識別子。プリコンパイラ識別子を文またはPL/SQLブロックに対応付けるには、埋込みSQLのPREPARE文を使用します。

USING DESCRIPTOR SQLDA_descriptor

Oracle記述子を使用します。
ANSI記述子(INTO句)と一緒には使用できません。

USING

オプションの標識変数を使用してホスト変数のリストを指定します(Oracleは実行する文にこれらの変数を入力変数として代入します)。ホスト変数および標識変数は、すべてスカラーか、すべて配列であることが必要です。

host_variable

ホスト変数。

indicator_variable

標識変数。

使用方法

この文の詳細は、第9章「Oracle動的SQL」を参照してください。

例

この例では、Pro*COBOL埋込みSQLプログラムでEXECUTE文を使用する方法を示します。

EXEC SQL PREPARE MY-STATEMENT FROM MY-STRING END-EXEC.
EXEC SQL EXECUTE MY-STATEMENT USING :MY-VAR END-EXEC.

関連項目

DECLARE DATABASE (Oracle埋込みSQLディレクティブ)。

PREPARE (実行可能埋込みSQL)。

EXECUTE DESCRIPTOR (実行可能埋込みSQL)

用途

ANSI SQL方法4では、埋込みSQLのPREPARE文によって準備済のDELETE文、INSERT文またはUPDATE文、あるいはPL/SQLブロックを実行します。

前提条件

埋込みSQLのPREPARE文を使用して、SQL文またはPL/SQLブロックを先に準備しておく必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

FOR :array_size
FOR integer

処理される行の数を格納するホスト変数。
処理される行数。

文の実行回数を制限します。Oracleは最小の配列の各コンポーネントに対してこの文を1回ずつ実行します。

statement_id

実行するSQL文またはPL/SQLブロックに対応付けられているプリコンパイラ識別子。プリコンパイラ識別子を文またはPL/SQLブロックに対応付けるには、埋込みSQLのPREPARE文を使用します。

USING
descriptor_name

descriptor name

ANSI入力記述子。
入力記述子名を格納するホスト変数。

入力記述子の名前。

INTO
descriptor_name

descriptor name

ANSI出力記述子。
出力記述子名を格納するホスト変数。

出力記述子の名前。

GLOBAL | LOCAL

LOCAL (デフォルト)はファイルのスコープで、GLOBALはアプリケーションのスコープです。

使用上の注意

この文の詳細は、「EXECUTE」を参照してください。

例

ANSI動的SQL方法4では、EXECUTEのINTO句によりSELECTのDML RETURNINGを使用することができます。

EXEC SQL EXECUTE S2 USING DESCRIPTOR :bv1 INTO DESCRIPTOR 'SELDES' END-EXEC.

関連項目

DECLARE DATABASE (Oracle埋込みSQLディレクティブ)。

PREPARE (実行可能埋込みSQL)。

EXECUTE IMMEDIATE (実行可能埋込みSQL)

用途

ホスト変数を含まないDELETE文、INSERT文またはUPDATE文、あるいはPL/SQLブロックを準備し、実行します。

前提条件

なし。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

AT

SQL文またはPL/SQLブロックをどのデータベースに対して宣言するかを指定します。次のいずれかを使用してデータベースを指定します。

db_name

すでにDECLARE DATABASE文で宣言されているデータベース識別子。

host_variable

すでに宣言されているdb_name値のホスト変数。

この句を省略した場合、文またはブロックはデフォルトのデータベースに対して実行されます。

host_string

実行するSQL文またはPL/SQLブロックを値とするホスト変数。

text

実行するSQL文またはPL/SQLブロックを含むテキスト・リテラル。引用符は省略できます。

SQL文は、DELETE文、INSERT文またはUPDATE文のいずれかであることが必要です。

使用上の注意

EXECUTE IMMEDIATE文を発行すると、Oracleは指定したSQL文またはPL/SQLブロックを解析してエラーをチェックし、実行します。見つかったエラーは、SQLCAのSQLCODEコンポーネントに戻されます。

この文の詳細は、「EXECUTE IMMEDIATE文」を参照してください。

例

この例では、EXECUTE IMMEDIATE文の使用方法を示します。

EXEC SQL
EXECUTE IMMEDIATE 'DELETE FROM EMP WHERE EMPNO = 9460'
END-EXEC.

関連項目

PREPARE (実行可能埋込みSQL)。

EXECUTE (実行可能埋込みSQL)。

FETCH (実行可能埋込みSQL)

用途

選択リストの値をホスト変数に割り当てて、問合せが戻した1つまたは複数の行を取り出します。ANSI動的SQL方法4の詳細は、「FETCH DESCRIPTOR (実行可能埋込みSQL)」を参照してください。

前提条件

OPEN文を使用してカーソルを先にオープンしておく必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

FOR :array_size
FOR integer

処理される行の数を格納するホスト変数。
処理される行数。

配列ホスト変数を使用する場合にフェッチする行数を制限します。この句を省略した場合、Oracleは最小の配列を満たすのに十分な数の行をフェッチします。

cursor

DECLARE CURSOR文を使用して宣言したカーソル。FETCH文は、カーソルに対応付けられた問合せが選択した行のうちの1行を戻します。

cursor_variable

ALLOCATE文を使用して割り当てたカーソル変数。FETCH文は、カーソル変数に対応付けられた問合せが選択した行のうちの1行を戻します。

INTO

データをフェッチするホスト変数およびオプションの標識変数のリストを指定します。これらのホスト変数および標識変数は、プログラム内で宣言されている必要があります。

USING SQLDA_variable

DESCRIBE文を使用して事前に参照しているOracle記述子を指定します。この句は、動的埋込みSQL方法4以外では使用しないでください。カーソル変数を使用している場合は、USING句は適用されません。

host_variable

データが戻されるホスト変数。

indicator_variable

ホスト標識変数。

使用上の注意

FETCH文はアクティブ・セットの行を読み取り、結果が含まれる出力変数の名前を示します。対応付けられたホスト変数がNULLの場合、標識変数の値は-1に設定されます。

出力ホスト変数のサイズは取り出された行数を示し、FOR句は値を示します。データを受け取るホスト変数は、すべてスカラーか、すべて配列であることが必要です。スカラーの場合は、Oracleは1行のみフェッチします。配列の場合、Oracleは配列を満たすのに十分な数の行をフェッチします。

配列ホスト変数は、サイズが異なってもかまいません。この場合、Oracleがフェッチする行数は、次の値のうち小さい方です。

- 最小の配列のサイズ

- オプションのFOR句のhost_integerの値

フェッチする行数は、実際に問合せを満たす行数によってさらに限定できます。

FETCH文が、問合せで戻された行すべてを取得しなかった場合、カーソルは戻された次の行に配置されます。問合せで戻された最後の行を取得すると、次のFETCH文を実行すると、SQLCAのSQLCODE要素に警告コードが戻されることになります。

配列が完全に満たされない場合には警告が発行されます。その場合は、実際にフェッチされた行数をSQLERRD(3)で確認してください。

FETCH文にはAT句がないので注意してください。カーソルによってアクセスされるデータベースは、DECLARE CURSOR文で指定する必要があります。

FETCH文では、アクティブ・セット内を前方向にのみ進めます。すでにフェッチした行に戻る場合は、カーソルを再オープンして各行を順番に取り出す必要があります。アクティブ・セットを変更するには、新しい値をカーソルの問合せの入力ホスト変数に割り当て、カーソルを再オープンします。

例

この例では、Pro*COBOL埋込みSQLプログラム内のFETCH文を示します。

EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT JOB, SAL FROM EMP WHERE DEPTNO = 30
END-EXEC.
...
EXEC SQL WHENEVER NOT FOUND GOTO ...
LOOP.
EXEC SQL FETCH EMPCURSOR INTO :JOB-TITLE1, :SALARY1 END-EXEC.
EXEC SQL FETCH EMPCURSOR INTO :JOB-TITLE2, :SALARY2 END-EXEC.
...
GO TO LOOP.
...

関連項目

CLOSE (実行可能埋込みSQL)。

DECLARE CURSOR (埋込みSQLディレクティブ)。

OPEN (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)。

FETCH DESCRIPTOR (実行可能埋込みSQL)

用途

選択リストの値をホスト変数に割り当てて、問合せが戻した1つまたは複数の行を取り出します。ANSI動的SQL方法4で使用します。

前提条件

OPEN文を使用してカーソルを先にオープンしておく必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

FOR :array_size
FOR integer

処理される行の数を格納するホスト変数。
処理される行数。

配列ホスト変数を使用する場合にフェッチする行数を制限します。この句を省略した場合、Oracleは最小の配列を満たすのに十分な数の行をフェッチします。

cursor

DECLARE CURSOR文を使用して宣言したカーソル。FETCH文は、カーソルに対応付けられた問合せが選択した行のうちの1行を戻します。

cursor_variable

ALLOCATE文を使用して割り当てたカーソル変数。FETCH文は、カーソル変数に対応付けられた問合せが選択した行のうちの1行を戻します。

INTO

データをフェッチするホスト変数およびオプションの標識変数のリストを指定します。これらのホスト変数および標識変数は、プログラム内で宣言されている必要があります。

INTO 'descriptor name'
INTO :descriptor_name

出力ANSI記述子の名前。
出力記述子名を格納するホスト変数。

GLOBAL | LOCAL

LOCAL (デフォルト)はファイルのスコープで、GLOBALはアプリケーションのスコープです。

使用上の注意

出力ホスト変数のサイズは取り出された行数を示し、FOR句は値を示します。データを受け取るホスト変数は、すべてスカラーか、すべて配列であることが必要です。スカラーの場合は、Oracleは1行のみフェッチします。配列の場合、Oracleは配列を満たすのに十分な数の行をフェッチします。

配列ホスト変数は、サイズが異なってもかまいません。この場合、Oracleがフェッチする行数は、次の値のうち小さい方です。

- 最小の配列のサイズ

- オプションのFOR句のarray_sizeの値

- フェッチする行数は、実際に問合せを満たす行数によってさらに限定できます。

FETCH文が、問合せで戻された行すべてを取得しなかった場合、カーソルは戻された次の行に配置されます。問合せで戻された最後の行を取得すると、次のFETCH文を実行すると、SQLCAのSQLCODE要素に警告コードが戻されることになります。

配列が完全に満たされない場合には警告が発行されます。その場合は、実際にフェッチされた行数をSQLERRD(3)で確認してください。

FETCH文にはAT句がないので注意してください。カーソルによってアクセスされるデータベースは、DECLARE CURSOR文で指定する必要があります。

FETCH文では、アクティブ・セット内を前方向にのみ進めます。すでにフェッチした行に戻る場合は、カーソルを再オープンして各行を順番に取り出す必要があります。アクティブ・セットを変更するには、新しい値をカーソルの問合せの入力ホスト変数に割り当て、カーソルを再オープンします。

ANSI SQL方法4アプリケーション用にDYNAMIC=ANSIプリコンパイラ・オプションを使用してください。ANSI SQL方法4アプリケーションの詳細は、「FETCH」を参照してください。

例

...
EXEC SQL ALLOCATE DESCRIPTOR 'output_descriptor' END-EXEC.
...
EXEC SQL PREPARE S FROM :dyn_statement END-EXEC.
EXEC SQL DECLARE mycursor CURSOR FOR S END-EXEC.
...
EXEC SQL FETCH mycursor INTO DESCRIPTOR 'output_descriptor' END-EXEC.
...

関連項目

PREPARE文。

FREE (実行可能埋込みSQL拡張機能)

用途

カーソル変数、LOBロケータまたはROWIDが使用するメモリーを解放します。

前提条件

メモリーがすでに割り当てられている必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

cursor_variable

ALLOCATE文に割当て済のカーソル変数。SQL-CURSOR型です。
FETCH文は、カーソル変数に対応付けられた問合せが選択した行のうちの1行を戻します。

host_ptr

LOB用のROWID、SQL-BLOB、SQL-CLOBまたはSQL-NCLOBのSQL-ROWID型の変数。

使用上の注意

「カーソル」および「カーソル変数」を参照してください。

例

* CURSOR VARIABLE EXAMPLE
...
01  CUR      SQL-CURSOR.
...
EXEC SQL ALLOCATE :CUR END-EXEC.
...
EXEC SQL CLOSE :CUR END-EXEC.
EXEC SQL FREE  :CUR END-EXEC.
...

関連項目

ALLOCATE (実行可能埋込みSQL拡張機能)。

CLOSE (実行可能埋込みSQL)。

DECLARE CURSOR (埋込みSQLディレクティブ)。

GET DESCRIPTOR (実行可能埋込みSQL)

用途

SQL記述子領域のホスト変数の情報を取得します。

前提条件

値構文およびANSI動的SQL方法4以外では使用しないでください。

構文

item_nameのみ次の中から選択できます。

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

array_size
integer

処理される行の数を格納するホスト変数。
処理される行数。

descriptor_name

割り当てられたANSI記述子名を格納するホスト変数。

'descriptor name'

割り当てられたANSI記述子の名前。

GLOBAL | LOCAL

LOCAL (デフォルト)はファイルのスコープで、GLOBALはアプリケーションのスコープです。

host_var=COUNT

入力および出力変数の合計数を格納するホスト変数。

integer

入力および出力変数の合計数。

VALUE :host_integer

参照される入力または出力変数の位置を格納するホスト変数。

VALUE integer

参照される入力または出力変数の位置。

host_var

項目の値を受け取るホスト変数。

item_name

item_nameに関しては、表10-4および表10-5の「記述子項目名」列を参照してください。

使用上の注意

DYNAMIC=ANSIプリコンパイラ・オプションを使用してください。配列サイズ句は、DATA、RETURNED_LENGTHおよびINDICATORの項目名で使用できます。「GET DESCRIPTOR」を参照してください。

例

EXEC SQL GET DESCRIPTOR GLOBAL 'mydesc' :mydesc_num_vars = COUNT END-EXEC.

関連項目

ALLOCATE DESCRIPTOR (実行可能埋込みSQL)。

DESCRIBE DESCRIPTOR (実行可能埋込みSQL)。

SET DESCRIPTOR (実行可能埋込みSQL)。

INSERT (実行可能埋込みSQL)

用途

表またはビューの実表に行を追加します。

前提条件

表に行を挿入するには、その表が自分のスキーマ内にあるか、またはその表に対してINSERTの権限を持っている必要があります。

ビューの実表に行を挿入するには、ビューが属するスキーマの所有者が、その実表に対してINSERTの権限を持っている必要があります。また、ビューがユーザーのスキーマ以外のスキーマ内にある場合は、ビューに対してINSERTの権限を持っている必要があります。

INSERT ANY TABLEシステム権限を使用すると、表またはビューの実表ならどれにでも行を入力できます。

構文

DML RETURNING句の構文を示します。

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

AT

INSERT文をどのデータベースについて実行するかを指定します。次のいずれかを使用してデータベースを指定します。

db_name

すでにDECLARE DATABASE文で宣言されているデータベース識別子。

host_variable

すでに宣言されているdb_name値のホスト変数。この句を省略した場合、INSERT文はデフォルトのデータベースに対して実行されます。

FOR: host_integer

VALUES句に配列ホスト変数が含まれる場合に、文を実行する回数を制限します。この句を省略した場合、Oracleは最小の配列の各コンポーネントにつき1回ずつ文が実行されます。

schema

表またはビューを含むスキーマ。schemaを省略した場合、Oracleは表またはビューがユーザーのスキーマ内にあるとみなします。

table
view

行を挿入する表の名前。viewを指定する場合、Oracleはビューの実表に行を挿入します。

db_link :

表またはビューがあるリモート・データベースへのデータベース・リンクの完全名または部分名。データベース・リンク参照の情報は、『Oracle Database SQL言語リファレンス』を参照してください。分散オプションでOracleを使用している場合のみ、リモートの表またはビューに行を挿入できます。
db_linkを省略した場合、Oracleは表またはビューがローカル・データベース内にあるとみなします。

part_name

表内のパーティションの名前。

column

表またはビューの列。挿入した行では、このリストの各列にVALUES句または問合せから値が割り当てられます。
このリストから表の列を削除する場合、挿入された行の列値は、表の作成時に指定した列のデフォルト値となります。列のリストを完全に省略した場合は、VALUES句または問合せによって、表のすべての列の値を指定する必要があります。

VALUES

表またはビューに挿入される値の行を指定します。『Oracle Database SQL言語リファレンス』のexprに関する説明を参照してください。式は、オプションの標識変数を付けたホスト変数です。VALUES句では、列のリストの各列に式を指定する必要があります。

subquery

表に挿入される行を戻す副問合せ。この副問合せの選択リストの列数は、INSERT文の列のリストの列数と同じであることが必要です。副問合せの構文説明は、『Oracle Database SQL言語リファレンス』のSELECTに関する項を参照してください。

DML RETURNING句

詳細は、「DML RETURNING句」を参照してください。

使用上の注意

WHERE句内のホスト変数は、すべてスカラーか、すべて配列であることが必要です。変数がスカラーの場合、OracleはINSERT文を1回実行します。変数が配列の場合、OracleはINSERT文を各配列コンポーネント・セットについて1回ずつ実行して、1行ずつ挿入します。

WHERE句の配列ホスト変数は、サイズが異なっていてもかまいません。この場合、Oracleが文を実行する回数は、次のうちの小さい方の値によって決定します。

- 最小の配列のサイズ

- オプションのFOR句のhost_integerの値。

この文の詳細は、「基本的なSQL文」を参照してください。

例I

この例では、埋込みSQL INSERT文の使用方法を示します。

EXEC SQL
INSERT INTO EMP (ENAME, EMPNO, SAL)
VALUES (:ENAME, :EMPNO, :SAL)
END-EXEC.

例II

この例では、副問合せを使用した埋込みSQLのINSERT文を示します。

EXEC SQL
INSERT INTO NEWEMP (ENAME, EMPNO, SAL)
SELECT ENAME, EMPNO, SAL FROM EMP
WHERE DEPTNO = :DEPTNO
END-EXEC.

関連項目

DECLARE DATABASE (Oracle埋込みSQLディレクティブ)。

LOB APPEND (実行可能埋込みSQL拡張機能)

用途

LOBを別のLOBの最後に追加します。

前提条件

LOBバッファリングは使用可能にしないでください。宛先LOBが初期化されている必要があります。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「APPEND」を参照してください。

関連項目

他のLOB文を参照してください。

LOB ASSIGN (実行可能埋込みSQL拡張機能)

用途

LOBまたはBFILEロケータを別のロケータに割り当てます。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「ASSIGN」を参照してください。

関連項目

他のLOB文を参照してください。

LOB CLOSE (実行可能埋込みSQL拡張機能)

用途

オープンされているLOBまたはBFILEをクローズします。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「CLOSE」を参照してください。

関連項目

他のLOB文を参照してください。

LOB COPY (実行可能埋込みSQL拡張機能)

用途

LOB値の全部または一部を別のLOBにコピーします。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「COPY」を参照してください。

関連項目

他のLOB文を参照してください。

LOB CREATE TEMPORARY (実行可能埋込みSQL拡張機能)

用途

一時LOBを作成します。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「CREATE TEMPORARY」を参照してください。

関連項目

他のLOB文を参照してください。

LOB DESCRIBE (実行可能埋込みSQL拡張機能)

用途

LOBから属性を取り出します。

構文

attribは次のとおりです。

使用上の注意

使用方法、キーワード、パラメータおよび例は、「DESCRIBE」を参照してください。

関連項目

他のLOB文を参照してください。

LOB DISABLE BUFFERING (実行可能埋込みSQL拡張機能)

用途

LOBバッファリングを使用禁止にします。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「DISABLE BUFFERING」を参照してください。

関連項目

他のLOB文を参照してください。

LOB ENABLE BUFFERING (実行可能埋込みSQL拡張機能)

用途

LOBバッファリングを有効にします。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「ENABLE BUFFERING」を参照してください。

関連項目

他のLOB文を参照してください。

LOB ERASE (実行可能埋込みSQL拡張機能)

用途

指定されたオフセットから始まる指定された量のLOBデータを消去します。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「ERASE」を参照してください。

関連項目

他のLOB文を参照してください。

LOB FILE CLOSE ALL (実行可能埋込みSQL拡張機能)

用途

カレント・セッションでオープンしているすべてのBFILEをクローズします。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「FILE CLOSE ALL」を参照してください。

関連項目

他のLOB文を参照してください。

LOB FILE SET (実行可能埋込みSQL拡張機能)

用途

BFILEロケータのDIRECTORYおよびFILENAMEを設定します。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「FILE SET」を参照してください。

関連項目

他のLOB文を参照してください。

LOB FLUSH BUFFER (実行可能埋込みSQL拡張機能)

用途

LOBのバッファをデータベース・サーバーに書き込みます。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「FLUSH BUFFER」を参照してください。

関連項目

他のLOB文を参照してください。

LOB FREE TEMPORARY (実行可能埋込みSQL拡張機能)

用途

LOBロケータ用に一時領域を解放します。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「FREE TEMPORARY」を参照してください。

関連項目

他のLOB文を参照してください。

LOB LOAD (実行可能埋込みSQL拡張機能)

用途

BFILEの全部または一部を、内部LOBにコピーします。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「LOAD FROM FILE」を参照してください。

関連項目

他のLOB文を参照してください。

LOB OPEN (実行可能埋込みSQL拡張機能)

用途

読取りまたは読取り/書込みを行うLOBまたはBFILEをオープンします。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「OPEN」を参照してください。

関連項目

他のLOB文を参照してください。

LOB READ (実行可能埋込みSQL拡張機能)

用途

LOBまたはBFILEの一部をバッファに読み込みます。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「READ」を参照してください。

関連項目

他のLOB文を参照してください。

LOB TRIM (実行可能埋込みSQL拡張機能)

用途

LOB値を切り捨てます。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「TRIM」を参照してください。

関連項目

他のLOB文を参照してください。

LOB WRITE (実行可能埋込みSQL拡張機能)

用途

バッファの内容をLOBに書き込みます。

構文

使用上の注意

使用方法、キーワード、パラメータおよび例は、「WRITE」を参照してください。

関連項目

他のLOB文を参照してください。

OPEN (実行可能埋込みSQL)

用途

対応付けられた問合せを評価し、USING句が示すホスト変数名を問合せのWHERE句に代入して、カーソルをオープンします。動的SQL文でEXECUTEのかわりに使用できます。ANSI動的SQL構文は、「OPEN DESCRIPTOR (実行可能埋込みSQL)」を参照してください。

前提条件

カーソルは、オープンする前に埋込みSQLのDECLARE CURSOR文を使用して宣言しておく必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

array_size
integer

処理される行の数を格納するホスト変数。
処理される行数。

OPENがEXECUTEと同等の場合にのみ使用できます。

cursor

オープンする(すでに宣言されている)カーソル。

host_variable

カーソルに対応付けられた文に代入するホスト変数を指定します。
ANSI記述子(INTO句)と一緒には使用できません。

DESCRIPTOR SQLDA_descriptor

対応付けられた問合せのWHERE句に代入するホスト変数を表すOracle記述子を指定します。記述子は、DESCRIBE文を使用して事前に初期化されている必要があります。代入は、位置に基づきます。この文で指定するホスト変数名は、対応付けられた問合せの変数名と異なってもかまいません。
ANSI記述子(INTO句)と一緒には使用できません。

使用上の注意

OPEN文は、行のアクティブ・セットを定義し、アクティブ・セットの最初の行の直前でカーソルを初期化します。OPEN時のホスト変数の値が文に代入されます。この文は、実際には行を取り出しません。行はFETCH文を使用して取り出されます。

カーソルを一度オープンすると、入力ホスト変数はカーソルを再オープンするまで再テストされません。入力ホスト変数およびアクティブ・セットを変更するには、カーソルを再オープンする必要があります。

プログラム内のすべてのカーソルは、プログラムを開始する場合またはCLOSE文を使用してカーソルを明示的にクローズした後にクローズ状態になります。

カーソルは事前にクローズしなくても、再オープンできます。この文の詳細は、「カーソルのオープン」を参照してください。

例

この例では、Pro*COBOLプログラムでOPEN文を使用する方法を示します。

EXEC SQL DECLARE EMPCURSOR CURSOR FOR
SELECT ENAME, EMPNO, JOB, SAL
FROM EMP
WHERE DEPTNO = :DEPTNO
END-EXEC.
EXEC SQL OPEN EMPCURSOR END-EXEC.

関連項目

CLOSE (実行可能埋込みSQL)

DECLARE CURSOR (埋込みSQLディレクティブ)

EXECUTE (実行可能埋込みSQL)。

FETCH (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)

OPEN DESCRIPTOR (実行可能埋込みSQL)

用途

対応付けられた問合せを評価し、USING句が示す入力ホスト変数名を問合せのWHERE句に代入して、カーソル(ANSI動的SQL方法4用)をオープンします。INTO句は、出力記述子を示します。動的SQL文でEXECUTEのかわりに使用できます。

前提条件

カーソルは、オープンする前に埋込みSQLのDECLARE CURSOR文を使用して宣言しておく必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

array_size
integer

処理される行の数を格納するホスト変数。
処理される行数。

EXECUTEと同等の場合のみ、動的SQLに使用できます。

cursor

オープンする(すでに宣言されている)カーソル。

USING DESCRIPTOR
descriptor_name 'descriptor name'

ANSI記述子の名前を格納するホスト変数またはANSI記述子の名前でANSI入力記述子を指定します。

INTO DESCRIPTOR descriptor_name 'descriptor name'

ANSI記述子の名前を格納するホスト変数もしくはANSI記述子の名前でANSI出力記述子を指定します。

GLOBAL | LOCAL

LOCAL (デフォルト)はファイルのスコープで、GLOBALはアプリケーションのスコープです。

使用上の注意

プリコンパイラのオプションDYNAMICにANSIを設定します。

OPEN文は、行のアクティブ・セットを定義し、アクティブ・セットの最初の行の直前でカーソルを初期化します。OPEN時のホスト変数の値が文に代入されます。この文は、実際には行を取り出しません。行はFETCH文を使用して取り出されます。

カーソルを一度オープンすると、入力ホスト変数はカーソルを再オープンするまで再テストされません。入力ホスト変数およびアクティブ・セットを変更するには、カーソルを再オープンする必要があります。

プログラム内のすべてのカーソルは、プログラムを開始する場合またはCLOSE文を使用してカーソルを明示的にクローズした後にクローズ状態になります。

カーソルは事前にクローズしなくても、再オープンできます。この文の詳細は、「行の挿入」を参照してください。

例

01 DYN-STATEMENT PIC X(58) VALUE "SELECT ENAME, EMPNO FROM EMP WHERE
DEPTNO =:DEPTNO-DAT".
01 DEPTNO-DAT PIC S9(9) COMP VALUE 10.
...
EXEC SQL ALLOCATE DESCRIPTOR 'input-descriptor' END-EXEC.
EXEC SQL ALLOCATE DESCRIPTOR 'output-descriptor'
...
EXEC SQL PREPARE S FROM :DYN-STATEMENT END-EXEC.
EXEC SQL DECLARE C CURSOR FOR S END-EXEC.
...
EXEC SQL OPEN C USING DESCRIPTOR 'input-descriptor' END-EXEC.
...

関連項目

CLOSE (実行可能埋込みSQL)。

DECLARE CURSOR (埋込みSQLディレクティブ)。

FETCH DESCRIPTOR (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)

用途

ホスト変数で指定するSQL文またはPL/SQLブロックを解析し、識別子に対応付けます。

前提条件

なし。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

db_name

CONNECT文で先に設定されるデータベース接続名を含むNULL終了文字列。省略した場合または空文字の場合は、デフォルトのデータベース接続とみなされます。

host_variable

データベース接続名を格納するホスト変数。

array_size
integer

処理される行の数を格納するホスト変数。
処理される行数。

statement_id

準備済のSQL文またはPL/SQLブロックに対応付ける識別子。この識別子がすでに別の文またはブロックに割り当てられている場合は、以前の割当てが置き換えられます。

host_string

準備するSQL文またはPL/SQLブロックのテキストが値であるホスト変数。

text

実行するSQL文またはPL/SQLブロックを含むテキスト・リテラル。引用符は省略できます。

select_command

SELECT文。

使用上の注意

host_stringまたはtextの変数はすべてプレースホルダです。実際のホスト変数名は、OPEN文のUSING句(入力ホスト変数)またはFETCH文のINTO句(出力ホスト変数)で割り当てます。

SQL文は一度準備すると、何回でも実行できます。

例

この例では、Pro*COBOL埋込みSQLプログラムでPREPARE文を使用する方法を示します。

EXEC SQL PREPARE MYSTATEMENT FROM :MY-STRING END-EXEC.
EXEC SQL EXECUTE MYSTATEMENT END-EXEC.

関連項目

CLOSE (実行可能埋込みSQL)。

DECLARE CURSOR (埋込みSQLディレクティブ)。

FETCH (実行可能埋込みSQL)。

OPEN (実行可能埋込みSQL)。

ROLLBACK (実行可能埋込みSQL)

用途

カレント・トランザクションで実行した作業を取り消します。この文は、インダウトの分散トランザクションの処理を手動で取り消すときにも使用できます。

前提条件

カレント・トランザクションをロールバックするには、権限は必要ありません。

ユーザーがコミットしたインダウトの分散トランザクションを手動でロールバックするには、FORCE TRANSACTIONのシステム権限が必要です。他のユーザーがコミットしたインダウトの分散トランザクションを手動でロールバックするには、FORCE ANY TRANSACTIONのシステム権限が必要です。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

db_name

CONNECT文で先に設定されるデータベース接続名を含むNULL終了文字列。省略した場合または空文字の場合は、デフォルトのデータベース接続とみなされます。

host_variable

データベース接続名を格納するホスト変数。

この句を省略した場合、セーブポイントはデフォルトのデータベースに対して作成されます。

WORK

オプションで、ANSIとの互換性のために用意されています。

TO

指定したセーブポイントまでカレント・トランザクションをロールバックします。この句を省略した場合、ROLLBACK文はトランザクション全体をロールバックします。

FORCE

インダウトの分散トランザクションを手動でロールバックします。ローカルまたはグローバル・トランザクションIDを格納するtextによりトランザクションを指定します。このようなトランザクションのIDを検索するには、データ・ディクショナリ・ビューDBA_2PC_PENDINGに問合せをします。
ROLLBACK文でのFORCE句の使用はPL/SQLではサポートされていません。

RELEASE

リソースをすべて解放し、アプリケーションをデータベース・サーバーから切断します。RELEASE句は、SAVEPOINT句およびFORCE句とは併用できません。

savepoint

ロールバックするためのセーブポイントの名前。

使用上の注意

トランザクション(または論理作業単位)は、Oracleが1つの単位として扱う一連のSQL文です。トランザクションは、COMMIT文、ROLLBACK文またはデータベースへの接続後の、最初の実行SQL文から始まります。トランザクションは、COMMIT文、ROLLBACK文またはデータベースからの切断(意図的かどうかに関係なく)で終了します。Oracleは、データ定義言語文の処理前および処理後に暗黙的COMMIT文を発行します。

TO SAVEPOINT句を指定せずにROLLBACK文を使用すると、次の処理が実行されます。

- トランザクションを終了します。

- カレント・トランザクションの変更内容がすべて取り消されます。

- トランザクションのセーブポイントがすべて消去されます。

- トランザクションのロックを解除します。

TO SAVEPOINT句を指定してROLLBACK文を使用すると、次の処理が実行されます。

- トランザクションのセーブポイント後の部分のみロールバックされます。

- 指定したセーブポイントの後に作成したセーブポイントがすべて消去されます。指定したセーブポイントは保持されるため、そのセーブポイントに複数回ロールバックできます。それ以前のセーブポイントも保持されます。

- 指定したセーブポイント後に取得した表および行のロックがすべて解除されます。セーブポイント後にロックされた行へのアクセスを要求した他のトランザクションは、コミットまたはロールバックされるまで待機する必要があります。行をまだ要求していない他のトランザクションは、ただちに行を要求し、アクセスできます。

アプリケーション・プログラムでは、COMMIT文またはROLLBACK文を使用してトランザクションを明示的に終了することをお薦めします。トランザクションを明示的にコミットしなかった場合にプログラムが異常終了すると、Oracleはコミットされていない最後のトランザクションをロールバックします。

例I

次の文はカレント・トランザクション全体をロールバックします。

EXEC SQL ROLLBACK END-EXEC.

例II

次の文はカレント・トランザクションをセーブポイントSP5までロールバックします。

EXEC SQL ROLLBACK TO SAVEPOINT SP5 END-EXEC.

分散トランザクション

Oracleで分散オプションを使用すると、分散トランザクション、つまり複数のデータベースのデータを変更するトランザクションを実行できます。分散トランザクションをコミットまたはロールバックするには、他のトランザクションと同じようにCOMMIT文またはROLLBACK文を発行するだけで済みます。

分散トランザクションのコミット・プロセス中にネットワーク障害が発生すると、トランザクションの状態が不明、つまりインダウトになる可能性があります。そのトランザクションに関連する他のデータベースの管理者に問い合せて、ローカル・データベースのトランザクションを手動でコミットするか、ロールバックするかを決定できます。ローカル・データベースのトランザクションを手動でロールバックするには、FORCE句を指定してROLLBACK文を発行します。

インダウトのトランザクションを手動でセーブポイントまでロールバックすることはできません。

FORCE句を指定したROLLBACK文は、指定したトランザクションのみロールバックします。このような文は、カレント・トランザクションには影響しません。

例III

次の文はインダウトの分散トランザクションを手動でロールバックします。

EXEC SQL ROLLBACK WORK FORCE '25.32.87' END-EXEC.

関連項目

COMMIT (実行可能埋込みSQL)。

SAVEPOINT (実行可能埋込みSQL)。

SAVEPOINT (実行可能埋込みSQL)

用途

後でロールバックする位置をトランザクション内に指定します。

前提条件

なし。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

AT

セーブポイントをどのデータベースに対して作成するかを指定します。次のいずれかを使用してデータベースを指定します。

db_name

すでにDECLARE DATABASE文で宣言されているデータベース識別子。

host_variable

すでに宣言されているdb_name値のホスト変数。この句を省略した場合、セーブポイントはデフォルトのデータベースに対して作成されます。

savepoint

作成するセーブポイントの名前。

使用上の注意

この文の詳細は、「SAVEPOINT文の使用」を参照してください。

例

この例では、埋込みSQLのSAVEPOINT文の使用方法を示します。

EXEC SQL SAVEPOINT SAVE3 END-EXEC.

関連項目

COMMIT (実行可能埋込みSQL)。

ROLLBACK (実行可能埋込みSQL)。

SELECT (実行可能埋込みSQL)

用途

選択した値をホスト変数に割り当てて、1つ以上の表、ビューまたはスナップショットからデータを取り出します。

前提条件

機能47829-1 - 新しいREAD権限
表またはスナップショットからデータを選択するには、表またはスナップショットが自分のスキーマ内にあるか、あるいは表またはスナップショットに対してREADまたはSELECTの権限を持つ必要があります。

ビューの実表から行を選択するには、ビューが属するスキーマの所有者が、実表に対してREADまたはSELECTの権限を持っている必要があります。また、ビューが自分以外のスキーマにある場合は、そのビューに対するREADまたはSELECT権限が必要です。

READ ANY TABLEまたはSELECT ANY TABLEシステム権限を使用すると、すべての表、スナップショットまたはビューの実表からデータを選択できます。

READ権限は、SELECT ... FOR UPDATE操作には使用できません。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

AT

どのデータベースに対してSELECT文を発行するかを指定します。次のいずれかを使用してデータベースを指定します。

db_name

すでにDECLARE DATABASE文で宣言されているデータベース識別子。

host_variable

すでに宣言されているdb_name値のホスト変数。

この句を省略した場合、SELECT文はデフォルトのデータベースに対して発行されます。

select_list

非埋込みSELECT文と同じですが、リテラルのかわりにホスト変数を使用できます。

INTO

SELECT文が戻すデータを受け取る出力ホスト変数とオプションの標識変数を指定します。これらの変数は、すべてスカラーか、すべて配列である必要があります。ただし、配列は同じサイズでなくてもかまいません。

WHERE

戻される行を、条件がTRUEの行のみに制限します。『Oracle Database SQL言語リファレンス』のconditionの構文説明を参照してください。conditionには、ホスト変数は使用できますが、標識変数は使用できません。これらのホスト変数はスカラーである必要があり、配列は使用できません。

その他のキーワードおよびパラメータは、非埋込みSQLのSELECT文と同じです。

使用上の注意

WHERE句の条件を満たす行が存在しない場合、行は取り出されず、OracleはSQLCAのSQLCODEコンポーネントを使用してエラー・コードを戻します。

SELECT文ではコメントを使用して指示またはヒントをOracleのオプティマイザに渡すことができます。オプティマイザはヒントを使用して文の実行計画を選択します。ヒントの詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください。

例

この例では、埋込みSQLのSELECT文の使用方法を示します。

EXEC SQL SELECT ENAME, SAL + 100, JOB
INTO :ENAME, :SAL, :JOB
FROM EMP
WHERE EMPNO = :EMPNO
END-EXEC.

関連項目

DECLARE CURSOR (埋込みSQLディレクティブ)。

DECLARE DATABASE (Oracle埋込みSQLディレクティブ)。

EXECUTE (実行可能埋込みSQL)。

FETCH (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)。

SET DESCRIPTOR (実行可能埋込みSQL)

用途

ANSI動的SQL文を使用して、ホスト変数の記述子領域内の情報を設定します。

前提条件

DESCRIBE DESCRIPTORの後で使用します。

構文

item_nameのみ次の中から選択できます。

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

array_size
integer

処理される行の数を格納するホスト変数。
処理される行数。配列サイズの句は、DATA、RETURNED_LENGTHおよびINDICATORの項目名でのみ使用できます。

GLOBAL | LOCAL

LOCAL (デフォルト)はファイルのスコープで、GLOBALはアプリケーションのスコープです。

descriptor_name
'descriptor name'

割り当てられたANSI記述子名を格納するホスト変数。
割り当てられたANSI記述子の名前。

COUNT

入力および出力変数の合計数です。

VALUE

文中で参照されるホスト変数の位置です。

item_name

item_namesのリストおよび説明は、表10-6および表10-7を参照してください。

host_var

入力および出力変数の合計数を格納するホスト変数。

integer

入力および出力変数の合計数。

host_var

項目の設定に使用するホスト変数。

REF

参照セマンティクスが使用されます。RETURNED_LENGTH、DATAおよびINDICATORの項目名以外では使用できません。
RETURNED_LENGTHを設定するときに使用する必要があります。

使用上の注意

DYNAMIC=ANSIプリコンパイラ・オプションを使用してください。クライアント側でUnicodeをサポートするには、CHARACTER_SET_NAMEにUTF16を設定します。記述子項目名の表などの詳細は、「SET DESCRIPTOR」を参照してください。

例

EXEC SQL SET DESCRIPTOR GLOBAL :mydescr COUNT = 3 END-EXEC.

関連項目

ALLOCATE DESCRIPTOR (実行可能埋込みSQL)。

DEALLOCATE DESCRIPTOR (埋込みSQL文)。

DESCRIBE DESCRIPTOR (実行可能埋込みSQL)。

GET DESCRIPTOR (実行可能埋込みSQL)。

PREPARE (実行可能埋込みSQL)。

UPDATE (実行可能埋込みSQL)

用途

表またはビューの実表の既存の値を変更します。

前提条件

表またはスナップショットの値を更新するには、表がユーザーのスキーマ内にあるか、または表に対してUPDATEの権限を持っている必要があります。

ビューの実表の値を更新するには、ビューが属するスキーマの所有者が、実表に対してUPDATEの権限を持っている必要があります。また、ビューがユーザーのスキーマ以外のスキーマ内にある場合は、ビューに対してUPDATEの権限を持っている必要があります。

UPDATE ANY TABLEシステム権限を使用すると、すべての表またはビューの実表の値を更新できます。

構文

DML RETURNING句の構文を示します。

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

AT

どのデータベースに対してUPDATE文を発行するかを指定します。次のいずれかを使用してデータベースを指定します。

dbname

すでにDECLARE DATABASE文で宣言されているデータベース識別子。

host_variable

すでに宣言されているdbname値のホスト変数。

-

この句を省略した場合、UPDATE文はデフォルトのデータベースに対して発行されます。

FOR: host_integer

SET句およびWHERE句が配列ホスト変数を含む場合に、UPDATE文を実行する回数を制限します。この句を省略した場合、Oracleは最小の配列の各コンポーネントにつき1回ずつ文が実行されます。

schema

表またはビューを含むスキーマ。schemaを省略した場合、Oracleは表またはビューがユーザーのスキーマ内にあるとみなします。

table view

更新する表の名前。viewを指定する場合、Oracleではビューのベース表を更新します。

dblink

表またはビューがあるリモート・データベースへのデータベース・リンクの完全名または部分名。データベース・リンクの参照の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。データベース・リンクを使用してリモートの表またはビューを更新できるのは、Oracleで分散オプションを使用している場合のみです。

part_name

表内のパーティションの名前。

alias

文の他の場所にある表、ビューまたは副問合せを参照するのに使用する名前です。

column

表またはビューで更新する列の名前。SET句から表の列を削除する場合、その列の値は変更されません。

expr

対応する列に割り当てる新しい値。この式には、ホスト変数およびオプションの標識変数を含めることができます。『Oracle Database SQL言語リファレンス』のexprの構文を参照してください。

subquery_1

対応する列に割り当てられた新しい値を戻す副問合せ。副問合せの構文は、『Oracle Database SQL言語リファレンス』のSELECTに関する項を参照してください。

subquery_2

対応する列に割り当てられた新しい値を戻す副問合せ。副問合せの構文は、『Oracle Database SQL言語リファレンス』のSELECTに関する項を参照してください。

WHERE

表またはビューで更新する行を指定します。

-

condition

-

CURRENT OF

-

この句を完全に省略した場合、Oracleは表またはビューのすべての行を更新します。

DML RETURNING句

詳細は、「DML RETURNING句」を参照してください。

使用上の注意

SET句およびWHERE句に含まれるホスト変数は、すべてスカラーか、またはすべて配列であることが必要です。変数がスカラーの場合、OracleはUPDATE文を1回のみ実行します。変数が配列の場合、Oracleは配列のコンポーネント・セットごとに1回ずつこの文を実行します。1回の実行で、0行または1行、複数行を更新できます。

配列ホスト変数は、サイズが異なってもかまいません。この場合、Oracleが文を実行する回数は、値の小さい方によって決定します。

次の値を比較します。

- 最小の配列のサイズ

- オプションのFOR句のhost_integerの値

更新された行の累積数は、SQLCAのSQLERRDコンポーネントの第3要素に設定されて戻されます。入力ホスト変数として配列を使用した場合、この数値はUPDATE文で処理された配列のすべてのコンポーネントにおよぶ更新数の合計を示します。この条件を満たす行が存在しない場合、行は更新されず、OracleはSQLCAのSQLCODE要素を通じてエラー・メッセージを戻します。WHERE句を省略した場合は、すべての行が更新され、OracleはSQLCAのSQLWARN要素の第5コンポーネントに警告フラグを設定します。

UPDATE文ではコメントを使用して指示またはヒントをOracleのオプティマイザに渡すことができます。オプティマイザはヒントを使用して文の実行計画を選択します。ヒントの詳細は、『Oracle Databaseパフォーマンス・チューニング・ガイド』を参照してください。

この文の詳細は、「基本的なSQL文」および第3章「データベースの概念」を参照してください。

例

次の例では、埋込みSQLのUPDATE文の使用方法を示します。

EXEC SQL UPDATE EMP
SET SAL = :SAL, COMM = :COMM INDICATOR :COMM-IND
WHERE ENAME = :ENAME
END-EXEC.

EXEC SQL UPDATE EMP
SET (SAL, COMM) =
(SELECT AVG(SAL)*1.1, AVG(COMM)*1.1
FROM EMP)
WHERE ENAME = 'JONES'
END-EXEC.

関連項目

DECLARE DATABASE (Oracle埋込みSQLディレクティブ)。

VAR (Oracle埋込みSQLディレクティブ)

用途

ホスト変数の同値化を実行するか、特定のOracle外部データ型をこのホスト変数に割り当て、デフォルトのデータ型割当てをオーバーライドします。また、オプションのCONVBUFSZ句を使用して、キャラクタ・セット変換用のバッファ・サイズを指定します。

前提条件

ホスト変数は、埋込みSQLプログラム内であらかじめ宣言しておく必要があります。

構文

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

host_variable

Oracleの外部データ型を割り当てるホスト変数。

dtyp

Pro*COBOLによって認識されるOracleの外部データ型(Oracleの内部データ型ではありません)。データ型には、長さ、精度または位取りを含めることができます。この外部データ型がhost_variableに割り当てられます。外部データ型のリストは、「外部データ型」を参照してください。

size

Oracleランタイム・ライブラリ内のバッファのサイズ(バイト単位)です。これを使用して、host_variableのキャラクタ・セットを変換します。

使用上の注意

データ型の同値化は次の目的に有効です。

- プログラム・データをバイナリ・データとしてデータベースに格納します。

- デフォルトのデータ型のかわりに使用します。

Oracleデータ型の詳細は、「サンプル・プログラム4: データ型の同値化」を参照してください。

例

この例では、ホスト変数DEPT_NAMEをデータ型VARCHAR2に、ホスト変数BUFFERをデータ型RAW(200)に同値化しています。

EXEC SQL BEGIN DECLARE SECTION END-EXEC.
...
01 DEPT-NAME  PIC X(15).
* -- default datatype is CHAR
EXEC SQL VAR DEPT-NAME IS VARCHAR2 END-EXEC.
* -- reset to STRING
...
01 BUFFER-VAR.
05 BUFFER  PIC X(200).
* -- default datatype is CHAR
EXEC SQL VAR BUFFER IS RAW(200) END-EXEC.
* -- refer to RAW
...
EXEC SQL END DECLARE SECTION END-EXEC.

関連項目

なし。

WHENEVER (埋込みSQLディレクティブ)

用途

埋込みSQLプログラムの実行時に、エラーまたは警告が発生した場合の処置を指定します。

前提条件

なし。

構文

DO.CALL.CLAUSEの構文を次に示します。

キーワードおよびパラメータ

キーワードおよびパラメータ

説明

NOT FOUND | NOTFOUND

エラー・コード+1403 (または、MODE=ANSIのときは+100コード)をSQLCODEに戻す例外状態を示します。

SQLERROR

負のリターン・コードを戻す状態を示します。

SQLWARNING

致命的でない警告状態を示します。

CONTINUE

プログラムが次の文に進む必要があることを指示します。

GOTO | GO TO

プログラムにlabelで指定した文に分岐するように指示します。

STOP

プログラムの実行を停止します。

DO PERFORM

プログラムがlabelで指定した段落または項を実行する必要があることを示します。

DO CALL

プログラムがサブプログラムを実行する必要があることを示します。

subprogram_name

実行するサブプログラムです。二重引用符(")で囲む必要があります。

USING

サブプログラムのパラメータです。

param

空白で区切られたサブプログラム・パラメータのリストです。

WHENEVERディレクティブを使用すると、埋込みSQL文でエラーまたは警告が発生したときに、プログラムから指定したアクションの1つを実行できます。

WHENEVER文のスコープは論理的にではなく、位置的に適用されます。WHENEVER文は、プログラム論理の流れではなく、ソース・ファイル内で物理的に後続するすべての埋込みSQL文に適用されます。WHENEVER文は、同じ条件をチェックする別のWHENEVER文に置換されるまで有効です。

このディレクティブの条件およびアクションの例は、「WHENEVERディレクティブ」を参照してください。

埋込みSQLのWHENEVERディレクティブとSQL*PlusコマンドのWHENEVERディレクティブを混同しないでください。

例

次の例では、Pro*COBOL埋込みSQLプログラムでWHENEVERディレクティブを使用する方法を示します。

EXEC SQL WHENEVER NOT FOUND CONTINUE END-EXEC.
...
EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC.
...
SQL-ERROR.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
DISPLAY "ORACLE ERROR DETECTED.".
EXEC SQL ROLLBACK RELEASE END-EXEC.
STOP RUN.

関連項目

なし

F Pro*COBOL for Windows

この項では、Windowsオペレーティング・システム用のPro*COBOLを使用したOracle Databaseアプリケーション作成の概要について説明します。

この項の内容は、次のとおりです。

- Pro*COBOLアプリケーションのコンパイルおよびリンク

- サンプル・プログラム

Pro*COBOLアプリケーションのコンパイルおよびリンク

Pro*COBOLは、Windowsの32-bit版対応のMicro Focus Net Express 5.0をサポートしています。この項では、Micro Focusコンパイラを使用したPro*COBOLアプリケーションのコンパイルおよびリンク方法を説明します。

Micro Focus COBOLアプリケーションを作成および実行するには、次の2つの方法があります。

- IDEの使用方法(Net Expressのみを使用)

- Animatorの使用方法(Net Express以外の製品)

- COBOLおよびCBLLINKコマンド(すべての製品)

- COBSQLコマンド

いずれの場合も、次の利点からCOBSQLユーティリティが使用される場合があります。

- Pro*COBOLはMicro Focusコンパイラで実行され、別の処理として実行する必要はありません。

- アニメーションは、Pro*COBOLによって生成された.cblファイルではなく.pcoソース・ファイルを使用して行われます。

- MAKEYSYNディレクティブは、自動的に指定され、手動で指定する必要はありません。

IDEの使用方法

Pro*COBOLによって生成されたプログラムは、Micro Focus Net ExpressのIDEからコンパイルおよび実行できます。Pro*COBOLによって生成された.cblファイルをNet Expressプロジェクトに追加します。Oracleライブラリのルーチンをコールするときに矛盾が生じないように、次のディレクティブを使用してプログラムをコンパイルします。

MAKESYN "COMP-5" = "COMP"

このディレクティブは、ソース・ファイル作成の設定またはプロジェクト設定で、あるいはソース・ファイルの先頭の$SET行で指定できます。「Rebuild」または「Rebuild All」を選択すると、IDEによって「Run」または「Animate」が使用できる実行可能ファイルが生成されます。

Animatorの使用方法

Micro Focus COBOLのデバッガであるAnimator V2を使用して、プログラムをコンパイルおよび実行できます。

Oracleライブラリのルーチンをコールするときに矛盾が生じないように、メニュー・オプションの「Compiler Directives」を選択し、次のように入力します。

Micro Focus COBOLでは、2進数がビッグ・エンディアン形式で格納されるので、この手順が必要です。Oracleライブラリでは、2進数はリトル・エンディアン形式(マシン形式)で格納されていることを前提としています。

MAKESYN "COMP-5" = "COMP"

COBOLおよびCBLLINKコマンド

プログラムを作成する場合、COBOLおよびCBLLINKは、Pro*COBOLランタイムが静的にリンクされるか、実行時にDLLを通してアクセスされるかによって2通りの方法で使用されます。

動的リンクの場合のコマンドは次のとおりです。

COBOL sample1 /MAKESYN"COMP-5"="COMP";
CBLLINK sample1

静的リンクの場合のコマンドは次のとおりです。

COBOL sample1 /LITLINK /MAKESYN"COMP-5"="COMP";
CBLLINK sample1 ORACLE_BASE\ORACLE_HOME\precomp\lib\orasql12.lib

前述のコマンドによりsample1.exeが作成されます。このファイルは、他のWindowsプログラムと同様に実行できます。

注意:
ファイルを正常に実行するには、Pro*COBOLと同じシステムにMicro Focus COBOLがインストールされている必要があります。

COBSQLコマンド

COBSQLを使用すると、前処理およびデバッグが簡単にできます。COBSQLを使用するには、COBOLコンパイラに次のディレクティブを指定します。

PREPROCESS(COBSQL) COBSQLTYPE=ORACLE8 ENDP

または次の短い形式を使用します。

P(COBSQL) CSQLT=ORA8 ENDP

リリース8.0より前のPro*COBOLの場合、COBSQLTYPEはORACLEまたはORAに設定します。ディレクティブは、ソース・ファイルの先頭の$SET行、COBOLのコマンドライン、Net Expressのプログラム作成の設定またはプロジェクト設定か、AnimatorのSQLコンパイラ・ディレクティブ設定によって設定できます。コンパイル時に、COBSQLではPro*COBOLをバックグラウンド・タスクとして実行し、Animatorで.cblファイルではなく.pcoファイルを使用して実行を追跡できるよう、必要な追加情報と一緒にその出力がCOBOLコンパイラに渡されます。

COBSQLを使用している場合、.cblファイルを直接処理する必要はありません。かわりに、.pcoファイルをNet Expressプロジェクトに追加するか、Animatorで開きます。

サンプル・プログラム

Oracle Databaseの機能でPro*COBOLを使用する方法を示すためにサンプル・プログラムが提供されています。これらのプログラムのリストは、「サンプル・ファイル」を参照してください。

この項では、サンプル・プログラムをビルドするための基本的なプリコンパイル、コンパイルおよびリンクのコマンドの使用方法を説明します。また、Pro*COBOLのサンプル・プログラムの実行に必要な準備についても説明します。

デモ表の作成

Pro*COBOLのサンプル・プログラムを実行するには、ユーザー名がscottでパスワードがtigerのデータベース・アカウントが必要です。データベースにこのアカウントがない場合は、アカウントを作成してからサンプル・プログラムを実行してください。

scottアカウントには、emp表およびdept表が含まれている必要があります。アカウントにこれらの表がない場合は、demobld.sqlスクリプトを使用して作成してください。

demobld.sqlスクリプトを実行するには、次のようにします。

1. SQL*Plusを起動します。

2. ユーザー名scott、パスワードtigerでデータベースに接続します。

3. demobld.sqlスクリプトを実行します。次に例を示します。

SQL> @ORACLE_BASE\ORACLE_HOME\sqlplus\demo\demobld.sql

サンプル・プログラムのビルド

Pro*COBOLでは、Micro Focus COBOLのサンプル・ファイルのビルド用に次の項で説明するmakeit.batファイルが提供されます。

バッチ・ファイルはORACLE_BASE\ORACLE_HOME \precomp\demo\procob2にあります。

サンプル・プログラムをビルドするには、次のようにします。

1. 任意のサンプル・ファイルでバッチ・ファイルを実行します。ファイル拡張子は入力しないでください。次に例を示します。

C:\ORACLE\ORA90\PRECOMP\DEMO\PROCOB2> makeit sample1

2. サンプル・プログラムをビルドしているときにエラーが発生した場合は、すべてのパスおよびファイル名がシステム構成と一致しているかを確認してください。

サンプル・プログラムを実行するコマンドは、次のディレクトリが現行の作業ディレクトリであると想定します。

ORACLE_BASE\ORACLE_HOME \precomp\demo\procob2

システム構成に合せてサンプル・リンク・スクリプトの変更が必要な場合があります。詳細は、「Pro*COBOLアプリケーションのコンパイルおよびリンク」を参照してください。

makeit.batには、次の内容が含まれています。

procob iname=%1.pco ireclen=132
cobol %1 /anim /litlink makesyn "COMP-5" = "COMP";
cbllink %1 /M%1 ORACLE_BASE\ORACLE_HOME\precomp\lib\orasql12.lib

サンプル・ファイル

表F-1にリストされているPro*COBOLのサンプル・ファイルは、ORACLE_BASE\ORACLE_HOME\precomp\demo\procob2ディレクトリにあります。SQLスクリプトは、ORACLE_BASE\ORACLE_HOME\precomp\demo\sqlディレクトリにあります。

表F-1 Pro*COBOLのサンプル・プログラム

サンプル・プログラム

説明

sample1.pco

単純な問合せ

sample2.pco

カーソル操作

sample3.pco

ホスト表

sample4.pco

データ型の同値化

sample6.pco

動的SQL方法1

sample7.pco

動的SQL方法2

sample8.pco

動的SQL方法3

sample9.pco

ストアド・プロシージャ・コール

calldemo.sql

ストアド・プロシージャ・コール

sample10.pco

動的SQL方法4

sample11.pco

カーソル変数操作

sample11.sql

カーソル変数操作

sample12.pco

ANSI動的SQLを使用する動的SQL方法4

sample13.pco

ネストされたプログラム

sampleco.pco

単純な問合せおよび挿入

sample14.pco

ホスト表x

lobdemo1.pco

LOBデータ型

lobdemo1.sql

LOBデータ型

索引
A B C D E F G H I J L M N O P Q R S T U V W X

A

略称の制限, 2.2.1

異常終了

自動ロールバック, E.8

アクティブ・セット, 5.4

変更, 5.4.2, 5.4.3

定義, 5.4

空の場合, 5.4.3

ALLOCATE DESCRIPTOR文, E.5 ALLOCATE文, E.4

ROWIDで使用, 4.7

割当て

カーソル, E.4

スレッド・コンテキスト, 12.4.2.3, E.10

カーソル変数の割当て, 6.10.2 ALTER AUTHORIZATION

パスワードの変更, 3.2.4

ANSI動的SQL, F.2.3

「動的SQL (ANSI)」も参照, 10

ANSI書式

COBOL文, 2.2.4

ANSI/ISO SQL

拡張, 14.7.18

アプリケーション開発過程, 2.1.1 ARRAYLEN文, 6.6.1 ASACCプリコンパイラ・オプション, 14.7.1 ASSUME_SQLCODEプリコンパイラ・オプション, 14.7.2 AT句

CONNECT文, 3.2.2.1

DECLARE CURSOR文, 3.2.2.1

DECLARE STATEMENT文, 3.2.2.1

EXECUTE IMMEDIATE文3.2.2.1

COMMIT文, E.8

CONNECT文, E.9

DECLARE CURSORディレクティブE.14

DECLARE STATEMENTディレクティブ, E.16

EXECUTE IMMEDIATE文, E.25

EXECUTE文, E.22

INSERT文, E.30

SAVEPOINT文, E.53

SELECT文, E.54

UPDATE文, E.56

制限, 3.2.2.1

AUTO_CONNECTオプション

CONNECT文の代用, 3.2.3.1

AUTO_CONNECTプリコンパイラ・オプション, 14.7.3 自動ログイン, 3.2.2, 3.2.3 不要な再解析の回避, C.10

B

バッチ・フェッチ, 7.4.1

例, 7.4.1

戻される行の数, 7.4.3

BFILE

定義, 13.1.2

バインド記述子, 11.2.1 バインド記述子

情報, 9.13.2

バインドSQLDA, 11.1.3 バインド変数, 9.13.1 ホスト変数のバインド, 9.5 BNDDFCLP変数(SQLDA), 11.3 BNDDFCRCP変数(SQLDA), 11.3 BNDDFMT変数(SQLDA), 11.3 BNDDH-CUR-VNAMEL変数(SQLDA), 11.3 BNDDH-MAX-VNAMEL変数(SQLDA), 11.3 BNDDH-VNAME変数(SQLDA), 11.3 BNDDI変数(SQLDA), 11.3 BNDDI-CUR-VNAMEL変数(SQLDA), 11.3 BNDDI-MAX-VNAMEL変数(SQLDA), 11.3 BNDDI-VNAME変数(SQLDA), 11.3 BNDDV変数(SQLDA), 11.3 BNDDVLN変数(SQLDA), 11.3 BNDDVTYP変数(SQLDA), 11.3

C

CALL SQL文, 6.8.2.2

CALL文, E.6

例, 6.8.2.3

文字の大小区別なし, 2.2.2 CHARデータ型

外部, 4.1.2.1

文字ホスト変数

出力変数, 4.6.3.2

処理, 4.6

サーバー処理, 4.6.3.2

タイプ, 4.6

キャラクタ・セット

マルチバイト, 4.9

文字列

マルチバイト, 4.9.2

CHARFデータ型指定子, 4.12.3

VAR文で使用, 4.12.3, 4.12.3

CHARFデータ型

外部, 4.1.2.2

CHARZデータ型

外部, 4.1.2.3

CLOSEコマンド

例, E.7

CLOSE文, E.7

例, 5.4.4

動的SQL方法4, 11.6.17

CLOSE_ON_COMMIT

プリコンパイラ・オプション, 3.6.2, 5.4.1

CLOSE_ON_COMMITプリコンパイラ・オプション, 14.7.6 クローズ

カーソル, E.7

サポートされるCOBOLのバージョン, 2.2.3, A.1.1 COBOL-74, A.1.1 COBOL-85, A.1.1 COBSQL, F.1.4 コード・ページ, 4.8 コーディング領域

段落の名前, 2.2.22

コーディング規則, 2.2 列リスト, 5.3.3 COMMENT句

COMMIT文, E.8

コメント

ANSI SQLスタイル, 2.2.6

Cスタイル, 2.2.6

埋込みSQL文, 2.2.6

埋込みSQL, 2.2.6

動的PL/SQLブロックのコメント, 9.16.5 コミット, 3.4

自動, 3.5

明示的と暗黙的の比較, 3.5

COMMIT文, 3.6, E.8

影響, 3.6

トランザクションの終了, E.52

例, 3.6

例, E.8

RELEASEオプション, 3.6

PL/SQLブロックで使用, 3.14.3

配置位置, 3.6

コミットする

トランザクション, E.8

COMP_CHARSETプリコンパイラ・オプション, 14.7.7 コンパイル, 2.7 複合型, 11.4.3 同時実行性, 3.3 同時ログイン, 3.2.1 条件付きプリコンパイル, 2.5

記号の定義, 2.5.2

例, 2.5.1

CONFIGプリコンパイラ・オプション, 14.7.6, 14.7.8 構成ファイル

システムとユーザーの比較, 14.7.8

CONNECT文, E.9

AT句, 3.2.2.1

意味検査を使用可能にする, D.3.1.1

例, E.9

Oracleにログイン, 3.1

配置, 3.1

要件, 3.1

USING句, 3.2.2.1

必須でない場合, 3.2.3.1

Oracleへの接続, 3.1

自動的, 3.2.3

同時, 3.2.1

例, 3.1

Oracle Net Servicesを介した, 3.2.1

接続

デフォルトと非デフォルトの比較, 3.2.1

暗黙的, 3.2.6

命名, 3.2.2

CONTEXT ALLOCATE文, 12.4.2.3, E.10, E.10 CONTEXT FREE文, 12.4.2.5, E.11 CONTEXT USEディレクティブ, 12.4.2.4 CONTEXT USE SQLディレクティブ, E.12 CONTEXT USE SQL文, 12.4.2.4 行の継続

構文, 2.2.7

CONTINUEアクション

WHENEVERディレクティブ, 8.3.8.6, 8.3.8.6, E.58

VAR文のCONVBUFSZ句, 4.12.2.1 CREATE PROCEDURE文, 6.8.1 作成

セーブポイント, E.53

CURRENT OF句, 5.4.5, 7.3.5

例, 5.4.5

ROWIDで擬似実行, 3.12, 7.11

制限, 5.4.6

カレント行, 5.4 CURRVAL擬似例, 4.1.2.23 カーソル・キャッシュ, 8.4.4

統計情報の収集, 8.4.5.11

用途, 8.4, C.9.2.1

カーソル変数, 6.10, E.4

利点, 6.10

割当て, 6.10.2

クローズ, 6.10.5

宣言, 6.10.1

フェッチ, 6.10.4

ヒープ・メモリーの使用, 6.10.2

オープン

無名ブロック, 6.10.3.2

ストアド・プロシージャ, 6.10.3.1

制限, 6.10.7 スコープ, 6.10.1 カーソル, 5.4

割当て, E.4

問合せとの関連付け, 5.4

クローズ, E.7

宣言, 5.4.1

パフォーマンスへの影響, C.9.1

明示的と暗黙的の比較, 5.4

行をフェッチする, E.26, E.27

命名, 5.4.1

オープン, E.49, E.50

再オープン, 5.4.2, 5.4.3

制限されたスコープ, 2.6.2

制限, 5.4.1

スコープ, 5.4.1

複数行の問合せに使用, 5.4

複数使用, 5.4.1

自動的にクローズする場合, 5.4.4

D

データ定義言語(DDL)

説明, 5.1.1

埋込み, 14.7.35

データの整合性, 3.3 データ・ロック, 3.3 データベース・リンク

DELETE文で使用, E.18

INSERT文で使用, E.30

UPDATE文で使用, E.56

データ型

内部対外部, 2.1.7

データ型変換

内部型と外部型間, 4.11

データ型の同値化

利点, 4.12.1

例, 4.12.2.2

ガイドライン, 4.12.4

データ型

ANSI DATE, 4.2

NUMBERをVARCHAR2に強制変換する, 11.4.3

変換, 4.10

Oracle内部からの処理, 11.4.3

記述子コード, 11.4.3

同値化

説明, 4.12

例, 4.12.2

内部, 11.4.2 INTERVAL DAY TO SECOND,4.2 INTERVAL YEAR TO MONTH,4.2 強制変換が必要, 11.4.3 同等のPL/SQL, 11.4.3 TIMESTAMP, 4.2 TIMESTAMP WITH LOCAL TIME ZONE,4.2 TIMESTAMP WITH TIME ZONE,4.2 リセットするとき, 11.4.3 DATEデータ型

変換, 4.11

デフォルトの書式, 4.11

DATE文字列フォーマット

明示的に制御, 4.11

DATE,ANSI

データ型, 4.2

DATE_FORMATプリコンパイラ・オプション, 14.7.9 DBMSプリコンパイラ・オプション, 14.7.10, 14.7.11 DDL (データ定義言語), 14.7.35 DDL (データ定義言語), 5.1.1 デッドロック, 3.3

トランザクションでの影響, 3.7.1

解除方法, 3.7.1

DEALLOCATE DESCRIPTOR文, E.13 DECIMALデータ型, 4.1.2.5 宣言

カーソル, 5.4.1

ホスト変数, 2.1.6

宣言SQL文, 2.1.2.1

トランザクションでの使用, 3.5

宣言部

ディレクティブ(別称), 2.1.2.1

DECLARE CURSORディレクティブ, E.14

例, 5.4.1

例, E.14

DECLARE CURSOR文

AT句, 3.2.2.1

動的SQL方法4, 11.6.7

配置位置, 5.4.1

DECLARE DATABASEディレクティブ, E.15 宣言部

ユーザー名およびパスワードの定義, 3.1

宣言部

使用可能な文, 2.3.1

例, 2.3.1.1

用途, 2.3.1

要件, 2.3.1

定義規則, 2.3.1

複数使用, 2.3.2

DECLARE文

動的SQL方法3での使用, 9.11.2

DECLARE STATEMENTディレクティブ, E.16

例, E.16

スコープ, E.16

DECLARE STATEMENT文

AT句, 3.2.2.1

例, 9.14

動的SQLでの使用, 9.14

必要なとき, 9.14

DECLARE TABLEディレクティブ, E.17

例, E.17

DECLARE TABLEディレクティブ

SQLCHECKオプションを使用, D.3.1.2

DECLARE_SECTIONプリコンパイラ・オプション, 14.7.12 宣言

カーソル変数, 6.10.1

ホスト表, 7.3.1

標識変数, 4.4.2

ORACA, 8.4.2

SQLCA, 8.3.2

SQLDA, 11.2.3

VARCHAR変数, 4.5.1

デフォルト

エラー処理, 8.3.8

LITDELIMオプションの設定, 2.2.10, 14.7.26

ORACAオプションの設定, 8.4.3

デフォルトの接続, 3.2.1 DEFINEプリコンパイラ・オプション, 14.7.13 DELETE文, E.18

埋込みSQL例, E.18

例, 5.3.6

表の使用制限, 7.7.1

ホスト表の使用, 7.7

WHERE句, 5.3.6

DEPENDING ON句, 7.3.1.1 DEPT表, 2.8 DESCRIBE BIND VARIABLES文

動的SQL方法4, 11.6.8

DESCRIBE DESCRIPTOR文, E.20 DESCRIBE SELECT LIST文

動的SQL方法4, 11.6.12

DESCRIBE文, E.19

例, E.19

PREPARE文で使用, E.19

動的SQL方法4での使用, 9.13.1

記述子

命名, E.19

記述子

バインド記述子, 11.2.1

用途, 11.2.1

選択記述子, 11.2.1

SQLADRサブルーチン, 11.1.3

ホスト表のディメンション(次元), 7.3.1.1 ディレクティブ

宣言部(別称), 2.1.2.1

ディレクトリ・パス

INCLUDEファイル, 2.3.3.2

DISPLAYデータ型, 4.1.2.6 分散処理, 3.2.1 DML RETURNING句, 5.3.3, 5.3.3 DO CALLアクション

WHENEVERディレクティブ, 8.3.9.1, 8.3.9.2, E.58

DO PERFORMアクション

WHENEVERディレクティブ, 8.3.8.8, E.58

DSNTIAR

DB2互換機能, 8.3.7

DSNTIARルーチン, 8.3.7 DYNAMICオプション

機能への影響, 10.5

動的PL/SQL, 9.16 動的SQL

長所および短所, 9.2

適切な方法を選択, 9.6.5

ガイドライン, 9.6.5

概要, 2.1.4, 9.1

制限, 14.7.35

PL/SQLの使用, 6.8.3

AT句の使用, 3.2.2.1

使用方法, 9.3

動的SQL (ANSI), F.2.3

ALLOCATE DESCRIPTOR文, 10.6.1

基礎, 10.1

バルク操作, 10.4.2

CLOSE CURSOR文, 10.6.13

Oracle動的SQL方法4との比較, 10

DEALLOCATE DESCRIPTOR文, 10.6.2

DESCRIBE DESCRIPTOR文, 10.6.6

Oracle動的SQLとの違い, 10.6.14

EXECUTE文, 10.6.8

FETCH文, 10.6.12

GET DESCRIPTOR文, 10.6.3

OPEN文, 10.6.11

Oracle拡張機能, 10.4

概要, 10.2

プリコンパイラのオプション, 10.1.1, 10.5

参照セマンティクス, 10.4.1

制限, 10.6.15

サンプル・プログラム, 10.7

SAMPLE12.PCO, 10.7

SET DESCRIPTOR文, 10.6.4

DECLARE CURSORの使用, 10.6.10

EXECUTE IMMEDIATE文の使用, 10.6.9

PREPARE文の使用, 10.6.5

使用するとき, 10

動的SQL方法1

コマンド, 9.6.1

説明, 9.7.1

例, 9.7.2

要件, 9.6.1

EXECUTE IMMEDIATEの使用, 9.7.1

PL/SQLの使用, 9.16.1

動的SQL方法2

コマンド, 9.6.2

説明, 9.9

要件, 9.6.2

PL/SQLの使用,9.16.2

DECLARE STATEMENT文の使用, 9.14

EXECUTE文の使用, 9.9

PREPARE文の使用, 9.9

動的SQL方法3

コマンド, 9.6.3

方法2と比較, 9.11

要件, 9.6.3

PL/SQLの使用, 9.16.3

DECLARE文の使用, 9.11.2

DECLARE STATEMENT文の使用, 9.14

FETCH文の使用, 9.11.4

OPEN文の使用, 9.11.3

PREPARE文の使用, 9.11.1

動的SQL方法4

CLOSE文, 11.6.17

DECLARE CURSOR文, 11.6.7

DESCRIBE文, 11.6.8, 11.6.12

外部データ型, 11.4.2

FETCH文, 11.6.15

内部データ型, 11.4.2

OPEN文, 11.6.11

PREPARE文, 11.6.6

前提条件, 11.4

記述子の用途, 11.2.1

要件, 9.6.4, 11.1.1

使用された一連の文, 11.6

SQLDA, 11.2

ステップ, 11.5

記述子の使用, 9.13

PL/SQLの使用, 9.16.4

DECLARE STATEMENT文の使用, 9.14

DESCRIBE文の使用, 9.13.1

FOR句の使用, 9.15

SQLDAの使用9.13.1

必要なとき, 9.13

動的SQL文, 9.1

ホスト変数のバインド, 9.5

プロセス法, 9.5

要件, 9.4

ホスト表の使用, 9.15

対静的SQL文, 9.1

E

埋込みデータ定義言語(DDL), 14.7.35

埋込みPL/SQL

利点, 6.2.1

カーソルFORループ, 6.2.3

例, 6.4.1, 6.4.2

ホスト変数, 6.1.1

標識変数, 6.1.3

マルチバイト・グローバリゼーション・サポート機能, 4.9.1

SQLCHECKオプションに必要, 6.3

USERIDオプションに必要, 6.3

概要, 2.1.5

パッケージ, 6.2.5

PL/SQL表, 6.2.6

要件, 6.1

サブプログラム, 6.2.4

SQLをサポート, 2.1.5

ユーザー定義レコード, 6.2.7

%TYPEの使用, 6.2.2

VARCHAR擬似型の使用, 6.4.3

パフォーマンス向上のために使用, C.4

VARCHAR変数, 6.1.2

使用できる所, 6.1, 6.3

埋込みSQL

ALLOCATE DESCRIPTOR文, E.5

ALLOCATE文, 4.7, 6.10.2, E.4

CALL文, 6.8.2.2, E.6

CLOSE文, 5.4.4, 6.10.5, E.7

COMMIT文, E.8

CONNECT文, E.9

CONTEXT ALLOCATE文, 12.4.2.3, E.10

CONTEXT FREE文, 12.4.2.5, E.11

CONTEXT USEディレクティブ, E.12

DEALLOCATE DESCRIPTOR文, E.13

DECLARE CURSORディレクティブ, 5.4.1

DECLARE CURSORディレクティブ, E.14

DECLARE DATABASEディレクティブ, E.15

DECLARE STATEMENTディレクティブ, E.16

DECLARE TABLEディレクティブ, E.17

DELETE文, 5.3.6, E.18

DESCRIBE DESCRIPTOR文, E.20

DESCRIBE文, E.19

ENABLE THREADS文, 12.4.2.2

EXECUTE IMMEDIATE文, E.25

EXECUTE文, E.23

EXECUTE...END-EXEC文, E.22

FETCH DESCRIPTOR文, E.27

FETCH文, 5.4.3, 6.10.4, E.26, E.27

FREE文, 6.10.6, E.28

GET DESCRIPTOR文, E.29

INSERT文, 5.3.2, 7.5, E.30

基本概念, 2.1

OPEN DESCRIPTOR文, E.50

OPEN文, 5.4.2, E.49, E.49, E.50

PREPARE文, E.51

ROLLBACK文, E.52

SAVEPOINT文, 3.8, E.53

SELECT文, 5.3.1, 7.4, E.54

SET DESCRIPTOR文, E.55

SET TRANSACTION文, 3.10

UPDATE文, 5.3.5, E.56

VARディレクティブ, E.57

対話型SQLとの相違点, 2.1.3

使用するとき, 1.4

WHENEVERディレクティブ, E.58

埋込みSQL文

段落の名前を対応付ける, 2.2.22

コメント, 2.2.6

継続, 2.2.7

表意定数, 2.2.13

ホスト言語文と混合, 2.1.3

ホスト表の参照, 7.3.2

ホスト変数の参照, 4.3.2

標識変数の参照, 4.4.3

要件, 2.2.12

概要, E.1

構文, 2.1.3, 2.2.12

終了記号, 2.2.25

埋込み

Oracle7プリコンパイラ・プログラムのPL/SQLブロック, E.22

EMP表, 2.8 ENABLE THREADS SQL文, E.21 ENABLE THREADS文, 12.4.2.2 使用可能にする

スレッド, 12.4.2.2

コード体系, 4.8 END_OF_FETCHプリコンパイラ・オプション, 14.7.15, 14.7.15 同値化

ホスト変数の同値化, E.57

データ型の同値化, 4.12 エラー検出

エラー・レポート, E.58

エラー処理

代替手段, 8.2

利点, 8.1

デフォルト, 8.3.8

概要, 2.1.9

状態変数の使用

SQLCA, 8.2.1, 8.3

ROLLBACK文の使用, 3.7 SQLGLSルーチンの使用, 8.3.10 エラー・メッセージ・テキスト

SQLGLMサブルーチン, 8.3.6

エラー・メッセージ

最大長, 8.3.6

エラー・レポート

エラー・メッセージ・テキスト, 8.3.3.5

基本コンポーネント, 8.3.3

解析エラー・オフセット, 8.3.3.4

処理済行数, 8.3.3.3

ステータス・コード, 8.3.3.1

警告フラグ, 8.3.3.2

WHENEVERディレクティブ, E.58

ERRORSプリコンパイラ・オプション, 14.7.16 例外、PL/SQL, 6.5.1 EXEC ORACLE DEFINE文, 2.5 EXEC ORACLE ELSE文, 2.5 EXEC ORACLE ENDIF文, 2.5 EXEC ORACLE IFDEF文, 2.5 EXEC ORACLE IFNDEF文, 2.5 EXEC ORACLE文

スコープ, 14.4.2.2

構文, 14.4.2

用途, 14.4.2.1

オプションのインライン入力に使用, 14.4.2

EXEC SQL句, 2.1.3, 2.2.12 EXECUTE IMMEDIATE文, E.25

AT句, 3.2.2.1

例, E.25

動的SQL方法1での使用, 9.7.1

ARRAYLEN文のEXECUTEオプション・キーワード, 6.6.1.1 EXECUTE文, E.23, E.23

例, E.22, E.23

動的SQL方法2での使用, 9.9

EXECUTE...END-EXEC文, E.22 実行計画, C.5 EXPLAIN PLAN文

パフォーマンス向上のために使用, C.5.1.1

明示的ログイン

単一, 3.2.2.1

明示的ログイン, 3.2.2 外部データ型

CHAR, 4.1.2.1

CHARF, 4.1.2.2

CHARZ, 4.1.2.3

DECIMAL, 4.1.2.5

定義, 2.1.7

DISPLAY, 4.1.2.6

動的SQL方法4, 11.4.2

FLOAT, 4.1.2.7

INTEGER, 4.1.2.8

LONG, 4.1.2.9

LONG RAW, 4.1.2.10

LONG VARCHAR, 4.1.2.11

LONG VARRAW, 4.1.2.12

パラメータ, 4.12.2

RAW, 4.1.2.15

STRING, 4.1.2.17

表, 4.1.2

UNSIGNED, 4.1.2.18

VARCHAR, 4.1.2.19

VARCHAR2, 4.1.2.20

VARNUM, 4.1.2.21

VARRAW, 4.1.2.22

F

FETCH SQL文, E.27, E.27

FETCH文, 5.4.3, 5.4.3, E.26

カーソル変数, 6.10.4

例, 5.4.3

例, E.26

動的SQL方法4, 11.6.15

INTO句, 5.4.3

OPEN文の後で使用, E.49, E.50

動的SQL方法3での使用, 9.11.4

フェッチ、バッチ, 7.4.1 フェッチする

カーソルからの行, E.26, E.27

表意定数

埋込みSQL文, 2.2.13

ファイル拡張子

INCLUDEファイル, 2.3.3.1

ファイルの長さ制限, 2.2.14 FIPSフラガー

配列の使用を示す, 7.3.6

FIPSプリコンパイラ・オプション, 14.7.18 フラグ, 8.3.3.2 FLOATデータ型, 4.1.2.7 FOR句, 7.9

例, 7.9

埋込みSQL EXECUTE文, E.23, E.24

埋込みSQL INSERT文, E.30

制限, 7.9.1

ホスト表の使用, 7.9

FOR UPDATE OF句, 3.11.1 FORCE句

COMMIT文, E.8

ROLLBACK文, E.52

書式マスク, 4.11 FORMATプリコンパイラ・オプション, 14.7.19

用途, 2.2.4

COBOL文の書式

ANSI, 2.2.4

TERMINAL, 2.2.4

前方参照, 5.4.1 FREE文, E.28, E.28 解放

スレッド・コンテキスト, 12.4.2.5, E.11

フル・スキャン, C.7

G

GET DESCRIPTOR文, E.29

グローバリゼーション・サポート, 4.8, 4.8, 14.7.35

マルチバイト・キャラクタ文字列, 4.9

グローバリゼーション・サポート・パラメータ

NLS_LANG, 4.8

GOTOアクション

WHENEVERディレクティブ, 8.3.8.9, E.58

グループ項目

ホスト変数として使用, 4.3.2.1

暗黙的なVARCHAR, 4.5.2

ガイドライン

データ型の同値化, 4.12.4

動的SQL, 9.6.5

分割プリコンパイル, 2.6.1

トランザクション, 3.14.1

H

ヘッダー・ファイル, 1.7.1

ヒープ, 8.4.4

ヒープ・メモリー

カーソル変数の割当て, 6.10.2

ヒープ表, 4.7 ヒント、オプティマイザ, C.5.1 ヒント

DELETE文, E.18

SELECT文, E.54

UPDATE文, E.56

HOLD_CURSORオプション

ORACLEプリコンパイラ, E.7

パフォーマンス向上のために使用, C.9.2.4

影響, C.9

HOLD_CURSORプリコンパイラ・オプション, 14.7.20 ホスト言語, 2.1.2 HOSTプリコンパイラ・オプション, 14.7.21 ホスト・プログラム, 2.1.2 ホスト表の要素

最大, 7.3.1.1

ホスト表の例, 7.4.7 ホスト表, 7.1

利点, 7.2

宣言, 7.3.1

要素数の設定, 7.3.1.1

マルチディメンション(多次元), 7.3.1.1

操作, 2.1.8

参照, 7.3.2

制限, 7.3.1.1, 7.3.1.1, 7.4.4, 7.5.1, 7.7.1

制限, 7.3.5

サポート, 4.3.1.1

動的SQL文で使用, 9.15

DELETE文で使用, 7.7

INSERT文で使用, 7.5

SELECT文で使用, 7.4

UPDATE文で使用, 7.6

WHERE句で使用, 7.10

FOR句の使用, 7.9

パフォーマンス向上のために使用, C.3

可変長, 7.3.1.1

ホスト変数, 5.1

値の割当て, 2.1.6

宣言, 2.2.1, 2.3.1

宣言とネーミング, A.1.2

定義, 2.2.16

ホスト変数の同値化, E.57

EXECUTE文, E.23

OPEN文, E.49

初期化, 4.3.1.2

長さ30文字まで, 2.1.6

命名, 2.1.6, 4.3.2, 4.3.2.2

概要, 2.1.6

参照, 2.1.6, 4.3.2

要件, 2.1.6

制限, 2.2.17, 4.3.2.2

PL/SQLでの使用, 6.4

使用できる所, 2.1.6

PL/SQLでの, 6.1.1

ハイフン付き

ホスト変数名, 2.2.17

I

IDE, F.1.1

識別子, ORACLE

フォーム方法, E.3.6

暗黙的ログイン, 3.2.6 暗黙的なVARCHAR, 4.5.2 IN OUTパラメータ・モード, 6.2.4.1 INパラメータ・モード, 6.2.4.1 INAMEオプション

ファイル拡張子が必要な場合, 14.1

INAMEプリコンパイラ・オプション, 14.7.23 INCLUDEプリコンパイラ・オプション, 14.7.24 INCLUDE文

大小文字区別オペレーティング・システム, 2.3.3.2

ORACAの宣言, 8.4.2

SQLCAの宣言, 8.3.2

SQLDAの宣言, 11.2.3

影響, 2.3.3

INCLUDE文, A.1.3 索引

パフォーマンス向上のために使用, C.7

索引構成表, 4.7 インジケータ表, 7.1 インジケータ表

例, 7.3.3

用途, 7.3.3

標識変数

NULLの処理に使用, 5.2.3, 5.2.4

標識変数, 5.2

値の割当て, 4.4.1.2

ホスト変数との関連付け, 4.4, 4.4.1

宣言, 2.2.1, 4.4.2

機能, 4.4

機能, 4.4.1

値の意味, 5.2.2

NULL, 6.1.3.1

参照, 4.4.3

必須サイズ, 4.4.2

切り捨てられた値, 6.1.3.2

マルチバイト・キャラクタ文字列で使用, 4.9.5

PL/SQLでの使用, 6.5

NULLの検出に使用, 4.4.2

切り捨てられた値の検出に使用, 4.4.2

NULLのテストに使用, 5.2.6

PL/SQLでの, 6.1.3

インダウト・トランザクション, 3.13 入力ホスト変数

制限, 5.1.1

使用できる所, 5.1.1

INSERT文, E.30

列リスト, 5.3.3

例, 5.3.2

INTO句, 5.3.3

ホスト表の使用, 7.5

VALUES句, 5.3.3

挿入

行を表およびビューに挿入する, E.30

INTEGERデータ型, 4.1.2.8 内部データ型

定義, 2.1.7

内部データ型

動的SQL方法4, 11.4.2

INTERVAL DAY TO SECONDデータ型, 4.2 INTERVAL YEAR TO MONTHデータ型, 4.2 INTO句, 5.1.1, 6.10.4

FETCH文, 5.4.3

INSERT文, 5.3.3

FETCH文, E.26, E.27

SELECT文, E.54

SELECT文, 5.3.1

IRECLENプリコンパイラ・オプション, 14.7.25 IS NULL演算子

NULL値を検索, 2.2.21

J

Javaメソッド

Pro*COBOLからコール, 6.8

L

言語サポート, 1.2.1

LEVEL擬似例, 4.1.2.23

ライブラリ・ファイル, 1.7.2

行の継続, 2.2.7

リンク, 2.7

LITDELIMオプション

用途, 14.7.26

LITDELIMプリコンパイラ・オプション, 2.2.10, 14.7.26 LNAMEプリコンパイラ・オプション, 14.7.27 LOBおよびプリコンパイラの型, 13.4.15 LOB APPEND文, E.31 LOB ASSIGN文, E.32 LOB CLOSE文, E.33 LOB COPY文, E.34 LOB CREATE文, E.35 LOB DESCRIBE文, E.36 LOB DISABLE BUFFERING文, E.37 LOB ENABLE BUFFERING文, E.38 LOB ERASE文, E.39 LOB FILE CLOSE文, E.40 LOB FILE SET文, E.41 LOB FLUSH BUFFER文, E.42 LOB FREE TEMPORARY, E.43 LOB LOAD文, E.44 LOB OPEN文, E.45 LOB READ文, E.46 LOB文

LOB APPEND, 13.4.1

LOB ASSIGN, 13.4.2

LOB CLOSE, 13.4.3

LOB CLOSE ALL, 13.4.9

LOB COPY, 13.4.4

LOB CREATE TEMPORARY, 13.4.5

LOB DISABLE BUFFERING, 13.4.6

LOB ENABLE BUFFERING, 13.4.7

LOB ERASE, 13.4.8

LOB FILE SET, 13.4.10

LOB FLUSH BUFFER, 13.4.11

LOB FREE TEMPORARY, 13.4.12

LOB LOAD FROM FILE, 13.4.13

LOB OPEN, 13.4.14

LOB READ, 13.4.15

LOB TRIM, 13.4.16

LOB WRITE, 13.4.17

LOB TRIM文, E.47 LOB WRITE文, E.48 LOB

バッファリングの利点, 13.1.7

CHUNKSIZEの属性, 13.4.18

LONGおよびLONG RAWとの比較, 13.1.4

定義, 13.1

DIRECTORYの属性, 13.4.18

外部, 13.1.2, 13.2.2.2

FILEEXISTSの属性, 13.4.18

FILENAMEの属性, 13.4.18

内部, 13.1.1, 13.2.2.1

ISOPENの属性, 13.4.18

ISTEMPORARYの属性, 13.4.18

LENGTHの属性, 13.4.18

LOBデモ・プログラム, 13.5

ロケータ, 13.1.5

すべての文に適用されるルール, 13.3.1

バッファリング・サブシステムに適用されるルール, 13.3.2

文のルール, 13.3.3

一時, 13.1.6, 13.2.2.3

ポーリング・メソッドを使用した読込みおよび書込み, 13.4.19

ロック

ROLLBACK文による解除, E.52

LOCK TABLE文, 3.12.1

例, 3.12.1

NOWAITパラメータの使用, 3.12.1

ロック, 3.3, 3.11

明示的と暗黙的の比較, 3.11

モード, 3.3

デフォルトに一時優先, 3.11

要権限, 3.14.2

FOR UPDATE OF句の使用, 3.11

LOCK TABLE文の使用, 3.12.1

ログイン

自動, 3.2.3

同時, 3.2.1

明示的, 3.2.2

要件, 3.1

LONGデータ型

外部, 4.1.2.9

LONG RAWデータ型

変換, 4.12.5

LONG RAWデータ型

外部, 4.1.2.10

LONG VARCHARデータ型, 4.1.2.11 LONG VARRAWデータ型, 4.1.2.12 LRECLENプリコンパイラ・オプション, 14.7.28 LTYPEプリコンパイラ・オプション, 14.7.29

M

MAXLITERAL, A.1.4

MAXLITERALプリコンパイラ・オプション, 14.7.31

MAXOPENCURSORSオプション, C.9

分割プリコンパイルに使用, 2.6.1.2

MAXOPENCURSORSプリコンパイラ・オプション, 14.7.32 Micro Focus COBOL

COBSQL, F.1.4

IDE, F.1.1

Net Express, F.1.1

メッセージ・テキスト, 8.3.3.5 MODE

等価, 14.7.33

MODEオプション

効果, 4.6.2

MODEプリコンパイラ・オプション, 14.7.33 モード、パラメータ, 6.2.4.1 マルチバイト・キャラクタ・セット, 4.9 マルチバイト・グローバリゼーション・サポート機能

データ型, 2.2.20

PL/SQLでの, 4.9.1

マルチスレッド・アプリケーション

サンプル・プログラム, 12.5

ユーザー・インタフェース機能

埋込みSQL文およびディレクティブ, 12.4.2

N

ネームスペース

Oracleにより確保, B.2

命名

ホスト変数, 2.2.16

データベース・オブジェクト, E.3.6

選択リスト項目, 11.2.1

ネーミング規則

カーソル, 5.4.1

デフォルトのデータベース, 3.2.1

ホスト変数, 2.1.6

NATIVE

DBMSオプションの値, 14.7.10

NESTEDプリコンパイラ・オプション, 14.7.34 ネストされたプログラム

サポート, 2.4.1

Net Express, F.1.1 NEXTVAL擬似例, 4.1.2.23 ニブル, 4.12.5 NLS_LOCAL

プリコンパイラ・オプション, 14.7.35

NOT FOUND状態

WHENEVERディレクティブ, 8.3.8.4, E.58

NOWAITパラメータ, 3.12.1

LOCK TABLE文で使用, 3.12.1

NULL

定義, 2.1.6

検出, 4.4.2

処理

動的SQL方法4, 11.4.4

標識変数, 6.1.3.1

ハードコード, 5.2.3 挿入, 5.2.3 SQL (NVL関数)意味, 2.2.21 制限, 5.2.6 検索, 5.2.4 SQLNULサブルーチン, 11.4.4 テスト用, 5.2.6 SQLのNULL

検出方法, 2.2.21

NUMBERデータ型

SQLPRCサブルーチンを使用, 11.4.3

NVL関数

NULL値を検索, 2.2.21

O

ONAMEプリコンパイラ・オプション, 14.7.36

OPEN DESCRIPTOR文, E.50

OPEN SQL文, E.50

OPEN文, E.49

例, 5.4.2

例, E.49

動的SQL方法4, 11.6.11

動的SQL方法3での使用, 9.11.3

オープン

カーソル, E.49, E.50

カーソル変数のオープン, 6.10.3 演算子

関係, 2.2.25

オプティマイザ・ヒント, C.5.1 オプションの分割ヘッダー, 2.2.11 オプション

プリコンパイラの概念, 14.3

ORACA, 1.7.1, 8.2.2

宣言, 8.4.1, 8.4.2

使用可能にする, 8.4.3, 8.4.3

例, 8.4.6

フィールド, 8.4.5

カーソル・キャッシュ統計情報の収集, 8.4.5.11

ORACABCフィールド, 8.4.5.2

ORACAIDフィールド, 8.4.5.1

ORACCHFフラグ, 8.4.5.3

ORACOCフィールド, 8.4.5.14

ORADBGFフラグ, 8.4.5.4

ORAHCHFフラグ, 8.4.5.5

ORAHOCフィールド, 8.4.5.12

ORAMOCフィールド, 8.4.5.13

ORANEXフィールド, 8.4.5.17

ORANORフィールド, 8.4.5.15

ORANPRフィールド, 8.4.5.16

ORASFNMCフィールド, 8.4.5.9

ORASFNMLフィールド, 8.4.5.9

ORASLNRフィールド, 8.4.5.10

ORASTXTCフィールド, 8.4.5.8

ORASTXTFフラグ, 8.4.5.6

ORASTXTLフィールド, 8.4.5.8

プリコンパイラ・オプション, 8.4.3

用途, 8.2.2, 8.4

構造, 8.4.5

ORACAプリコンパイラ・オプション, 14.7.22, 14.7.30, 14.7.37, 14.7.39, 14.7.40, 14.7.42, 14.7.52 ORACABCフィールド, 8.4.5.2 ORACAIDフィールド, 8.4.5.1 ORACCHFフラグ, 8.4.5.3 Oracle通信領域

ORACA, 8.4

Oracle動的SQL

使用するとき, 10

Oracleオブジェクト名

フォーム方法, E.3.6

Oracleネームスペース, B.2 Oracle Net

ROWIDデータ型を使用, 4.1.2.16

Oracleへの接続に使用, 3.2.1

Oracle Net Services

同時ログイン, 3.2.1

Oracle Open Gateway

ROWIDデータ型を使用, 4.1.2.16

ORACOC

ORACA内, 8.4.5.14

ORACOCフィールド, 8.4.5.14 ORADBGFフラグ, 8.4.5.4 ORAHCHFフラグ, 8.4.5.5 ORAHOCフィールド, 8.4.5.12 ORAMOCフィールド, 8.4.5.13 ORANEX

ORACA内, 8.4.5.17

ORANEXフィールド, 8.4.5.17 ORANORフィールド, 8.4.5.15 ORANPRフィールド, 8.4.5.16 ORASFNM, ORACA内, 8.4.5.9 ORASFNMCフィールド, 8.4.5.9 ORASFNMLフィールド, 8.4.5.9 ORASLNR

ORACA内, 8.4.5.10

ORASLNRフィールド, 8.4.5.10 orasql11.libライブラリ・ファイル, 1.7.2 ORASTXTCフィールド, 8.4.5.8 ORASTXTFフラグ, 8.4.5.6 ORASTXTLフィールド, 8.4.5.8 ORECLENプリコンパイラ・オプション, 14.7.38 OUTパラメータ・モード, 6.2.4.1 出力ホスト変数, 5.1.1, 5.1.1 出力と入力, 5.1

P

PAGELENプリコンパイラ・オプション, 14.7.41

段落の名前

SQL文と対応付ける, 2.2.22

コーディング領域, 2.2.22

パラメータ・モード, 6.2.4.1 解析エラー・オフセット, 8.3.3.4 動的文を解析する

PREPARE文, E.51

パスワード

ALTER AUTHORIZATIONを使用して実行時に変更, 3.2.4

定義, 3.1

ハードコード, 3.1

パフォーマンス

チューニング, C.1

改善, C.2

グローバリゼーション・サポート文字のPIC G句, A.1.5 グローバリゼーション・サポート文字のPIC N句, A.1.5 PICXプリコンパイラ・オプション, 4.6.1, 14.7.43 プレースホルダ

複製, 9.16.2

計画、実行, C.5 PLAN_BASELINE

プリコンパイラ・オプション, 14.7.44

PLAN_ENABLED

プリコンパイラ・オプション, 14.7.48

PLAN_FIXED

プリコンパイラ・オプション, 14.7.47

PLAN_PREFIX

プリコンパイラ・オプション, 14.7.45

PLAN_RUN

プリコンパイラ・オプション, 14.7.46

PL/SQL

利点, 1.5

カーソルFORループ, 6.2.3

同等のデータ型, 11.4.3

埋込み, 6.1

例外, 6.5.1

サーバーとの統合, 6.2.2

カーソル変数のオープン

無名ブロック, 6.10.3.2

ストアド・プロシージャ, 6.10.3.1

パッケージ, 6.2.5 SQLとの関連, 1.5 サブプログラム, 6.2.4 ユーザー定義レコード, 6.2.7 PL/SQLブロックの実行

SQLCAコンポーネントへの影響, 8.3.5

PL/SQLブロック

Oracle7プリコンパイラ・プログラムに埋め込む, E.22

PL/SQLサブプログラム

Pro*COBOLからコール, 6.8

PL/SQL表, 6.2.6 プリコンパイル

条件付き, 2.5

生成コード, 14.2

分割, 2.6

プリコンパイル・ユニット, 14.5 プリコンパイラ・コマンド

必須引数, 14.1

プリコンパイラのオプション

略称, 14.3

ANSI動的SQL, 10.5

ASACC, 14.7.1

ASSUME_SQLCODE, 14.7.2

AUTO_CONNECT, 3.2.3.1, 14.7.3

CLOSE_ON_COMMIT, 5.4.1, 5.5.2, 14.7.6

COMP_CHARSET, 14.7.7, 14.7.7

CONFIG, 14.7.8

カレント値, 14.3.3

DATE_FORMAT, 14.7.9, 14.7.9

DBMS, 14.7.10, 14.7.11

DECLARE_SECTION, 2.3.2, 14.7.12

DEFINE, 14.7.13

表示, 14.3

構文、デフォルトおよび目的の表示, 14.6

DYNAMIC, 10.5, 14.7.14

END_OF_FETCH, 14.7.15, 14.7.15

入力, 14.4

インラインの入力, 14.4.2

コマンドラインに入力, 14.1

ERRORS, 14.7.16

FIPS, 14.7.18

FORMAT, 14.7.19

HOLD_CURSOR, 14.7.20, C.9

HOST, 14.7.21

INAME, 14.7.23

INCLUDE, 14.7.24

IRECLEN, 14.7.25

リスト, 14.6

LITDELIM, 2.2.10, 14.7.26

LNAME, 14.7.27

LRECLEN, 14.7.28

LTYPE, 14.7.29

マクロとマイクロ, 14.3.2

MAXLITERAL, 14.7.31

MAXOPENCURSORS, 2.6.1.2, 14.7.32, C.9

MODE, 4.6.2, 8.2.3, 10.5, 14.7.33

システム構成ファイルの名前, 14.4.3

NESTED, 14.7.34

NLS_LOCAL, 14.7.35

ONAME, 14.7.36

ORACA, 8.4.3, 14.7.22, 14.7.30, 14.7.37, 14.7.39, 14.7.40, 14.7.42, 14.7.52

ORECLEN, 14.7.38

PAGELEN, 14.7.41

PICX, 4.6.1, 14.7.43

PLAN_BASELINE, 14.7.44

PLAN_ENABLED, 14.7.48

PLAN_FIXED, 14.7.47

PLAN_PREFIX, 14.7.45

PLAN_RUN, 14.7.46

優先順位, 14.3.1

PREFETCH, 5.4.9, 14.7.49, 14.7.50

RELEASE_CURSOR, 14.7.51, C.9

再指定, 14.5

スコープ, 14.5, 14.5

SELECT_ERROR, 14.7.53

指定, 14.1

SQLCHECK, 14.7.54

構文, 14.1, 14.1

マクロ・オプションによるマイクロ・オプションの設定方法の表, 14.3.2

THREADS, 12.4.1

TYPE_CODE, 10.5, 14.7.55, 14.7.56

UNSAFE_NULL, 14.7.57

USERID, 14.7.58

VARCHAR, 14.7.59

XREF, 14.7.60

プリコンパイラ

利点, 1.3

グローバリゼーション・サポート, 4.8

言語サポート, 1.2.1

実行, 14

PL/SQLの使用, 6.3

PREFETCHプリコンパイラ・オプション, 5.4.9, 5.5.3, 14.7.49, 14.7.50 PREPARE文, E.51

データ定義文での効果, 9.6.2

例, E.51

動的SQL方法4, 11.6.6

動的SQLでの使用, 9.9, 9.11.1

プライベートSQL領域

カーソルとの関連, 5.4

オープン, 5.4

用途, C.9.2.1

Pro*COBOL

機能, 1.2

プログラムの終了, 3.9 プログラミングのガイドライン, 2.2 プログラミング言語サポート, 1.2.1 擬似例, 4.1.2.23

CURRVAL, 4.1.2.23

LEVEL, 4.1.2.23

NEXTVAL, 4.1.2.23

ROWNUM, 4.1.2.23

Q

問合せ

カーソルとの関連付け, 5.4

単一行と複数行の比較, 5.3.1

問合せ, 5.3

R

RAWデータ型

変換, 4.12.5

外部, 4.1.2.15

RAWTOHEX関数, 4.12.5 読込み一貫性, 3.3 READ ONLYパラメータ

SET TRANSACTIONで使用, 3.10

読取り専用トランザクション, 3.10

終了, 3.10

例, 3.10

レコード、ユーザー定義, 6.2.7 REDEFINES句

用途, 2.2.23

制限, 2.2.23

参照

ホスト変数, 2.1.6

参照カーソル, 6.10 参照

ホスト表, 7.3.2

ホスト変数, 4.3.2

標識変数, 4.4.3

VARCHAR変数, 4.5.3

関係演算子

COBOL対SQL, 2.2.25

RELEASEオプション, 3.6, 3.9

COMMIT文, 3.6

オミット, 3.9

制限, 3.8

ROLLBACK文, 3.7

RELEASE_CURSORオプション, C.9

ORACLEプリコンパイラ, E.7

RELEASE_CURSORプリコンパイラ・オプション, 14.7.51 リモート・データベース

宣言, E.15

制限

AT句, 3.2.2.1

CURRENT OF句, 5.4.6

カーソルの宣言, 5.4.1

カーソル変数, 6.10.7

動的SQL, 14.7.35

FOR句, 7.9.1

ホスト表, 7.3.1.1, 7.4.4, 7.5.1, 7.7.1

ホスト変数, 4.3.2.2

命名, 2.2.16

参照, 4.3.2.2

入力ホスト変数, 5.1.1 ホスト表, 7.3.5 REDEFINES句, 2.2.23 RELEASEオプション, 3.8 分割プリコンパイル, 2.6.1.1 SET TRANSACTION文, 3.10 SQLGLMサブルーチン, 8.3.6 SQLIEMサブルーチン, 8.3.6 TO SAVEPOINT句, 3.8 CURRENT OF句の使用, 7.3.5 表から行を取り出す

埋込みSQL, E.54

RETURN-CODE特別登録が予測できない, A.1.6 RETURNING句, 5.3.3

INSERT, 5.3.3

ロールバック

セーブポイント, E.53

同じセーブポイントに複数回, E.52

ロールバック

自動, 3.7

用途, 3.4

文レベル, 3.7.1

ロールバック・セグメント, 3.3 ROLLBACK文, 3.7, 3.7, E.52

影響, 3.7

トランザクションの終了, E.52

例, 3.7

例, E.52

RELEASEオプション, 3.7

TO SAVEPOINT句, 3.7

PL/SQLブロックで使用, 3.14.3

エラー処理ルーチンで使用, 3.7

配置位置, 3.7

ロールバック

トランザクション, E.52

行ロック

FOR UPDATE OFで取得, 3.11.1

パフォーマンス向上のために使用, C.8

取得した場合, 3.11.1.1

解除された場合, 3.11.1.1

ROWIDデータ型

ヒープ表と索引構成表, 4.7

汎用, 4.7

使用方法, 4.7

ALLOCATEの使用, 4.7

ROWID疑似列

SQLROWIDGETを使用した取出し, 4.7.1

ユニバーサルROWID, 4.7

CURRENT OFの擬似に使用, 3.12, 7.11

ROWNUM擬似例, 4.1.2.23 行

カーソルからフェッチする, E.26, E.27

表およびビューに挿入する, E.30

更新, E.56

処理済行数, 8.3.3.3 RR図

「構文図」を参照, E.3

S

サンプル・データベース表

DEPT表, 2.8

EMP表, 2.8

サンプル・プログラム

ストアド・プロシージャのコール, 6.9, 6.9

カーソル操作, 5.8

カーソル変数の使用方法, 6.10.8

カーソル変数

PL/SQLソース, 6.10.8.1

データ型の同値化, 4.14, 4.14 動的SQL方法1, 9.8 動的SQL方法2, 9.10 動的SQL方法3, 9.12 動的SQL方法4, 11.8 EXEC ORACLEスコープ, 14.4.2.2 バッチでフェッチ, 7.4.7, 7.13 LOBDEMO1.PCO, 13.5 場所, 1.7 PL/SQLの例, 6.4.1 SAMPLE10.PCO, 11.8 SAMPLE11.PCO, 6.10.8 SAMPLE12.PCO, 10.7 SAMPLE13.PCO, 2.4.1.2 SAMPLE14.PCO, 7.13 SAMPLE1.PCO, 2.9 SAMPLE2.PCO, 5.8 SAMPLE3.PCO, 7.4.7 SAMPLE4.PCO, 4.14 SAMPLE6.PCO, 9.8 SAMPLE7.PCO, 9.10 SAMPLE8.PCO, 9.12 SAMPLE9.PCO, 6.9 単純な問合せ, 2.9 グループ項目の表, 7.13 WHENEVER...DO CALLの例, 8.3.9.2 セーブポイント, 3.8 SAVEPOINT文, 3.8, E.53

例, 3.8

例, E.53

セーブポイント

作成, E.53

消去された場合, 3.8

スカラー型, 11.4.3 位取り

定義, 4.12.2

SQLPRCを使用して抽出, 4.12.2

負数の場合, 4.12.2

スコープ

カーソル変数, 6.10.1

DECLARE STATEMENTディレクティブ, E.16

プリコンパイラ・オプション, 14.5, 14.5

EXEC ORACLE文, 14.4.2.2

WHENEVERディレクティブ, 8.3.9.3

検索条件, 5.3.7

WHERE句で使用, 5.3.7

SELDFCLP変数(SQLDA), 11.3 SELDFCRCP変数(SQLDA), 11.3 SELDFMT変数(SQLDA), 11.3 SELDH-CUR-VNAMEL変数(SQLDA), 11.3 SELDH-MAX-VNAMEL変数(SQLDA), 11.3 SELDH-VNAME変数(SQLDA), 11.3 SELDI変数(SQLDA), 11.3 SELDI-CUR-VNAMEL変数(SQLDA), 11.3 SELDI-MAX-VNAMEL変数(SQLDA), 11.3 SELDI-VNAME変数(SQLDA), 11.3 SELDV変数(SQLDA), 11.3 SELDVLN変数(SQLDA), 11.3 SELDVTYP変数(SQLDA), 11.3 選択記述子, 11.2.1 選択記述子

情報, 9.13.2

選択リスト, 5.3.1 選択SQLDA

用途, 11.1.3

SELECT文, E.54

使用可能な句, 5.3.1.1

埋込みSQL例, E.54

例, 5.3.1

INTO句, 5.3.1

ホスト表の使用, 7.4

SELECT_ERRORオプション, 5.3.1 SELECT_ERRORプリコンパイラ・オプション, 14.7.53 選択リスト項目

命名, 11.2.1

意味検査, D.1

使用可能にする, D.3.1

SQLCHECKオプションを使用, D.1

分割プリコンパイル

ガイドライン, 2.6.1

制限, 2.6.1.1

セッション, 3.3 セッション

開始する, E.9

SET句, 5.3.5

副問合せの使用, 5.3.5

SET DESCRIPTOR文, E.55 SET TRANSACTION文

例, 3.10

READ ONLYパラメータ, 3.10

制限, 3.10

スナップショット, 3.3 SQL

文の概要, E.1

SQLコード

SQLGLSルーチンによって戻される, 8.3.10

SQLコミュニケーション領域, 2.1.9.2 SQL記述子領域, 9.13.1, 11.2 SQLディレクティブ

CONTEXT USE, 12.4.2.4

DECLARE CURSOR, E.14

DECLARE DATABASE, E.15

DECLARE STATEMENT, E.16

DECLARE TABLE, E.17

VAR, E.57

WHENEVER, E.58

SQLディレクティブCONTEXT USE, E.12 SQL文

ALLOCATE, E.4

ALLOCATE DESCRIPTOR, E.5

CALL, E.6

CLOSE, E.7

COMMIT, E.8

CONNECT, E.9

CONTEXT ALLOCATE, E.10

CONTEXT FREE, E.11

トランザクションの制御, 3.4

DEALLOCATE DESCRIPTOR, E.13

DELETE, E.18

DESCRIBE, E.19

DESCRIBE DESCRIPTOR, E.20

ENABLE THREADS, E.21

EXECUTE, E.23

EXECUTE DESCRIPTOR, E.24

EXECUTE IMMEDIATE, E.25

EXECUTE...END-EXEC, E.22

FETCH, E.26, E.27

FETCH DESCRIPTOR, E.27

FREE, E.28, E.28

GET DESCRIPTOR, E.29

INSERT, E.30

LOB APPEND, E.31

LOB ASSIGN, E.32

LOB CLOSE, E.33

LOB COPY, E.34

LOB CREATE, E.35

LOB DESCRIBE, E.36

LOB DISABLE BUFFERING, E.37

LOB ENABLE BUFFERING, E.38

LOB ERASE, E.39

LOB FILE CLOSE, E.40

LOB FILE SET, E.41

LOB FLUSH BUFFER, E.42

LOB FREE TEMPORARY, E.43

LOB LOAD, E.44

LOB OPEN, E.45

LOB READ, E.46

LOB TRIM, E.47

LOB WRITE, E.48

OPEN, E.49, E.49, E.50

OPEN DESCRIPTOR, E.50

パフォーマンス向上のために最適化, C.5

PREPARE, E.51

ROLLBACK, E.52

SAVEPOINT, E.53

SELECT, E.54

SET DESCRIPTOR, E.55

静的対動的, 2.1.4

概要, E.1

UPDATE, E.56, E.56

カーソルの制御に使用, 5.3, 5.4

SQL*Plus, 1.4 SQL_CURSOR, E.4 SQLADRサブルーチン

例, 11.6.4

パラメータ, 11.4.1

バッファ・アドレスの格納, 11.1.3

構文, 11.4.1

SQLCA, 1.7.1, 8.2.1

PL/SQLブロックに設定されたコンポーネント, 8.3.5

EXTERNALの宣言, 2.6.1.3

フィールド, 8.3.4

Oracleとの相互作用, 2.1.9.2

概要, 2.1.9.2

共有, 2.6.1.3

SQLCABCフィールド, 8.3.4.2

SQLCAIDフィールド, 8.3.4.1

SQLCODEフィールド, 8.3.4.4

SQLERRD(3)フィールド, 8.3.4.5

SQLERRD(5)フィールド, 8.3.4.5

SQLERRMCフィールド, 8.3.4.4

SQLERRMLフィールド, 8.3.4.4

SQLWARN(4)フラグ, 8.3.4.6

Oracle Net Servicesでの使用, 8.3

SQLCA状態変数

データ構造, 8.3.1

宣言, 8.3.2

MODEオプションの影響, 8.2.3

明示的なチェックと暗黙的なチェックの比較, 8.2.1

用途, 8.3

SQLCABCフィールド, 8.3.4.2 SQLCAIDフィールド, 8.3.4.1 SQLCHECKオプション

DECLARE TABLE文を使用, D.3.1.2

構文/意味検査に使用, D

SQLCHECKプリコンパイラ・オプション, 14.7.54 SQLCODEフィールド, 8.3.4.4

その値の解釈, 8.3.4.4

SQLCODE状態変数

MODEオプションの影響, 8.2.3

使用方法, 8.2.3

SQL-CONTEXT, 12.4.2

ホスト表の使用禁止, 12.4.2.1

変数宣言, 4.3.1

SQLDA, 1.7.1, 9.13.1, 9.13.3

バインド対選択, 9.13.3

BNDDFCLP変数, 11.3

BNDDFCRCP変数, 11.3

BNDDFMT変数, 11.3

BNDDH-CUR-VNAMEL変数, 11.3

BNDDH-MAX-VNAMEL変数, 11.3

BNDDH-VNAME変数, 11.3

BNDDI変数, 11.3

BNDDI-CUR-VNAMEL変数, 11.3

BNDDI-MAX-VNAMEL変数, 11.3

BNDDI-VNAME変数, 11.3

BNDDV変数, 11.3

BNDDVLN変数, 11.3

BNDDVTYP変数, 11.3

宣言, 11.2.3

例, 11.2.3

情報を保存, 9.13.3

用途, 11.2.1

SELDFCLP変数, 11.3

SELDFCRCP変数, 11.3

SELDFMT変数, 11.3

SELDH-CUR-VNAMEL変数, 11.3

SELDH-MAX-VNAMEL変数, 11.3

SELDH-VNAME変数, 11.3

SELDI変数, 11.3

SELDI-CUR-VNAMEL変数, 11.3

SELDI-MAX-VNAMEL変数, 11.3

SELDI-VNAME変数, 11.3

SELDV変数, 11.3

SELDVLN変数, 11.3

SELDVTYP変数, 11.3

SQLADRサブルーチン, 11.4.1

SQLDFND変数, 11.3

SQLDNUM変数, 11.3

構造体, 11.3

SQLDFND変数(SQLDA), 11.3 SQLDNUM変数(SQLDA), 11.3 SQLERRD(3)フィールド, 8.3.4.5

バッチ・フェッチで使用, 7.4.3

SQLERRD (3)変数, 8.3.3.3 SQLERRD(5)フィールド, 8.3.4.5 SQLERRMCフィールド, 8.3.4.4 SQLERRMC変数, 8.3.3.5 SQLERRMLフィールド, 8.3.4.4 SQLERROR状態, 8.3.8.3

WHENEVERディレクティブ, 8.3.8.3

WHENEVERディレクティブ, E.58

SQLFCパラメータ, 8.3.10 SQLGLMサブルーチン

例, 8.3.6

パラメータ, 8.3.6

DSNTIARによるDB2変換のサポート, 8.3.7

用途, 8.3.6

制限, 8.3.6

構文, 8.3.6

SQLGLSルーチン, 8.3.10, 8.3.10

パラメータ, 8.3.10

戻されるSQLコード, 8.3.10

構文, 8.3.10

SQLテキストの取得に使用, 8.3.10

SQLIEMサブルーチン

制限, 8.3.6

SQLNULサブルーチン

例, 11.4.4

パラメータ, 11.4.4

用途, 11.4.4

構文, 11.4.4

SQLPRCサブルーチン

例, 11.4.3

パラメータ, 11.4.3

用途, 11.4.3

構文, 11.4.3

SQLROWIDGET

最後に挿入したROWIDの取出し, 4.7.1

SQLSTATE

宣言, 8.2.4

SQLSTATE状態変数

クラス・コード, 8.2.4.1

コード構成, 8.2.4.1

MODEオプションの影響, 8.2.3

値の解釈, 8.2.4.1

事前定義のクラス, 8.2.4.1

サブクラス・コード, 8.2.4.1

使用方法, 8.2.3

SQLSTMパラメータ, 8.3.10 SQLSTMルーチン, 8.3.10 SQLWARN(4)フラグ, 8.3.4.6 SQLWARNING

条件WHENEVERディレクティブ, E.58

SQLWARNING状態, 8.3.8.2

WHENEVERディレクティブ, 8.3.8.2

文レベルのロールバック, 3.7.1

デッドロックの解除, 3.7.1

エラー・レポートのステータス・コード, 8.3.3.1 STMLENパラメータ, 8.3.10 STOPアクション

WHENEVERディレクティブ, 8.3.8.10, E.58

ストアド・プロシージャ

カーソルのオープン, 6.10.8

サンプル・プログラム, 6.10.8

ストアド・プロシージャ

カーソルのオープン, 6.10.3.1

サンプル・プログラム, 6.9

ストアド・サブプログラム

コール, 6.8.2.1

作成, 6.8.1

パッケージとスタンドアロンの比較, 6.8

ストアド対インライン, C.4

パフォーマンス向上のために使用, C.4

ストアド・サブプログラム、コール, 6.8 STRINGデータ型, 4.1.2.17 文字列リテラル

次の行に継続, 2.2.7

サブプログラム、PL/SQL, 6.2.4 サブプログラム、PL/SQLまたはJava, 6.8 副問合せ, 5.3.4

例, 5.3.4, 5.3.5

SET句での使用, 5.3.5

VALUES句での使用, 5.3.4

構文検査, D.1 構文

継続行, 2.2.7

埋込みSQL文, 2.2.12

SQLADRサブルーチン, 11.4.1

SQLGLMサブルーチン, 8.3.6

SQLNULサブルーチン, 11.4.4

SQLPRC, 11.4.3

構文図

説明, E.3

読み方, E.3

使用方法, E.3

使用する記号, E.3

構文、埋込みSQL, 2.1.3 SYSDATE関数, 4.1.2.23 SYSDBA権限の設定方法, 3.2.5.2 SYSOPER権限

設定方法, 3.2.5.2

システム障害

トランザクションでの影響, 3.5

システム・グローバル領域(SGA), 6.8

T

ホスト(表)要素

最大, 7.3.1.1

表ロック

LOCK TABLEで取得, 3.12.1

行共有, 3.12.1

解除された場合, 3.12.1

表

要素, 7.1

索引構成, 4.7

行を挿入する, E.30

行を更新する, E.56

表、ホスト, 7.1 TERMINAL書式

COBOL文, 2.2.4

埋込みSQL文の終了記号, 2.2.25 スレッド, E.10

コンテキストの割当て, 12.4.2.3, E.10

使用可能にする, 12.4.2.2, E.21

コンテキストの解放, 12.4.2.5, E.11

コンテキストの使用, 12.4.2.4, E.12

THREADS

プリコンパイラ・オプション, 12.4.1

TIMESTAMPデータ型, 4.2 TIMESTAMP WITH LOCAL TIME ZONEデータ型, 4.2 TIMESTAMP WITH TIME ZONEデータ型, 4.2 TO SAVEPOINT句, 3.8

制限, 3.8

ROLLBACK文の使用, 3.8

トレース機能

パフォーマンス向上のために使用, C.5.1.1

トランザクション, 3.4 トランザクション

コミットする, E.8

内容, 3.5

ガイドライン, 3.14.1

開始方法, 3.5

終了方法, 3.5

インダウト, 3.13

確定する, 3.6

読取り専用, 3.10

ロールバック, E.52, E.52

セーブポイントで再分割, 3.8

取消し, 3.7

一部を取消し, 3.8

自動的にロールバックされた場合, 3.5, 3.7

切り捨てられた値, 6.5.2

検出, 4.4.2

標識変数, 6.1.3.2

切捨てエラー

生成時, 5.2.7

チューニング、パフォーマンス, C.1 TYPE文

CHARFデータ型指定子の使用, 4.12.3

TYPE_CODEオプション

機能への影響, 10.5

TYPE_CODEプリコンパイラ・オプション, 14.7.55, 14.7.56

U

UID関数, 4.1.2.23

トランザクションを取り消す, E.52

ユニバーサルROWID

ROWID擬似例, 4.7

UNSAFE_NULLプリコンパイラ・オプション, 14.7.57 UNSIGNEDデータ型, 4.1.2.18 UPDATE文, E.56

埋込みSQL例, E.56

例, 5.3.5

SET句, 5.3.5

ホスト表の使用, 7.6

更新

表およびビューの行, E.56

使用

スレッド・コンテキスト, 12.4.2.4

USER関数, 4.1.2.23 ユーザー・セッション, 3.3 ユーザー定義レコード, 6.2.7 USERIDオプション

SQLCHECKオプションを使用, D.3.1.1

USERIDプリコンパイラ・オプション, 14.7.58 ユーザー名

定義, 3.1

ハードコード, 3.1

USING句

CONNECT文, 3.2.2.1

FETCH文, E.26

OPEN文, E.49

EXECUTE文で使用, 9.9.1

標識変数の使用, 9.9.1

db文字列の使用

Oracle Net Servicesデータベースid仕様部, E.9

V

V7

DBMSオプションの値, 14.7.10

VALUE句

ホスト変数の初期化, 4.3.1.2

VALUES句

INSERT文, 5.3.3

埋込みSQL INSERT文, E.30

INSERT文, E.30

副問合せの使用, 5.3.4

VARディレクティブ, E.57

例, E.57

VAR文

CONVBUFSZ句, 4.12.2.1

構文, 4.12.2

CHARFデータ型指定子の使用, 4.12.3

VARCHARデータ型, 4.1.2.19 VARCHARプリコンパイラ・オプション, 14.7.59 VARCHAR擬似型

PL/SQLと使用, 6.4.3

VARCHAR変数

利点, 4.6.4.2

入力変数, 4.6.4.1

出力変数, 4.6.4.2

宣言, 4.5.1

暗黙的なグループ項目, 4.5.2

長さ要素, 4.5.1

最大長, 4.5.1

参照, 4.5.3

サーバー処理, 4.6.4.1, 4.6.4.2

文字列要素, 4.5.1

構造体, 4.5.1

固定長文字列と比較, 4.6.4.2

PL/SQLでの, 6.1.2

VARCHAR2データ型

外部, 4.1.2.20

VARNUMデータ型, 4.1.2.21 VARRAWデータ型, 4.1.2.22 VARYINGキーワード

VARYING句と比較, 4.5.1

COBOLのバージョンのサポート, 2.2.3 ビュー

行を挿入する, E.30

行を更新する, E.56

W

エラー・レポートの警告フラグ, 8.3.3.2

WHENEVER

DO CALLの例, 8.3.9.2

WHENEVERディレクティブ, 8.3.8, E.58

不注意な使用方法, 8.3.9.4

CONTINUEアクション, 8.3.8.6

DO CALLアクション, 8.3.8.7

DO PERFORMアクション, 8.3.8.8

例, 8.3.9.1

例, E.58

GOTOアクション, 8.3.8.9

概要, 2.1.9.3

用途, 8.3.8

スコープ, 8.3.9.3

SQLERROR状態, 8.3.8.3

SQLWARNING状態, 8.3.8.2

STOPアクション, 8.3.8.10

構文, 8.3.9

自動的にSQLCAをチェックするのに使用, 8.3.8.1

WHERE句, 5.3.7

DELETE文, 5.3.6

DELETE文, E.18

UPDATE文, E.56

検索条件, 5.3.7

SELECT文, 5.3.1

UPDATE文, 5.3.5

ホスト表の使用, 7.10

WHERE CURRENT OF句, 5.4.5 WITH HOLD

DECLARE CURSOR文の句, 5.4.1

WORKオプション

COMMIT文, E.8

ROLLBACK文, E.52

X

XREFプリコンパイラ・オプション, 14.7.60

オラクル社の法律上の注意点について

コピーライトについて

Copyright © 1994-2015, Oracle and/or its affiliates.All rights reserved.

商標と登録商標について

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

ライセンス制約の保証と結果的に生じる損害の免責

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

保証免責

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

制限付権利

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs.No other rights are granted to the U.S. Government.

危険な用途への使用について

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション（人的傷害を発生させる可能性があるアプリケーションを含む）への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性（redundancy）、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

第三者のコンテンツ、製品、サービスに対する免責事項

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

ドラフトのアルファ版およびベータ版ドキュメントについて

このドキュメントが試作版の場合:

このドキュメントは試作版であり、デモおよび暫定使用のみを目的としたものです。このソフトウェアを使用するハードウェアに限定するものではありません。オラクル社およびその関連会社は、このドキュメントに関して一切の責任を負わず、いかなる保証もいたしません。また、このドキュメントを使用したことによって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。