ヘッダーをスキップ
Pro*C/C++プログラマーズ・ガイド
11g リリース1(11.1)
E05689-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

1 概要

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

Oracleプリコンパイラ

Oracleプリコンパイラとは、高水準ソース・プログラムで埋込みSQL文を使用可能にするプログラミング・ツールです。図1-1のように、プリコンパイラはソース・プログラムを入力として受け入れ、埋込みSQL文を標準Oracleランタイム・ライブラリ・コールに変換して、通常の方法でコンパイル、リンクおよび実行できる変更済ソース・プログラムを生成します。

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

埋込みSQLプログラムの開発
「図1-1 埋込みSQLプログラムの開発」の説明

Oracle Pro*C/C++プリコンパイラを使用する理由

Oracle Pro*C/C++プリコンパイラを使用すると、アプリケーション・プログラムに強力かつ柔軟なSQLを使用できます。便利で使用しやすいインタフェースにより、アプリケーションからOracleに直接アクセスできます。

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

さらに、Pro*C/C++はアプリケーションの微調整に役立ちます。リソースの使用状況、SQL文の実行状況および各種のランタイム・インジケータを綿密に監視できます。この情報に基づいて、パフォーマンスを最大化するようにプログラム・パラメータを変更できます。

プリコンパイルを行うと、アプリケーションの開発プロセスの工程が増えますが、時間の節約になります。Pro*C/C++プリコンパイラにより、埋込みSQL文はOracleランタイム・ライブラリ(SQLLIB)のコールに自動的に変換されます。また、ホスト変数の分析、構造体から列へのマッピングの定義が行われ、SQLCHECK=FULLに設定することで埋込みSQL文の意味分析が実行されます。

SQLを使用する理由

Oracleデータにアクセスし、それを操作するには、SQLが必要です。SQLをSQL*Plusで対話形式で使用するか、アプリケーション・プログラムに埋め込むかは、実行する作業によって決まります。ジョブにCまたはC++のプロシージャ型処理機能が必要な場合や、ジョブを定期的に実行する場合は、埋込みSQLを使用してください。

SQLは、柔軟かつ強力で、しかも覚えやすいという特長のために、データベース言語の選択肢となりました。SQLは非手続き型言語であるため、処理の方法でなく要求内容を指定できます。英文に似た少数の文を使用して、Oracleデータを一度に1行ずつまたは複数行ずつ容易に操作できます。

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

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

PL/SQLを使用する理由

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

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


関連項目

Pro*C/C++プログラムでのPL/SQLの埋込みについては、第7章「埋込みPL/SQL」を参照してください。

Pro*C/C++プリコンパイラの利点

図1-2のように、Pro*C/C++には多くの機能と利点があり、効果的で信頼性の高いアプリケーションの開発に役立ちます。

図1-2 機能と利点

図
「図1-2 機能と利点」の説明

Pro*C/C++によって次のことが可能となります。

このように、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ディレクトリ構造

ディレクトリ名 コンテンツ

\admin

構成ファイル

\demo\proc

Pro*C/C++のサンプル・プログラム

\demo\sql

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

\doc\proc

Pro*C/C++のreadmeファイル

\help\proc

Pro*C/C++のヘルプ・ファイル

\lib\msvc

Pro*C/C++のライブラリ・ファイル

\mesg

メッセージ・ファイル

\misc\proc

Pro*C/C++のその他のファイル

\public

ヘッダー・ファイル



注意:

\precompディレクトリには、その他の製品(Pro*COBOLなど)用のファイルが含まれている可能性があります。

既知の問題、制限および回避策

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

  • proc iname=test one.pc

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

ライブラリ・ファイル

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.liblibcmt.libおよびmsvcrt.lib)を提供しています。Oracle DLLは、msvcrt.libランタイム・ライブラリを使用します。アプリケーションを、他の2つのMicrosoftライブラリではなく、msvcrt.libとリンクする必要があります。

よくある質問(FAQ)

この項では、Pro*C/C++およびPro*C/C++に関連するOracle9iについての一般的な質問をいくつか示します。回答はこのマニュアルの他の部分に比べると簡単なものですが、該当項目の参照先がわかります。

VARCHARについて説明してください。

次の表は、VARCHARの簡単な説明を示しています。

VARCHAR 説明
VARCHAR2 データベースの列の一種で、可変長文字データが含まれています。列型として使用できるため、Oracleではこれを「内部データ型」と呼びます。
VARCHAR Oracleの「外部データ型」(データ型コード9)です。このデータ型を使用するのは、動的SQL方法4またはデータ型同値化を使用する場合のみです。
VARCHAR[n]

