この章では、Oracle Pro*C/C++プリコンパイラについて説明します。Oracleデータを操作するアプリケーション・プログラムを開発する上でのPro*C/C++の役割と、プリコンパイラによりアプリケーションで実行できる処理について説明します。この章の項目は、次のとおりです。
Oracleプリコンパイラとは、高水準ソース・プログラムで埋込みSQL文を使用可能にするプログラミング・ツールです。図1-1のように、プリコンパイラはソース・プログラムを入力として受け入れ、埋込みSQL文を標準Oracleランタイム・ライブラリ・コールに変換して、通常の方法でコンパイル、リンクおよび実行できる変更済ソース・プログラムを生成します。
Oracle Pro*C/C++プリコンパイラを使用すると、アプリケーション・プログラムに強力かつ柔軟なSQLを使用できます。便利で使用しやすいインタフェースにより、アプリケーションからOracleに直接アクセスできます。
多くのアプリケーション開発ツールとは異なり、Pro*C/C++では、アプリケーションを高度にカスタマイズできます。たとえば、最新のウィンドウ機能およびマウス技術を取り込んだユーザー・インタフェースを作成できます。ユーザーとの対話なしに、バックグラウンドで実行するアプリケーションも作成できます。
さらに、Pro*C/C++はアプリケーションの微調整に役立ちます。リソースの使用状況、SQL文の実行状況および各種のランタイム・インジケータを綿密に監視できます。この情報に基づいて、パフォーマンスを最大化するようにプログラム・パラメータを変更できます。
プリコンパイルを行うと、アプリケーションの開発プロセスの工程が増えますが、時間の節約になります。Pro*C/C++プリコンパイラにより、埋込みSQL文はOracleランタイム・ライブラリ(SQLLIB)のコールに自動的に変換されます。また、ホスト変数の分析、構造体から列へのマッピングの定義が行われ、SQLCHECK=FULLに設定することで埋込みSQL文の意味分析が実行されます。
Oracleデータにアクセスし、それを操作するには、SQLが必要です。SQLをSQL*Plusで対話形式で使用するか、アプリケーション・プログラムに埋め込むかは、実行する作業によって決まります。ジョブにCまたはC++のプロシージャ型処理機能が必要な場合や、ジョブを定期的に実行する場合は、埋込みSQLを使用してください。
SQLは、柔軟かつ強力で、しかも覚えやすいという特長のために、データベース言語の選択肢となりました。SQLは非手続き型言語であるため、処理の方法でなく要求内容を指定できます。英文に似た少数の文を使用して、Oracleデータを一度に1行ずつまたは複数行ずつ容易に操作できます。
任意(SQL*Plus以外)のSQL文をアプリケーション・プログラムから実行できます。たとえば、次のようなSQL文です。
データベースの表の動的なCREATE、ALTERおよびDROP
データ行のSELECT、INSERT、UPDATEおよびDELETE
トランザクションのCOMMITまたはROLLBACK
SQL文は、アプリケーション・プログラムに埋め込む前に、SQL*Plusを使用して対話形式でテストできます。通常は、わずかな変更によって対話型SQLから埋込みSQLに切り替えることができます。
SQLを拡張したPL/SQLは、プロシージャ構造、変数宣言および強力なエラー処理をサポートするトランザクション処理言語です。同一PL/SQLブロック内で、SQLおよびPL/SQLの拡張機能のすべてを使用できます。
埋込みPL/SQLの主な利点はパフォーマンスの向上です。SQLとは異なり、PL/SQLでは、SQL文を論理的にグループ化し、1文ずつではなくブロック単位でOracleに送ることができます。これにより、ネットワークの通信量と処理のオーバーヘッドが減少します。
図1-2のように、Pro*C/C++には多くの機能と利点があり、効果的で信頼性の高いアプリケーションの開発に役立ちます。
Pro*C/C++によって次のことが可能となります。
CまたはC++言語でアプリケーションを作成すること。
ANSI/ISO規格に従って高水準言語にSQL文を埋め込むこと。
動的SQLを利用すること。動的SQLとは、プログラム実行時に適切なSQL文を受け入れるか作成する、高度なプログラミング技法です。
高度にカスタマイズしたアプリケーションを設計および開発すること。
共有サーバー・プロセス・アプリケーションを作成すること。
Oracleの内部データ型と高水準言語のデータ型の間で自動的な変換を実行すること。
アプリケーション・プログラムにPL/SQLトランザクション処理ブロックを埋め込むことで、パフォーマンスを向上すること。
役立つプリコンパイラ・オプションをインラインまたはコマンドラインで指定し、その値をプリコンパイル中に変更すること。
データ型の同値化を使用して、Oracleで入力データを解釈し出力データをフォーマットする方法を制御すること。
複数のプログラム・モジュールを別々にプリコンパイルし、それらをリンクして1つの実行プログラムにすること。
埋め込まれたSQLデータ操作文とPL/SQLブロックの構文と意味を全面的にチェックすること。
Oracle Netを使用して、複数のノード上のOracleデータベースに同時にアクセスすること。
配列を入力プログラム変数および出力プログラム変数として使用すること。
様々な環境で実行できるように、ホスト・プログラムのコード・セクションを条件付きでプリコンパイルすること。
高水準言語で作成されたユーザー・イグジットを使用した、SQL*Formsとの直接インタフェース。
SQLコミュニケーション領域(SQLCA)およびWHENEVER文またはDO文を使用して、エラーおよび警告を処理すること。
Oracle通信領域(ORACA)により提供される強力な診断機能を使用すること。
データベース内でユーザー定義のオブジェクト型を処理すること。
データベースでコレクション(VARRAYおよびネストした表)を使用すること。
データベースでラージ・オブジェクト(LOB)を使用すること。
データベースに格納された各国語キャラクタ・セット・データを使用すること。
プログラム内でOracle Call Interface(OCI)関数を使用すること。
マルチスレッド・アプリケーションを使用すること。
Microsoft Visual C++のサポート(32ビット・アプリケーション用バージョン6.0)。
このように、Pro*C/C++は、充実した埋込みSQLプログラム技法をサポートする多機能ツールです。
注意: Pro*C/C++では16ビット・コードの生成はサポートされません。 |
Oracleソフトウェアをインストールすると、ハード・ドライブ上にOracle製品のディレクトリ構造が作成されます。メインのOracleディレクトリには、Pro*C/C++の実行に必要なOracleサブディレクトリおよびファイルが含まれます。
Pro*C/C++をインストールすると、Oracle Universal InstallerによりORACLE_BASE
\
ORACLE_HOME
ディレクトリに\precomp
というディレクトリが作成されます。このサブディレクトリには、表1-1に示したPro*C/C++の実行可能ファイル、ライブラリ・ファイルおよびサンプル・プログラム・ファイルが含まれています。
表1-1 precompディレクトリ構造
ディレクトリ名 | コンテンツ |
---|---|
|
構成ファイル |
Pro*C/C++のサンプル・プログラム |
|
|
サンプル・プログラムのSQLスクリプト |
|
Pro*C/C++のreadmeファイル |
|
Pro*C/C++のヘルプ・ファイル |
|
Pro*C/C++のライブラリ・ファイル |
|
メッセージ・ファイル |
|
Pro*C/C++のその他のファイル |
|
ヘッダー・ファイル |
注意: \precomp ディレクトリには、その他の製品(Pro*COBOLなど)用のファイルが含まれている可能性があります。 |
Pro*C/C++アプリケーションをリンクするとき、ライブラリ・ファイルを使用します。Pro*C/C++ライブラリ・ファイルは、次のようにインストールされます。
ORACLE_HOME\precomp\LIB\orasql10.lib
ORACLE_HOME\precomp\LIB\ottclasses.zip
ORACLE_HOME\precomp\LIB\msvc\orasqx10.lib
Pro*C/C++アプリケーション・プログラム・インタフェース(API)のコールは、使用するPro*C/C++ソフトウェアで提供されているDLLファイルに実装されます。DLLを使用するには、アプリケーションを、Pro*C/C++ DLLに対応するインポート・ライブラリ(.libファイル)とリンクする必要があります。また、DLLファイルが、Pro*C/C++アプリケーションを実行しているコンピュータ上にインストールされていることを確認する必要があります。
Microsoftでは、3つのライブラリ(libc.lib
、libcmt.lib
およびmsvcrt.lib
)を提供しています。Oracle DLLは、msvcrt.lib
ランタイム・ライブラリを使用します。アプリケーションを、他の2つのMicrosoftライブラリではなく、msvcrt.lib
とリンクする必要があります。
この項では、Pro*C/C++およびPro*C/C++に関連するOracle9iについての一般的な質問をいくつか示します。回答はこのマニュアルの他の部分に比べると簡単なものですが、該当項目の参照先がわかります。
次の表は、VARCHARの簡単な説明を示しています。
VARCHAR | 説明 |
---|---|
VARCHAR2 | データベースの列の一種で、可変長文字データが含まれています。列型として使用できるため、Oracleではこれを「内部データ型」と呼びます。 |
VARCHAR | Oracleの「外部データ型」(データ型コード9)です。このデータ型を使用するのは、動的SQL方法4またはデータ型同値化を使用する場合のみです。 |
VARCHAR[n]
varchar[n] |
これはPro*C/C++プログラムでホスト変数として宣言できるPro*C/C++の疑似型です。実際には、Pro*C/C++では、2バイト長の要素と[n]バイトの文字配列からなる構造体として生成されます。 |
SQLLIBはドキュメントが外部公開されておらず、サポートされておらず、さらにリリースごとに変更される可能性があります。一方、Pro*C/C++はANSI/ISOに準拠した製品であり、埋込みSQLの標準要件に従っています。
SQLLIBはAPIではありません。ユーザーがコール可能な関数も含まれていますが、主として言語のプリコンパイラ・パッケージ用のランタイム・ライブラリです。
データベース用のAPIコーディングが必要な場合は、Oracle Call InterfaceまたはOracle RDBMS用のクライアント側APIを使用するか、OCIとPro*C/C++を併用してください。
「OCIリリース8のSQLLIB拡張相互運用性」を参照してください。
コールできます。第7章「埋込みPL/SQL」を参照してください。デモ・プログラム「ストアドPL/SQLまたはJavaサブプログラムのコール」があります。
たとえば、実行時にSQL文に表の名前を入力できるようにするとします。しかし、ホスト変数を使用すると、プリコンパイラのエラーが発生します。
通常、SQL文またはPL/SQL文中の式を使用できるところであれば、任意の位置にホスト変数を使用できます。「ホスト変数の参照」を参照してください。
ただし、次のSQL文は無効です(table_nameはホスト変数です)。
EXEC SQL SELECT ename,sal INTO :name, :salary FROM :table_name;
問題を解決するには、動的SQLを使用する必要があります。第13章「Oracle動的SQL」を参照してください。これを実行するために応用できるデモ・プログラム「サンプル・プログラム: 動的SQL方法2」があります。
多数のオプションがありますが、簡単に説明します。第1に、従来のプリコンパイラおよびOracle7との互換性が必要な場合は、VARCHAR[n]ホスト変数を使用するのが最も安全な方法です。「VARCHAR変数の宣言」を参照してください。
Pro*C/C++では、他のすべての文字変数のデフォルト・データ型はCHARZです。「CHARZ」を参照してください。入力時には文字列をヌル文字で終了する必要があります。出力時には空白文字で埋められ、ヌル文字で終了されます。
リリース8.0では、文字変数のデフォルト・マッピングを指定できるように、CHAR_MAPプリコンパイラ・オプションが追加されています。「CHAR_MAPプリコンパイラ・オプション」を参照してください。
アプリケーションでVARCHARもCHARZも不適切であり、全面的にC言語と同様の(ヌル文字で終了するが空白文字で埋められない)動作が必要な場合は、TYPEコマンドとC言語のtypedef
文を使用し、データ型の同値化を使用して文字ホスト変数を文字列に変換してください。「ユーザー定義型同値化」を参照してください。TYPEコマンドの使用方法を示すサンプル・プログラムについては、「サンプル・プログラム: sqlvcp()の使用」を参照してください。
はい。Pro*C/C++では、入力ホスト変数または出力ホスト変数をバインドするときに、その長さを認識する必要があります。VARCHAR[n]を使用するか、char[n]型のホスト変数を宣言すると、Pro*C/C++では宣言から長さが認識されます。ただし、プログラム内で文字ポインタをホスト変数として使用し、malloc()
を使用してバッファを定義すると、Pro*C/C++では長さが認識されません。
出力時には、バッファを割り当てるだけでなく、ヌル文字でない文字を埋め込んでからヌル文字で終了する必要があります。入力時または出力時、Pro*C/C++は長さを取得するために、バッファについてstrlen()
をコールします。「ポインタ変数」を参照してください。
SPOOLはSQL*Plusで使用される特殊なコマンドです。埋込みSQLコマンドではありません。「埋込みSQLプログラムの主な概要」を参照してください。
Oracleのインストール時には、demo
ディレクトリが作成されます。このディレクトリがないか、あってもサンプル・プログラムが含まれていない場合は、システム管理者またはデータベース管理者に連絡してください。
コンパイルとリンクの方法は、プラットフォームごとに異なります。Pro*C/C++アプリケーションをリンクする方法については、システム固有のOracleマニュアルを参照してください。UNIXシステムでは、demo
ディレクトリにproc.mk
というMakeファイルがあります。たとえば、デモ・プログラムsample1.pcをリンクするには、次のコマンドラインを入力します。
make -f proc.mk sample1
特殊なプリコンパイラ・オプションを使用する必要がある場合は、Pro*C/C++を別に実行してからmakeを実行します。または、独自のカスタムMakeファイルを作成することもできます。たとえば、プログラムに埋込みPL/SQLコードが含まれている場合は、次のように入力します。
proc cv_demo userid=username/password sqlcheck=semantics make -f proc.mk cv_demo
VMSシステムには、Pro*C/C++アプリケーションをリンクできるように、LNPROCというスクリプトが用意されています。
配列インタフェースとともに使用した場合の動作について教えてください。
1つの構造体の内部で複数の配列を使用できます。また、構造体の配列を配列インタフェースとともに使用できます。「ホスト構造体」および「ポインタ変数」を参照してください。
いいえ。旧リリースのPro*CまたはPro*C/C++は新バージョンのサーバーに対して使用できますが、新リリースのPro*C/C++は旧バージョンのサーバーに対しては使用できません。
たとえば、Pro*C/C++のリリース2.2はOracle8iに対して使用できますが、Pro*C/C++のリリース8.0はOracle7に対しては使用できません。
標識変数が結合されていないホスト変数にNULLを入れています。これはANSI/ISO規格に準拠していないため、Oracle7からは変更されました。
可能であれば、標識変数を使用してプログラムを書きなおし、今後の開発にはインジケータを使用します。標識変数については、「標識変数」を参照してください。
または、MODE=ORACLEとDBMS=V7またはV8を指定してプリコンパイルしている場合は、コマンドラインでUNSAFE_NULL=YESを指定し、ORA-01405メッセージを無効にしてください(詳細は「UNSAFE_NULL」を参照)。
いいえ。各自のプログラムまたはそのデータに関する情報を取得するためにコールできるSQLLIB関数がいくつかあります。SQLLIBパブリック関数は、次のとおりです。
SQLLIBパブリック関数 | 説明 |
---|---|
SQLSQLDAAlloc() | 動的SQL方法4でSQL記述配列(SQLDA)を割り当てるために使用します。「SQLDAの参照方法」を参照してください。 |
SQLCDAFromResultSetCursor() | Pro*C/C++のカーソル変数をOCIカーソル・データ領域に変換するために使用します。「SQLLIBパブリック関数の新しい名前」を参照してください。 |
SQLSQLDAFree() | SQLSQLDAAlloc()を使用して割り当てたSQLDAを解放するために使用します。「SQLLIBパブリック関数の新しい名前」を参照してください。 |
SQLCDAToResultSetCursor() | OCIのカーソル・データ領域をPro*C/C++のカーソル変数に変換するために使用します。「SQLLIBパブリック関数の新しい名前」を参照してください。 |
SQLErrorGetText() | 長いエラー・メッセージを戻します。「sqlerrm」を参照してください。 |
SQLStmtGetText() | 最後に実行されたSQL文のテキストを戻すために使用します。「SQL文のテキスト取得」を参照してください。 |
SQLLDAGetNamed() | Pro*C/C++プログラムでOCIコールを使用するときに、指定された接続に有効なログイン・データ領域を取得するために使用します。「SQLLIBパブリック関数の新しい名前」を参照してください。 |
SQLLDAGetCurrent() | Pro*C/C++プログラムでOCIコールを使用するときに、最後の接続に有効なログイン・データ領域を取得するために使用します。「SQLLIBパブリック関数の新しい名前」を参照してください。 |
SQLColumnNullCheck() | 動的SQL方法4のNULL状態の表示を戻します。「NULL/Not NULLデータ型の処理」を参照してください。 |
SQLNumberPrecV6() | 数値の精度と位取りを戻します。「精度と位取りの抽出」を参照してください。 |
SQLNumberPrecV7() | SQLNumberPrecV6()の変形。「精度と位取りの抽出」を参照してください。 |
SQLVarcharGetLength() | VARCHAR[n]の埋め込んだサイズを取得するために使用します。「VARCHAR配列コンポーネントの長さを調べる方法」を参照してください。 |
SQLEnvGet() | 特定のSQLLIBランタイム・コンテキストのOCI環境ハンドルを戻します。「SQLEnvGet()」を参照してください。 |
SQLSvcCtxGet() | データベース接続のOCIサービス・コンテキストを戻します。「SQLSvcCtxGet()」を参照してください。 |
SQLRowidGet() | 最後に挿入された行のユニバーサルROWIDを戻します。「SQLRowidGet()」を参照してください。 |
SQLExtProcError() | 外部Cプロシージャでエラーが発生した場合に、PL/SQLに制御を戻します。「SQLExtProcError()」を参照してください。 |
このリストの関数は、スレッド・セーフなSQLLIBパブリック関数です。すべての新規アプリケーションで、これらの関数を使用します。関数名はリリース8.0用に変更されていますが、Pro*C/C++では以前の名前もサポートされています。これらのスレッド・セーフなパブリック関数(およびその旧称)の詳細は、「SQLLIBパブリック関数 - 新しい名前」を参照してください。
Pro*C/C++アプリケーションでのオブジェクト型の使用方法は、第17章「オブジェクト」および第19章「Object Type Translator(OTT)」を参照してください。
Pro*C/C++では、リリース11.1より、OCIベースのアプリケーションと同様の互換性規則を採用します。この場合、下位互換性に対するOCIの制限と同じ制限が適用されます。
追加の配列のINSERTおよびSELECT構文は、DB2プリコンパイラ・アプリケーションのPro*C/C++アプリケーションへの移行に役立ちます。これは、DB2の配列のINSERTおよびSELECT構文をOracle Pro*C/C++の構文に変更する必要がないためです。
Pro*C/C++でサポートされている「暗黙的バッファ挿入」機能は、パフォーマンス向上のためにPro*C/C++の配列構文を使用せずに、DB2プリコンパイラ・アプリケーションをPro*C/C++アプリケーションに移行する場合に役立ちます。