Oracle Pro*C/C++

Pro*C/C++とは

Pro*C/C++とは、Oracleデータベースを利用するプログラムをC言語やC++で開発するための開発環境です。SQLを埋め込んだソースコードをプリコンパイルすることで、C言語やC++のソースコードへ変換することができます。

Oracle Pro*C プリコンパイラのサンプルソースコードを次に示します。

#include <stdio.h>

EXEC SQL INCLUDE SQLCA;

int main() {
  EXEC SQL BEGIN DECLARE SECTION;
  int ID
  char NAME[256];
  EXEC SQL END DECLARE SECTION;

  EXEC SQL connect to bookmark user dbuser;
  EXEC SQL insert into Name_list (id, name) values (:ID, :NAME);
  EXEC SQL commit;

  return 0;
}

埋め込みSQLの概要

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

埋め込みSQL文はホスト言語で直接解釈することができないため、ホスト言語で扱えるように変換(APIに置き換えるなど)する必要がある。ホスト言語がCまたはC++言語の場合、この変換を行なうのがPro*C/C++プリコンパイラである。

コメント

SQL文で空白を挿入できる位置であれば、任意の位置にC言語形式のコメント(/* ... */)を記述することができる。また、SQL文の行末にはANSI形式のコメント(-- ...)も挿入できる。

EXEC SQL SELECT empno, ename
  INTO :emp_no, :e_name    -- ホスト変数出力
  FROM emp
  WHERE deptno = :dept_no;

