Google
 
Web itpro-blogger.blogspot.com
土曜日, 5月 15, 2010

[C言語・C++]OCI(Oracle Call Interface)サンプル

次のテーブルを使用したサンプルを示す。

CREATE TABLE TEST_TBL (
"NO" NUMBER(3), /* 番号 */
"DT_NUMBER" NUMBER(12,2), /* NUMBER型 */
"DT_CHAR" CHAR(10), /* CHAR型 */
"DT_VARCHAR2" VARCHAR2(32), /* VARCHAR2型 */
"DT_DATE" DATE /* DATE型 */
)

①追加のインクルードディレクトリ
インストールされたoracleパス\product\10.2.0\db_1\OCI\include

②追加のライブラリディレクトリ
インストールされたoracleパス\product\10.2.0\db_1\OCI\lib\MSVC

③追加の依存ファイル
oci.lib kernel32.lib msvcrt.lib




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>

typedef struct _OCI_TIMESTAMP_STRUCT
{
short year;
unsigned short month;
unsigned short day;
unsigned short hour;
unsigned short minute;
unsigned short second;
unsigned long fraction;
} OCI_TIMESTAMP_STRUCT_T;

typedef OCI_TIMESTAMP_STRUCT_T OCI_TIME;

static text *database = (text *)"データベース名";
static text *username = (text *)"ユーザー名";
static text *password = (text *)"パスワード";

//static text *SEL_TEST_TBL = (text *) "SELECT * FROM TEST_TBL WHERE NO = :NO";
static text *SEL_TEST_TBL = (text *) "SELECT * FROM TEST_TBL ORDER BY NO";

static OCIEnv *envhp;
static OCIError *errhp;
OCISession *authp = (OCISession *)0;
OCIServer *srvhp;
OCISvcCtx *svchp;
OCIStmt *stmthp;

static sword checkerr( OCIError *errhp, sword status );
static void cleanup(/*_ void _*/);

sword OCI_DefineByPos( OCIStmt *stmtp, OCIDefine **defnp, OCIError *errhp,
ub4 position, dvoid *valuep, sb4 value_sz,
ub2 dty, dvoid *indp, ub2 *rlenp, ub2 *rcodep, ub4 mode );
sword OCI_GetDataNumber( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, OCINumber *TargetValuePtr );
sword OCI_GetDataInt( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, int *TargetValuePtr );
sword OCI_GetDataShort( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, short *TargetValuePtr );
sword OCI_GetDataLong( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, long *TargetValuePtr );
sword OCI_GetDataFloat( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, float *TargetValuePtr );
sword OCI_GetDataDouble( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, double *TargetValuePtr );
sword OCI_GetDataChar( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, char *TargetValuePtr, unsigned int BufferLength );
sword OCI_GetDataTimeStamp( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, OCIDate *TargetValuePtr );


int main( int argc, char* argv[] )
{
sword ret = 0;
sword no = 1;
int out_no = 0;
OCINumber out_number;
int out_int = 0;
short out_short = 0;
long out_long = 0;
float out_float = 0;
double out_double = 0;
char out_char[10+1];
char out_varchar2[32+1];
OCIDate out_date;
OCI_TIME out_time;
long rows = 0;

OCIBind *bndhp[1]; // バインド・ハンドル
OCIDefine *defhp[6]; // 定義ハンドル

memset( bndhp, 0x00, sizeof( bndhp ) );
memset( defhp, 0x00, sizeof( defhp ) );
memset( out_char, 0x00, sizeof( out_char ) );
memset( out_varchar2, 0x00, sizeof( out_varchar2 ) );
memset( &out_date, 0x00, sizeof( out_date ) );
memset( &out_time, 0x00, sizeof( OCI_TIME ) );

ret = OCIInitialize( (ub4)OCI_DEFAULT, (dvoid *)0,
( dvoid * (*)(dvoid *, size_t) )0,
( dvoid * (*)(dvoid *, dvoid *, size_t) )0,
( void (*)(dvoid *, dvoid *) )0 );
if ( ret != OCI_SUCCESS ) {
checkerr( NULL, ret );
return ret;
}

ret = OCIEnvInit( (OCIEnv **)&envhp, (ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
checkerr( NULL, ret );
return ret;
}

ret = OCIHandleAlloc( (dvoid *)envhp, (dvoid **) &errhp, (ub4)OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
checkerr( NULL, ret );
return ret;
}

/* ■データベース接続開始 */

// サーバー・ハンドル割当て
ret = OCIHandleAlloc( (dvoid *)envhp, (dvoid **)&srvhp, (ub4)OCI_HTYPE_SERVER, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
checkerr( NULL, ret );
cleanup();
return ret;
}

// サーバー・コンテキスト・ハンドル割当て
ret = OCIHandleAlloc( (dvoid *)envhp, (dvoid **)&svchp, (ub4)OCI_HTYPE_SVCCTX, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
checkerr( NULL, ret );
cleanup();
return ret;
}

// データソースの連結(アタッチ)。サーバー・コンテキスト・ハンドルの初期化
ret = OCIServerAttach( srvhp, errhp, (text *)database, (ub4)strlen( (char*)database ), (ub4)0 );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}

// サーバー・ハンドルにサーバー・コンテキスト・ハンドルの連結(アタッチ)設定
ret = OCIAttrSet( (dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX, (dvoid *)srvhp,
(ub4)0, (ub4)OCI_ATTR_SERVER, errhp );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}

// ユーザー・セッション・ハンドル割当て
ret = OCIHandleAlloc( (dvoid *)envhp, (dvoid **)&authp, (ub4)OCI_HTYPE_SESSION, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
checkerr( NULL, ret );
cleanup();
return ret;
}

// ユーザー名設定
ret = OCIAttrSet( (dvoid *)authp, (ub4)OCI_HTYPE_SESSION,
(dvoid *)username, (ub4)strlen( (char *)username ), (ub4)OCI_ATTR_USERNAME, errhp );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}

