日本語PDF

1 概要

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

1.1 Oracleプリコンパイラ

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

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

図1-1の説明が続きます
「図1-1 埋込みSQLプログラムの開発」の説明

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

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

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

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

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

1.3 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に切り替えることができます。

1.4 PL/SQLを使用する理由

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

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

関連項目

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

図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 Studio .NET 2002/2003のサポート。

このように、Pro*C/C++は、充実した埋込みSQLプログラム技法をサポートする多機能ツールです。

注意:

Pro*C/C++では16ビット・コードの生成はサポートされません。

1.6 ディレクトリ構造

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ファイル

\lib\msvc

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

\mesg

メッセージ・ファイル

\public

ヘッダー・ファイル

注意:

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

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

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

  • proc iname=test one.pc

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

1.7 ライブラリ・ファイル

Pro*C/C++アプリケーションをリンクするとき、ライブラリ・ファイルを使用します。Pro*C/C++ライブラリ・ファイルは、次のようにインストールされます。

ORACLE_HOME\precomp\LIB\orasql12.lib
ORACLE_HOME\precomp\LIB\ottclasses.zip
ORACLE_HOME\precomp\LIB\msvc\orasqx12.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とリンクする必要があります。

1.8 よくある質問(FAQ)

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

1.8.1 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]バイトの文字配列からなる構造体として生成されます。

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

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

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

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

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

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

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

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

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

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

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

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

通常、SQL文またはPL/SQL文中の式を使用できるところであれば、任意の位置にホスト変数を使用できます。

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

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

問題を解決するには、動的SQLを使用する必要があります。これを実行するために応用できるデモ・プログラムとしてサンプル・プログラム: 動的SQL方法1があります。

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

多数のオプションがありますが、簡単に説明します。第1に、従来のプリコンパイラおよびOracle7との互換性が必要な場合は、VARCHAR[n]ホスト変数を使用するのが最も安全な方法です。

Pro*C/C++では、他のすべての文字変数のデフォルト・データ型はCHARZです。つまり、入力時には文字列をヌル文字で終了する必要があります。出力時には空白文字で埋められ、ヌル文字で終了されます。

リリース8.0では、文字変数のデフォルト・マッピングを指定できるように、CHAR_MAPプリコンパイラ・オプションが追加されています。

アプリケーションでVARCHARもCHARZも不適切であり、全面的にC言語と同様の(ヌル文字で終了するが空白文字で埋められない)動作が必要な場合は、TYPEコマンドとC言語のtypedef文を使用し、データ型の同値化を使用して文字ホスト変数を文字列に変換してください。TYPEコマンドの使用方法を示すサンプル・プログラムについては、サンプル・プログラム: sqlvcp()の使用を参照してください。

1.8.8 文字ポインタについて何か特別なことはありますか。

はい。Pro*C/C++では、入力ホスト変数または出力ホスト変数をバインドするときに、その長さを認識する必要があります。VARCHAR[n]を使用するか、char[n]型のホスト変数を宣言すると、Pro*C/C++では宣言から長さが認識されます。ただし、プログラム内で文字ポインタをホスト変数として使用し、malloc()を使用してバッファを定義すると、Pro*C/C++では長さが認識されません。

出力時には、バッファを割り当てるだけでなく、ヌル文字でない文字を埋め込んでからヌル文字で終了する必要があります。入力時または出力時、Pro*C/C++は長さを取得するために、バッファについてstrlen()をコールします。

関連項目

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

SPOOLはSQL*Plusで使用される特殊なコマンドです。埋込みSQLコマンドではありません。

1.8.10 サンプル・プログラムのオンライン版はどこにありますか。

Oracleのインストール時には、demoディレクトリが作成されます。このディレクトリがないか、あってもサンプル・プログラムが含まれていない場合は、システム管理者またはデータベース管理者に連絡してください。

1.8.11 アプリケーションをコンパイルしてリンクする方法を教えてください。

コンパイルとリンクの方法は、プラットフォームごとに異なります。Pro*C/C++アプリケーションをリンクする方法については、システム固有のOracleマニュアルを参照してください。UNIXシステムでは、demoディレクトリにdemo_proc.mkというMakeファイルがあります。たとえば、デモ・プログラムsample1.pcをリンクするには、次のコマンドラインを入力します。

make -f demo_proc.mk sample1

特殊なプリコンパイラ・オプションを使用する必要がある場合は、Pro*C/C++を別に実行してからmakeを実行します。または、独自のカスタムMakeファイルを作成することもできます。たとえば、プログラムに埋込みPL/SQLコードが含まれている場合は、次のように入力します。

proc cv_demo userid=username/password sqlcheck=semantics
make -f demo_proc.mk build OBJS=sample1.o EXE=sample1

VMSシステムには、Pro*C/C++アプリケーションをリンクできるように、LNPROCというスクリプトが用意されています。

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

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

1つの構造体の内部で複数の配列を使用できます。また、構造体の配列を配列インタフェースとともに使用できます。

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

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

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

データベース・サーバーに対してプリコンパイラまたはOCIアプリケーションを実行する場合、Oracleでは、クライアント・ソフトウェア・リリース以降のリリースのデータベース・サーバー・ソフトウェアを使用することをお勧めしますが、この構成が厳密に必要なわけではありません。たとえば、Oracle Databaseクライアント・ソフトウェアがリリース8.1.7である場合、サーバーに対してクライアント上でプリコンパイラ・アプリケーションを実行するには、リリース8.1.7以降のOracle Databaseサーバー・ソフトウェアを使用することをお薦めします。

アプリケーションのアップグレードの詳細は、『Oracle Databaseアップグレード・ガイド』を参照してください。

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

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

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

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

関連項目

1.8.16 すべての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パブリック関数です。すべての新規アプリケーションで、これらの関数を使用します。これらのスレッド・セーフなパブリック関数(およびその旧称)の詳細は、SQLLIBパブリック関数の新しい名前を参照してください。

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

Pro*C/C++アプリケーションでのオブジェクト型の使用方法は、オブジェクトおよびObject Type Translator (OTT)を参照してください。

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

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