CODE=CPPプリコンパイラ・オプションを使用してプリコンパイルする場合、C++形式のコメント(// ...)を使用できる。

ヘッダ・ファイルのインクルード

Pro*C/C++プリコンパイラではsqlca.horaca.hsqlda.hなどのヘッダ・ファイルを提供している。これらのヘッダ・ファイルをインクルードするには2通りの方法がある。

C言語の#includeプリプロセッサ・ディレクティブを使用してヘッダ・ファイルをインクルードするには、次のコードを追加する。

#include <sqlca.h>
#include <sqlda.h>
#include <oraca.h>

Pro*C/C++プリコンパリラのEXEC SQL INCLUDEコマンドを使用してヘッダ・ファイルをインクルードするには、次のコードを追加する。

EXEC SQL INCLUDE SQLCA;
EXEC SQL INCLUDE SQLDA;
EXEC SQL INCLUDE ORACA;

ホスト変数の宣言

ホスト変数の宣言は、C言語で変数を宣言できる所ならどこでも宣言できる。グローバル宣言してもよいし、関数内でローカル宣言してもよい。

ホスト変数の宣言は、EXEC SQL BEGIN DECLARE SECTION; で始め、EXEC SQL END DECLARE SECTION; で終了する。

EXEC SQL BEGIN DECLARE SECTION;
/* ホスト変数の宣言 */
int code;
char name[40];
EXEC SQL END DECLARE SECTION;

埋め込みSQL文(組み込みSQL文)の中でホスト変数を使用するには、変数名の前に : (コロン)をつける。

データベースへの接続

データの問い合わせや操作をする前に、Pro*C/C++プログラムをデータベースに接続する必要がある。データベースに接続するにはCONNECT文を使用する。

Oracleの外部データ型

Oracle外部データ型には、入力ホスト変数および出力ホスト変数に値を格納するのに使う形式を指定する。外部データ型を次に示す。

Oracleの外部データ型
名前 説明
CHAR 255バイト以下の固定長文字列
CHARF CHARのデフォルトをVARCHAR2またはCHARZではなくCHAR にするために、TYPE文またはVAR文で使用する
CHARZ 65534バイト以下のNULL終了符号をつけた固定長文字列
DATE 固定長日付/時刻値、7バイト
FLOAT 実数
INTEGER 符号付き整数
LONG 固定長文字列、2**31~1バイトまで
LONG RAW 2**31-1バイト以下の固定長バイナリ・データ
LONG VARCHAR 可変長文字列、<=2**31-5バイト
LONG VARRAW 可変長バイナリ・データ、<=2**31-5バイト
MLSLABEL オペレーティング・システム・ラベルのタグ、2~5バイト(Trusted Oracleの場合のみ)
NUMBER 2進浮動小数点形式で表した10進数
RAW 65533バイト以下の固定長バイナリ・データ
ROWID バイナリ値、外部の長さはシステムによって異なる
STRING NULL終了記号をつけた可変長文字列
UNSIGNED 符号無し整数
VARCHAR 65535バイト以下の可変長文字列
VARCHAR2 64KB以下の可変長文字列
VARNUM 10進数、NUMBERと同様だが表現の長さのコンポーネントが含まれる
VARRAW 65533バイト以下の可変長バイナリ・データ

デフォルトでは、Pro*C/C++ プリコンパイラはすべてのホスト変数に特定の外部データ型を割り当てます。デフォルトの割り当てを次に示します。

Cの型または疑似型 Oracle外部型
char
char[n]
char *
VARCHAR2 (DBMS=V6のデフォルト)
CHARZ (DBMS=V7, DBMS=V8のデフォルト)
int
int *
INTEGER
short
short *
INTEGER
long
long *
INTEGER
float
float *
FLOAT
double
double *
FLOAT
VARCHAR
VARCHAR[n]
VARCHAR

CHAR_MAPプリコンパイラ・コマンド行オプションを使って、char[n]およびcharホスト変数のデフォルトのマッピングを指定することもできます。CHAR_MAPの設定を次に示します。

CHAR_MAP の設定 説明
VARCHAR2 値が(NULLを含む)固定長の空白埋め。
CHARZ 固定長の空白埋めおよびゼロ終了記号付き。ANSI変数文字型に準拠。
STRING ゼロ終了記号付き。Cプログラムで使われているASCIIZ形式に準拠。
CHARF 固定長の空白埋め。NULLは左側に埋め込まれない。ANSI固定文字列型に準拠。

VARCHAR型ホスト変数の宣言は次のように行なう。

VARCHAR identifier[n];

Pro*C/C++プリコンパリラにより、上記のソースプログラムは次のように展開される。

struct {
  unsigned short len;
  unsigned char arr[n];
} identifier;

lenは文字列の長さを格納する変数、arrは文字列を格納する配列である。

ホストプログラムからVARCHAR型ホスト変数に文字列を渡す場合、lenに文字列の長さを格納する必要がある。

オラクルからVARCHAR型ホスト変数に文字列が渡される場合、lenに文字列の長さが入っている。

プリコンパイル

Pro*C/C++プリコンパイラとは、Pro*C/C++のソースプログラムファイルをプリコンパイルする実行プログラムである。Pro*C/C++プリコンパイラの実行方法を次に示す。

proc option=value ...

ソースプログラムファイルfoo.pcをプリコンパイルする例を示す。

$ proc INAME=example.pc

Pro*C/C++プリコンパイラのソースプログラムファイルのデフォルト拡張子は.pcである。このデフォルト拡張子.pcは、指定を省略することができる。つまり、上記の例は次のようにすることもできる。

$ proc INAME=example

procの引数はoption=valueの形式で指定するが、入力ファイルを表すINAMEだけは例外的に省略できる。つまり、次のように指定することができる。

$ proc example.pc

この場合もソースプログラムファイルのデフォルト拡張子.pcは省略できる。

$ proc example

EXEC SQL CONNECT

データベースへログインする。

構文

EXEC SQL CONNECT { :user IDENTIFIED BY :password | :user_string } [ AT :db_name ] ;

パラメータ

user
ユーザー名を格納したホスト変数の名前
password
パスワードを格納したホスト変数の名前
user_string
ユーザー名とパスワードをスラッシュ(/)で区切って格納したホスト変数の名前
db_name
接続先のデータベース名を格納したホスト変数の名前。AT句を省略した場合、デフォルトのデータベースに接続する。

ユーザー名とパスワードを別々のホスト変数で指定する例を次に示す。

サンプル・コード

EXEC SQL BEGIN DECLARE SECTION;
char username[32];
char password[32];
EXEC SQL END DECLARE SECTION;

strcpy(username, "scott");
strcpy(password, "tiger");

EXEC SQL CONNECT :username IDENTIFIED BY :password;

ユーザー名とパスワードをひとつのホスト変数で指定する例を次に示す。

EXEC SQL BEGIN DECLARE SECTION;
varchar uid[32];
EXEC SQL END DECLARE SECTION;

strcpy(uid.arr, "scott/tiger");
uid.len = strlen(uid.arr);

EXEC SQL CONNECT :uid;

EXEC SQL SELECT

問い合せを行い、選択した値をホスト変数に格納する。

構文

EXEC SQL SELECT select_list INTO :host_variable [ , ... ] FROM table_list [ WHERE condition ] ;

パラメータ

host_variable
選択リスト内の各項目に割り当てるホスト変数の名前

サンプル・コード

EXEC SQL SELECT ename, deptno
       INTO :e_name, :dept_no
       FROM emp
       WHERE empno = 1;

クライアントの静的ライブラリ(libclntst11.a)を作成する

クライアントの静的ライブラリ(libclntst11.a)は、Oracleデータベースをインストールしたときに生成されない。作成するアプリケーションをクライアントの静的ライブラリにリンクする場合は、静的ライブラリを生成する必要がある。静的ライブラリを生成する手順を次に示す。

  1. ユーザoracleでログインする。
  2. $ORACLE_HOME/bin/genclntstを実行する。

クライアントの静的ライブラリ(libclntst11.a)を生成する例を示す。

$ $ORACLE_HOME/bin/genclntst
ar: /opt/app/oracle/product/11.2.0/db_64/lib/libclntst11.a を作成中です。
Created /opt/app/oracle/product/11.2.0/db_64/lib/libclntst11.a
$

PL/SQLとの違い

PL/SQLで作成したプログラムは、Oracleデータエース内に格納され、データベースサーバ上で実行される。

Pro*C/C++で作成したプログラムは、データベースクライアントとなる。そのため、Oracleデータベースにアクセスできる環境であれば、データベースサーバ以外でも動作できる。