// パスワード設定
ret = OCIAttrSet( (dvoid *)authp, (ub4)OCI_HTYPE_SESSION,
(dvoid *)password, (ub4)strlen( (char *)password ), (ub4)OCI_ATTR_PASSWORD, errhp );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}

// ユーザー・セッション開始
ret = OCISessionBegin( svchp, errhp, authp, (ub4)OCI_CRED_RDBMS, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}

// サーバー・コンテキスト・ハンドルのセッション設定
ret = OCIAttrSet( (dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX, (dvoid *)authp,
(ub4)0, (ub4)OCI_ATTR_SESSION, errhp );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}

/* ■テーブル操作開始 */

// 文ハンドル割当て
ret = OCIHandleAlloc( (dvoid *)envhp, (dvoid **)&stmthp, (ub4)OCI_HTYPE_STMT, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}

// 実行するSQL文・PL/SQL文の準備
ret = OCIStmtPrepare( stmthp, errhp, (OraText *)SEL_TEST_TBL, (ub4)strlen( (char*)SEL_TEST_TBL ),
(ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}

/* ■WHERE句の変数定義 */

// 入力変数のバインド
//ret = OCIBindByName( stmthp, (OCIBind **)&bndhp[0], errhp,
// (OraText *)":NO", (sb4)strlen( ":NO" ), (dvoid *)&no, (sb4)sizeof( sword ),
// (ub2)SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, (ub4)OCI_DEFAULT );
//if ( ret != OCI_SUCCESS ) {
// checkerr( errhp, ret );
// cleanup();
// return ret;
//}

// SQL文・PL/SQL文のサーバー送信実行
ret = OCIStmtExecute( svchp, stmthp, errhp, (ub4)0, (ub4)0,
(CONST OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}

/* ■出力変数の定義 */

// NUMBER(3,0)型データ取得
(void)OCI_GetDataInt( stmthp, errhp, 1, &out_no );

// NUMBER(12,2)型データ取得

// OCINumber型で取得
//(void)OCI_GetDataNumber( stmthp, errhp, 2, &out_number );

// int型で取得
(void)OCI_GetDataInt( stmthp, errhp, 2, &out_int );

// short型で取得
(void)OCI_GetDataShort( stmthp, errhp, 2, &out_short );

// long型で取得
(void)OCI_GetDataLong( stmthp, errhp, 2, &out_long );

// float型で取得
//(void)OCI_GetDataFloat( stmthp, errhp, 2, &out_float );

// double型で取得
//(void)OCI_GetDataDouble( stmthp, errhp, 2, &out_double );

// CHAR型データ取得
(void)OCI_GetDataChar( stmthp, errhp, 3, (char*)&out_char, sizeof( out_char ) );

// VARCHAR2型データ取得
(void)OCI_GetDataChar( stmthp, errhp, 4, (char*)&out_varchar2, sizeof( out_varchar2 ) );

// DATE型データ取得
(void)OCI_GetDataTimeStamp( stmthp, errhp, 5, &out_date );

// 問合せから行の読込み実行
ret = OCIStmtFetch( stmthp, errhp, (ub4)1, (ub2)OCI_FETCH_NEXT, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}
else {
while ( (OCI_NO_DATA != ret) && (OCI_SUCCESS_WITH_INFO != ret) )
{
rows++;
printf( "[%03d],[%d],[%d],[%d],[%13.2f],[%13.2f],[%s],[%s],[%04d/%02d/%02d %02d:%02d:%02d]\n",
out_no, out_int, out_short, out_long, out_float, out_double, out_char, out_varchar2,
out_date.OCIDateYYYY, out_date.OCIDateMM, out_date.OCIDateDD, out_date.OCIDateTime.OCITimeHH, out_date.OCIDateTime.OCITimeMI, out_date.OCIDateTime.OCITimeSS );
// 問合せから行の読込み実行
ret = OCIStmtFetch( stmthp, errhp, (ub4)1, (ub2)OCI_FETCH_NEXT, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
if ( OCI_NO_DATA != ret ) {
checkerr( errhp, ret );
}
}
}
}

/* ■データベース接続終了 */

// 終了処理
cleanup();

return 0;
}


/*
* チェックエラー処理.
*/
sword checkerr( OCIError *errhp, sword status )
{
text errbuf[512];
sb4 errcode = 0;

switch ( status )
{
case OCI_SUCCESS:
// 関数は正常に終了しました。
break;
case OCI_SUCCESS_WITH_INFO:
// 関数は正常に終了しました。OCIErrorGet()をコールすると、追加診断情報が戻されます。
// これには、警告が含まれる場合があります。
(void)printf( "Error - OCI_SUCCESS_WITH_INFO\n" );
break;
case OCI_NEED_DATA:
// アプリケーションで、ランタイム・データを提供する必要があります。
(void)printf( "Error - OCI_NEED_DATA\n" );
break;
case OCI_NO_DATA:
// 関数が終了しました。これ以上データはありません。
(void)printf( "Error - OCI_NODATA\n" );
break;
case OCI_ERROR:
// 関数が失敗しました。OCIErrorGet()をコールすると、エラーの追加情報が戻されます。
if ( errhp ) {
(void)OCIErrorGet( (dvoid *)errhp, (ub4)1, (text *)NULL, &errcode, errbuf, (ub4)sizeof( errbuf ), OCI_HTYPE_ERROR );
(void)printf( "Error - %.*s\n", 512, errbuf );
}
else {
(void)printf( "Error - OCI_ERROR\n" );
}
break;
case OCI_INVALID_HANDLE:
// 無効なハンドルがパラメータとして渡されたか、ユーザー・コールバックで無効なハンドルまたは無効なコンテキストが渡されました。
// 追加診断情報はありません。
(void)printf( "Error - OCI_INVALID_HANDLE\n" );
break;
case OCI_STILL_EXECUTING:
// サービス・コンテキストが非ブロック化モードで確立されたため、現行の操作は即時完了できませんでした。
// この操作を完了するには、これを再度コールする必要があります。OCIErrorGet()がエラー・コードとしてORA-03123を戻します。
(void)printf( "Error - OCI_STILL_EXECUTE\n" );
break;
case OCI_CONTINUE:
// このコードはコールバック関数からのみ戻されます。
// これは、コールバック関数が、OCIライブラリの標準処理再開を示唆していることを示します。
(void)printf( "Error - OCI_CONTINUE\n" );
break;
default:
break;
}
return status;
}

/*
* 終了処理.
*/
void cleanup()
{
if ( stmthp ) {
// 文ハンドル解放
checkerr( NULL, OCIHandleFree( (dvoid *)stmthp, (ub4)OCI_HTYPE_STMT ) );
}
if ( authp ) {
// セッション終了
checkerr( errhp, OCISessionEnd( svchp, errhp, authp, (ub4)OCI_DEFAULT ) );
// ユーザー・セッション・ハンドル解放
checkerr( NULL, OCIHandleFree( (dvoid *)authp, (ub4)OCI_HTYPE_SESSION ) );
}
if ( srvhp ) {
// サーバー・ハンドルからサーバー・コンテキスト・ハンドルの連結解除(サーバー・コンテキスト・ハンドル未初期化)
checkerr( errhp, OCIServerDetach( srvhp, errhp, (ub4)OCI_DEFAULT ) );
// サーバー・ハンドル解放
checkerr( NULL, OCIHandleFree( (dvoid *)srvhp, (ub4)OCI_HTYPE_SERVER ) );
}
if ( svchp ) {
// サーバー・コンテキスト・ハンドル解放
checkerr( NULL, OCIHandleFree( (dvoid *)svchp, (ub4)OCI_HTYPE_SVCCTX ) );
}
if ( errhp ) {
// エラー・ハンドル解放
checkerr( NULL, OCIHandleFree( (dvoid *)errhp, (ub4)OCI_HTYPE_ERROR ) );
}
if ( envhp ) {
// 環境ハンドル解放
checkerr( NULL, OCIHandleFree( (dvoid *)envhp, (ub4)OCI_HTYPE_ENV ) );
}
// プロセスの終了と共有メモリー解放
checkerr( NULL, OCITerminate( OCI_DEFAULT ) );
return;
}

/*
* 出力変数定義処理.
*/
sword OCI_DefineByPos( OCIStmt *stmtp, OCIDefine **defhp, OCIError *errhp,
ub4 position, dvoid *valuep, sb4 value_sz,
ub2 dty, dvoid *indp, ub2 *rlenp, ub2 *rcodep, ub4 mode )
{
sword ret = OCIDefineByPos( stmtp, defhp, errhp, position, valuep, value_sz, dty, indp, rlenp, rcodep, mode );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}
return ret;
}


