概要
この章では、Pro*C/C++プリコンパイラについて説明します。Oracleデータを操作するアプリケーション・プログラムを開発する上でのPro*C/C++の役割と、プリコンパイラによりアプリケーションで実行できる処理について説明します。この章の項目は、次のとおりです。
Oracleプリコンパイラ
Oracleプリコンパイラとは、高水準ソース・プログラムで埋込みSQL文を使用可能にするプログラミング・ツールです。図1-1のように、プリコンパイラはソース・プログラムを入力として受け入れ、埋込みSQL文を標準Oracleランタイム・ライブラリ・コールに変換して、通常の方法でコンパイル、リンクおよび実行できる変更済ソース・プログラムを生成します。
図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文です。
- データベースの表の動的なCREATE、ALTERおよびDROP
- データ行のSELECT、INSERT、UPDATEおよびDELETE
- トランザクションのCOMMITまたはROLLBACK
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++プリコンパイラの利点
図1-2のように、Pro*C/C++には多くの機能と利点があり、効果的で信頼性の高いアプリケーションの開発に役立ちます。
図1-2 機能と利点
画像の説明
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)関数を使用すること。
このように、Pro*C/C++は、充実した埋込みSQLプログラム技法をサポートする多機能ツールです。
よくある質問(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ランタイム・ライブラリ・コールが生成されます。
自殺者の何パーセントどこに1960年代の男性
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方法1」のデモ・プログラムを調整し、動的SQLを使用してください。
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=scott/tiger 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++では以前の名前もサポートされています。これらのスレッド・セーフなパブリック関数(およびその旧称)の詳細は、表5-3「SQLLIBパブリック関数 - 新しい名前」を参照してください。
新しいオブジェクト型はOracle9iでどのようにサポートされていますか。
Pro*C/C++アプリケーションでオブジェクト型を使用する方法については、第17章「オブジェクト」および第19章「Object Type Translator(OTT)」を参照してください。
互換性、アップグレードおよび移行
Pro*C/C++では、リリース9.0.1より、OCI8ベースのアプリケーションと同様の互換性規則を採用します。特に、Oracle9i Pro*C/C++クライアントはOracle8iサーバー(8.1.6.3、V817x)をサポートします。この場合、下位互換性に対するOCI8の制限と同じ制限が適用されます。このようなアプリケーションの機能は、Oracle8iによりサポートされている機能に限定されます。Oracle9iサーバー機能を利用するアプリケーションには、下位互換性はありません。
Oracle8iサーバーを使用するOracle9i Pro*C/C++クライアントに関する問題は、オラクル社カスタマ・サポート・センターにご連絡ください。
0 コメント:
コメントを投稿