varchar[n]

これはPro*C/C++プログラムでホスト変数として宣言できるPro*C/C++の疑似型です。実際には、Pro*C/C++では、2バイト長の要素と[n]バイトの文字配列からなる構造体として生成されます。

Pro*C/C++はOracle Call Interfaceのコールを生成しますか。

生成しません。Pro*C/C++ではデータ構造体とSQLLIBランタイム・ライブラリ・コールが生成されます。

Pro*C/C++を使用せず、SQLLIBコールを使用してコーディングできますか。

SQLLIBはドキュメントが外部公開されておらず、サポートされておらず、さらにリリースごとに変更される可能性があります。一方、Pro*C/C++はANSI/ISOに準拠した製品であり、埋込みSQLの標準要件に従っています。

SQLLIBはAPIではありません。ユーザーがコール可能な関数も含まれていますが、主として言語のプリコンパイラ・パッケージ用のランタイム・ライブラリです。

データベース用のAPIコーディングが必要な場合は、Oracle Call InterfaceまたはOracle RDBMS用のクライアント側APIを使用するか、OCIとPro*C/C++を併用してください。

「OCIリリース8のSQLLIB拡張相互運用性」を参照してください。

PL/SQLのストアド・プロシージャをPro*C/C++プログラムからコールできますか。

コールできます。第7章「埋込みPL/SQL」を参照してください。デモ・プログラム「ストアドPL/SQLまたはJavaサブプログラムのコール」があります。

C++のコードを作成し、Pro*C/C++を使用してプリコンパイルできますか。

はい。第12章「C++アプリケーション」を参照してください。

SQL文の任意の場所でバインド変数を使用できますか。

たとえば、実行時にSQL文に表の名前を入力できるようにするとします。しかし、ホスト変数を使用すると、プリコンパイラのエラーが発生します。

通常、SQL文またはPL/SQL文中の式を使用できるところであれば、任意の位置にホスト変数を使用できます。「ホスト変数の参照」を参照してください。

ただし、次のSQL文は無効です(table_nameはホスト変数です)。

EXEC SQL SELECT ename,sal INTO :name, :salary FROM :table_name;

問題を解決するには、動的SQLを使用する必要があります。第13章「Oracle動的SQL」を参照してください。これを実行するために応用できるデモ・プログラム「サンプル・プログラム: 動的SQL方法2」があります。

Pro*C/C++の文字処理がよくわかりません。

多数のオプションがありますが、簡単に説明します。第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()をコールします。「ポインタ変数」を参照してください。

Pro*C/C++でSPOOLが動作しない理由を説明してください。

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というスクリプトが用意されています。

Pro*C/C++では構造体をホスト変数として使用できますか。

配列インタフェースとともに使用した場合の動作について教えてください。

1つの構造体の内部で複数の配列を使用できます。また、構造体の配列を配列インタフェースとともに使用できます。「ホスト構造体」および「ポインタ変数」を参照してください。

再帰関数内で埋込みSQLを使用した場合、その再帰関数をPro*C/C++で使用できますか。

はい。ただし、埋込みSQLの場合はカーソル変数を使用する必要があります。

Pro*C/C++のすべてのリリースを、Oracleサーバーのすべてのバージョンで使用できますか。

いいえ。旧リリースのPro*CまたはPro*C/C++は新バージョンのサーバーに対して使用できますが、新リリースのPro*C/C++は旧バージョンのサーバーに対しては使用できません。

たとえば、Pro*C/C++のリリース2.2はOracle8iに対して使用できますが、Pro*C/C++のリリース8.0はOracle7に対しては使用できません。

アプリケーションをOracle9iで実行すると、必ずORA-01405エラー(フェッチした列の値がNULLです)が発生します。

標識変数が結合されていないホスト変数にNULLを入れています。これはANSI/ISO規格に準拠していないため、Oracle7からは変更されました。

可能であれば、標識変数を使用してプログラムを書きなおし、今後の開発にはインジケータを使用します。標識変数については、「標識変数」を参照してください。

または、MODE=ORACLEとDBMS=V7またはV8を指定してプリコンパイルしている場合は、コマンドラインでUNSAFE_NULL=YESを指定し、ORA-01405メッセージを無効にしてください(詳細は「UNSAFE_NULL」を参照)。

すべてのSQLLIB関数はプライベート関数ですか。

いいえ。各自のプログラムまたはそのデータに関する情報を取得するためにコールできる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パブリック関数 - 新しい名前」を参照してください。

新しいオブジェクト型はOracle9iでどのようにサポートされていますか。

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++アプリケーションに移行する場合に役立ちます。