/*
* OCINumber型データ取得処理.
*/
sword OCI_GetDataNumber( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, OCINumber *TargetValuePtr )
{
sword ret = 0;
OCIDefine *defhp = NULL; // 定義ハンドル

ret = OCIDefineByPos( stmtp, (OCIDefine **)&defhp, errhp, (ub4)ColumnNumber, (dvoid*)TargetValuePtr, (sb4)sizeof( OCINumber ), SQLT_VNU, (dvoid *)0, (ub2)0, (ub2)0, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
return ret;
}

return ret;
}

/*
* int型データ取得処理.
*/
sword OCI_GetDataInt( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, int *TargetValuePtr )
{
sword ret = 0;
OCIDefine *defhp = NULL; // 定義ハンドル

ret = OCIDefineByPos( stmtp, (OCIDefine **)&defhp, errhp, (ub4)ColumnNumber, (dvoid*)TargetValuePtr, (sb4)sizeof( int ), SQLT_INT, (dvoid *)0, (ub2)0, (ub2)0, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
return ret;
}

return ret;
}

/*
* short型データ取得処理.
*/
sword OCI_GetDataShort( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, short *TargetValuePtr )
{
sword ret = 0;
OCIDefine *defhp = NULL; // 定義ハンドル

ret = OCIDefineByPos( stmtp, (OCIDefine **)&defhp, errhp, (ub4)ColumnNumber, (dvoid*)TargetValuePtr, (sb4)sizeof( short ), SQLT_INT, (dvoid *)0, (ub2)0, (ub2)0, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
return ret;
}

return ret;
}

/*
* long型データ取得処理.
*/
sword OCI_GetDataLong( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, long *TargetValuePtr )
{
sword ret = 0;
OCIDefine *defhp = NULL; // 定義ハンドル

ret = OCIDefineByPos( stmtp, (OCIDefine **)&defhp, errhp, (ub4)ColumnNumber, (dvoid*)TargetValuePtr, (sb4)sizeof( long ), SQLT_INT, (dvoid *)0, (ub2)0, (ub2)0, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
return ret;
}

return ret;
}

/*
* float型データ取得処理.
*/
sword OCI_GetDataFloat( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, float *TargetValuePtr )
{
sword ret = 0;
OCIDefine *defhp = NULL; // 定義ハンドル

ret = OCIDefineByPos( stmtp, (OCIDefine **)&defhp, errhp, (ub4)ColumnNumber, (dvoid*)TargetValuePtr, (sb4)sizeof( float ), SQLT_BFLOAT, (dvoid *)0, (ub2)0, (ub2)0, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
return ret;
}

return ret;
}

/*
* double型データ取得処理.
*/
sword OCI_GetDataDouble( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, double *TargetValuePtr )
{
sword ret = 0;
OCIDefine *defhp = NULL; // 定義ハンドル

ret = OCIDefineByPos( stmtp, (OCIDefine **)&defhp, errhp, (ub4)ColumnNumber, (dvoid*)TargetValuePtr, (sb4)sizeof( double ), SQLT_BDOUBLE, (dvoid *)0, (ub2)0, (ub2)0, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
return ret;
}

return ret;
}

/*
* char型データ取得処理.
*/
sword OCI_GetDataChar( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, char *TargetValuePtr, unsigned int BufferLength )
{
sword ret = 0;
OCIDefine *defhp = NULL; // 定義ハンドル

memset( TargetValuePtr, 0x00, BufferLength );

ret = OCIDefineByPos( stmtp, (OCIDefine **)&defhp, errhp, (ub4)ColumnNumber, (dvoid*)TargetValuePtr, (sb4)BufferLength, SQLT_STR, (dvoid *)0, (ub2)0, (ub2)0, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
return ret;
}

return ret;
}

/*
* OCIDate型データ取得処理.
*/
sword OCI_GetDataTimeStamp( OCIStmt *stmtp, OCIError *errhp, int ColumnNumber, OCIDate *TargetValuePtr )
{
sword ret = 0;
OCIDefine *defhp = NULL; // 定義ハンドル

ret = OCIDefineByPos( stmtp, (OCIDefine **)&defhp, errhp, (ub4)ColumnNumber, (dvoid *)TargetValuePtr, (sb4)sizeof( OCIDate ), SQLT_ODT, (dvoid *)0, (ub2)0, (ub2)0, (ub4)OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
return ret;
}

return ret;
}




This page is powered by Blogger. Isn't yours?