Jet Engineのキャッシュとその制御
非同期(トランザクションなし)の場合、実際に書き込み動作が始まるのは、[1] Write Cacheが、レジストリのMaxBufferSizeに指定したサイズを超えたとき、もしくは、[2] 最後の書込み動作以降にFlushTransactionTimeoutに設定された時間が経過したときであり、このうちどちらか短い方の条件が成立したときになります。
マルチユーザー環境などで、書き込み遅延が発生しては困るときには、同期書き込みを利用します。同期書き込みを行なうには、BeginTrans ~ CommitTransという、明示的なトランザクションを利用します。CommitTransを実行すると、遅延なしにディスクに書き込みが行なわれます。トランザクションは、DAOではWorkspaceの、ADOではConnectionのメソッドです。
gridview の更新が出来ない。
ACC2000: DBEngine.Idle dbRefreshCache の最新の情報に更新がないイミディエイト
月曜日, 10月 18, 2010
日曜日, 9月 26, 2010
[VB.NET]Browsable(False)ではプロパティウィンドウから「GenerateMember」「Locked」「Modifiers」が非表示にできない
▼質問
BrowsableAttributeクラスの属性を使ってユーザーコントロールのプロパティを
[プロパティ]ウィンドウから非表示にしたいんだ。
だけど、次のプロパティは非表示にできなかったんだ。
「GenerateMember」「Locked」「Modifiers」
良い方法があったら教えてくれ!
▼回答
次のコードを使うと実現できるから参考にしてくれ!!
BrowsableAttributeクラスの属性を使ってユーザーコントロールのプロパティを
[プロパティ]ウィンドウから非表示にしたいんだ。
だけど、次のプロパティは非表示にできなかったんだ。
「GenerateMember」「Locked」「Modifiers」
良い方法があったら教えてくれ!
▼回答
次のコードを使うと実現できるから参考にしてくれ!!
Imports System.ComponentModel.Design
Imports System.ComponentModel
<Designer(GetType(SampleDesigner), GetType(IDesigner))> _
Public Class UserControl1
End Class
Public Class SampleDesigner
Inherits System.Windows.Forms.Design.ParentControlDesigner
Private _unneededProperties As String() = {"GenerateMember", "Locked", "Modifiers"}
Protected Overrides Sub PostFilterProperties(ByVal properties As IDictionary)
For Each prop As String In _unneededProperties
properties.Remove(prop)
MyBase.PostFilterProperties(properties)
Next
End Sub
End Class
土曜日, 9月 25, 2010
[VB.NET]ユーザーコントロール(UserControl)のコントロール追加(コンテナ化)
▼質問
VB6からVB.NETに移行している作業で
独自のユーザーコントロール(UserControl)を作成したんだが
そのコントロールがデザイン時にコントロールを追加しようとしても
親子関係(コンテナ化)が結べないんだ。
VB6では、「ControlContainer」プロパティを設定すると
ユーザーコントロールがコンテナ化する事ができたと思うんだけど・・・。
VB.NETではどうするか教えてくれ!
▼回答
DesignerAttributeクラスの属性を使って実現することができるんだ。
そのコードを次に示しておくから参考にしてくれ!
■参考サイト
ユーザーコントロールにコントロールを追加するには - Insider .NET会議室
ユーザーコントロールのコンテナ - BIGLOBEなんでも相談室
VB 6.0 ユーザーのための VB .NET 移行ガイド - 標準コントロール
VB6からVB.NETに移行している作業で
独自のユーザーコントロール(UserControl)を作成したんだが
そのコントロールがデザイン時にコントロールを追加しようとしても
親子関係(コンテナ化)が結べないんだ。
VB6では、「ControlContainer」プロパティを設定すると
ユーザーコントロールがコンテナ化する事ができたと思うんだけど・・・。
VB.NETではどうするか教えてくれ!
▼回答
DesignerAttributeクラスの属性を使って実現することができるんだ。
そのコードを次に示しておくから参考にしてくれ!
Imports System.ComponentModel.Design
Imports System.ComponentModel
<Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", GetType(IDesigner))> _
Public Class UserControl
End Class
■参考サイト
ユーザーコントロールにコントロールを追加するには - Insider .NET会議室
ユーザーコントロールのコンテナ - BIGLOBEなんでも相談室
VB 6.0 ユーザーのための VB .NET 移行ガイド - 標準コントロール
月曜日, 9月 20, 2010
[VB.NET]プロパティウィンドウの非表示・インテリセンス(IntelliSense)の非表示ができない
▼質問
ユーザーコントロールで次のことしていた時に
・プロパティウィンドウ非表示
・インテリセンス(IntelliSense)非表示
ツールチップに次のメッセージが出てコードが書けないんだ。
「キーワードは、識別子として有効ではありません。」
どうしたらよいか教えてくれ!
▼回答
予約済みのキーワードは、[]角括弧で囲えばいいんだ。
ユーザーコントロールで次のことしていた時に
・プロパティウィンドウ非表示
・インテリセンス(IntelliSense)非表示
ツールチップに次のメッセージが出てコードが書けないんだ。
「キーワードは、識別子として有効ではありません。」
どうしたらよいか教えてくれ!
▼回答
予約済みのキーワードは、[]角括弧で囲えばいいんだ。
Private _Default As Object = Nothing
<Browsable(False), EditorBrowsable(EditorBrowsableState.Never)> _
Public Property [Default]() As Object
Get
Return _Default
End Get
Set(ByVal value As Object)
_Default = value
End Set
End Property
<EditorBrowsable(EditorBrowsableState.Never)> _
Public Shadows [Select]()
水曜日, 9月 15, 2010
[VB2010]カスタムコントロール作成
火曜日, 8月 03, 2010
土曜日, 7月 31, 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
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 OraText *poolName;
static sb4 poolNameLen;
//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;
OCISPool *spoolhp;
OCIThreadId *thrid[MAXTHREAD];
OCIThreadHandle *thrhp[MAXTHREAD];
static int employeeNum[MAXTHREAD];
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 );
sword threadFunction( dvoid *arg );
void threadFunctionEnd( OCISvcCtx *svchp, OCIError *errhp, OCIStmt *stmthp, sword status );
int main( int argc, char* argv[] )
{
sword ret = 0;
sword no = 1;
int i = 0;
ub4 connMin = 1; // 最小セッションプール数(有効値:0以上)
ub4 connMax = 5; // 最大セッションプール数(有効値:1以上)
ub4 connIncr = 1; // 増分セッションプール数(有効値:0以上)
OCIBind *bndhp[1]; // バインド・ハンドル
OCIDefine *defhp[6]; // 定義ハンドル
memset( bndhp, 0x00, sizeof( bndhp ) );
memset( defhp, 0x00, sizeof( defhp ) );
//ret = OCIInitialize( (ub4)(OCI_THREADED | OCI_OBJECT), (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 = OCIEnvCreate( (OCIEnv **)&envhp, (ub4)OCI_THREADED, (dvoid *)0,
( dvoid * (*)(dvoid *, size_t) )0,
( dvoid * (*)(dvoid *, dvoid *, size_t) )0,
( void (*)(dvoid *, dvoid *) )0, (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 **)&spoolhp, (ub4)OCI_HTYPE_SPOOL, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
checkerr( NULL, ret );
cleanup();
return ret;
}
/* CREATE THE SESSION POOL */
// OCI_DEFAULT:通常。
// OCI_SPC_REINITIALIZE:セッション・プールの作成後、プール属性を動的に変更する場合(connMin、connMax、connIncrの各パラメータを変更する場合)。
// OCI_SPC_HOMOGENEOUS:全セッションが引数のユーザー名とパスワードを使用して認証。
ret = OCISessionPoolCreate( envhp, errhp, spoolhp,
(OraText **)&poolName, (ub4 *)&poolNameLen,
(CONST OraText *)database, (ub4)strlen( (char*)database ),
connMin, connMax, connIncr,
(CONST OraText *)username, (ub4)strlen( (char*)username ),
(CONST OraText *)password, (ub4)strlen( (char*)password ),
OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}
{
OCIThreadProcessInit();
ret = OCIThreadInit( envhp, errhp );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
for ( i = 0 ; i < MAXTHREAD ; i++ ) {
ret = OCIThreadIdInit( envhp, errhp, &thrid[i] );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
ret = OCIThreadHndInit( envhp, errhp, &thrhp[i] );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
}
for ( i = 0 ; i < MAXTHREAD ; i++ ) {
employeeNum[i] = i;
ret = OCIThreadCreate( envhp, errhp, threadFunction, (dvoid *)&employeeNum[i], thrid[i], thrhp[i] );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
}
for ( i = 0 ; i < MAXTHREAD ; i++ ) {
// コールスレッド結合
checkerr( errhp, OCIThreadJoin( envhp, errhp, thrhp[i] ) );
// スレッド・ハンドルクローズ
checkerr( errhp, OCIThreadClose( envhp, errhp, thrhp[i] ) );
// スレッド・ハンドル破棄・割当て解除
checkerr( errhp, OCIThreadHndDestroy( envhp, errhp, &(thrhp[i]) ) );
// スレッドID破棄・割当て解除
checkerr( errhp, OCIThreadIdDestroy( envhp, errhp, &(thrid[i]) ) );
}
// OCIThreadコンテキスト割当てメモリー解放
checkerr( errhp, OCIThreadTerm( envhp, errhp ) );
if ( spoolhp ) {
checkerr( errhp, OCISessionPoolDestroy( spoolhp, errhp, (ub4)OCI_DEFAULT ) );
checkerr( NULL, OCIHandleFree( (dvoid *)spoolhp, (ub4)OCI_HTYPE_SPOOL ) );
}
}
// 終了処理
cleanup();
return 0;
}
sword threadFunction( dvoid *arg )
{
sword ret = 0;
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;
int empno = *(int *)arg;
OCISvcCtx *svchp = (OCISvcCtx *)arg;
OCIStmt *stmthp = (OCIStmt *)0;
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 ) );
// モード選択型ログイン
// OCI_DEFAULT:シングルセッション・ログイン。OCILogon()と同等。
// OCI_LOGON2_CPOOL:接続プーリングを使用する場合に設定する。
// OCI_LOGON2_SPOOL:セッション・プーリングを使用する場合に設定する。
// OCI_LOGON2_STMTCACHE:文キャッシュを使用可能にする。
// OCI_LOGON2_PROXY:プロキシ認証を使用可能にする。
ret = OCILogon2( envhp, errhp, (OCISvcCtx **)&svchp,
(CONST OraText *)username, (ub4)strlen( (char *)username ),
(CONST OraText *)password, (ub4)strlen( (char *)password ),
(CONST OraText *)poolName, (ub4)poolNameLen,
(ub4)OCI_LOGON2_SPOOL );
if ( ret != OCI_SUCCESS ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
return ret;
}
/* ■テーブル操作開始 */
// 文ハンドル割当て
ret = OCIHandleAlloc( (dvoid *)envhp, (dvoid **)&stmthp, (ub4)OCI_HTYPE_STMT, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
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 ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
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 );
// 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 ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
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 ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
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 ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
break;
}
}
}
}
// シングルセッション・ログオフ
ret = OCILogoff( svchp, errhp );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
return ret;
}
/*
* スレッド処理.
*/
void threadFunctionEnd( OCISvcCtx *svchp, OCIError *errhp, OCIStmt *stmthp, sword status )
{
sword ret = 0;
checkerr( errhp, status );
if ( stmthp ) {
// 文ハンドル解放
checkerr( NULL, OCIHandleFree( (dvoid *)stmthp, (ub4)OCI_HTYPE_STMT ) );
}
/* ■データベース接続終了 */
// シングルセッション・ログオフ
ret = OCILogoff( svchp, errhp );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
}
/*
* チェックエラー処理.
*/
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()
{
int i = 0;
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;
}
金曜日, 6月 18, 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
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 OraText *poolName;
static sb4 poolNameLen;
//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;
OCICPool *poolhp;
OCIThreadId *thrid[MAXTHREAD];
OCIThreadHandle *thrhp[MAXTHREAD];
static int employeeNum[MAXTHREAD];
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 );
sword threadFunction( dvoid *arg );
void threadFunctionEnd( OCISvcCtx *svchp, OCIError *errhp, OCIStmt *stmthp, sword status );
int main( int argc, char* argv[] )
{
sword ret = 0;
sword no = 1;
int i = 0;
ub4 connMin = 1; // 最小接続プール数(有効値:0以上)
ub4 connMax = 5; // 最大接続プール数(有効値:1以上)
ub4 connIncr = 1; // 増分接続プール数(有効値:0以上)
OCIBind *bndhp[1]; // バインド・ハンドル
OCIDefine *defhp[6]; // 定義ハンドル
memset( bndhp, 0x00, sizeof( bndhp ) );
memset( defhp, 0x00, sizeof( defhp ) );
//ret = OCIInitialize( (ub4)(OCI_THREADED | OCI_OBJECT), (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 = OCIEnvCreate( (OCIEnv **)&envhp, (ub4)OCI_THREADED, (dvoid *)0,
( dvoid * (*)(dvoid *, size_t) )0,
( dvoid * (*)(dvoid *, dvoid *, size_t) )0,
( void (*)(dvoid *, dvoid *) )0, (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 **)&poolhp, (ub4)OCI_HTYPE_CPOOL, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
checkerr( NULL, ret );
cleanup();
return ret;
}
/* CREATE THE CONNECTION POOL */
// OCI_DEFAULT:通常。
// OCI_CPOOL_REINITIALIZE:プール属性を動的に変更する場合(connMin、connMax、connIncrの各パラメータを変更する場合)。
ret = OCIConnectionPoolCreate( envhp, errhp, poolhp,
(OraText **)&poolName, (ub4 *)&poolNameLen,
(CONST OraText *)database, (ub4)strlen( (char*)database ),
connMin, connMax, connIncr,
(CONST OraText *)username, (ub4)strlen( (char*)username ),
(CONST OraText *)password, (ub4)strlen( (char*)password ),
OCI_DEFAULT );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
cleanup();
return ret;
}
{
OCIThreadProcessInit();
ret = OCIThreadInit( envhp, errhp );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
for ( i = 0 ; i < MAXTHREAD ; i++ ) {
ret = OCIThreadIdInit( envhp, errhp, &thrid[i] );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
ret = OCIThreadHndInit( envhp, errhp, &thrhp[i] );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
}
for ( i = 0 ; i < MAXTHREAD ; i++ ) {
employeeNum[i] = i;
ret = OCIThreadCreate( envhp, errhp, threadFunction, (dvoid *)&employeeNum[i], thrid[i], thrhp[i] );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
}
for ( i = 0 ; i < MAXTHREAD ; i++ ) {
// コールスレッド結合
checkerr( errhp, OCIThreadJoin( envhp, errhp, thrhp[i] ) );
// スレッド・ハンドルクローズ
checkerr( errhp, OCIThreadClose( envhp, errhp, thrhp[i] ) );
// スレッド・ハンドル破棄・割当て解除
checkerr( errhp, OCIThreadHndDestroy( envhp, errhp, &(thrhp[i]) ) );
// スレッドID破棄・割当て解除
checkerr( errhp, OCIThreadIdDestroy( envhp, errhp, &(thrid[i]) ) );
}
// OCIThreadコンテキスト割当てメモリー解放
checkerr( errhp, OCIThreadTerm( envhp, errhp ) );
if ( poolhp ) {
checkerr( errhp, OCIConnectionPoolDestroy( poolhp, errhp, (ub4)OCI_DEFAULT ) );
checkerr( NULL, OCIHandleFree( (dvoid *)poolhp, (ub4)OCI_HTYPE_CPOOL ) );
}
}
// 終了処理
cleanup();
return 0;
}
sword threadFunction( dvoid *arg )
{
sword ret = 0;
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;
int empno = *(int *)arg;
OCISvcCtx *svchp = (OCISvcCtx *)arg;
OCIStmt *stmthp = (OCIStmt *)0;
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 ) );
/* ■データベース接続開始 */
// モード選択型ログイン
// OCI_DEFAULT:シングルセッション・ログイン。OCILogon()と同等。
// OCI_LOGON2_CPOOL:接続プーリングを使用する場合に設定する。
// OCI_LOGON2_SPOOL:セッション・プーリングを使用する場合に設定する。
// OCI_LOGON2_STMTCACHE:文キャッシュを使用可能にする。
// OCI_LOGON2_PROXY:プロキシ認証を使用可能にする。
ret = OCILogon2( envhp, errhp, (OCISvcCtx **)&svchp,
(CONST OraText *)username, (ub4)strlen( (char *)username ),
(CONST OraText *)password, (ub4)strlen( (char *)password ),
(CONST OraText *)poolName, (ub4)poolNameLen,
(ub4)OCI_LOGON2_CPOOL );
if ( ret != OCI_SUCCESS ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
return ret;
}
/* ■テーブル操作開始 */
// 文ハンドル割当て
ret = OCIHandleAlloc( (dvoid *)envhp, (dvoid **)&stmthp, (ub4)OCI_HTYPE_STMT, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
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 ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
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 );
// 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 ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
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 ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
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 ) {
threadFunctionEnd( svchp, errhp, stmthp, ret );
break;
}
}
}
}
return ret;
}
/*
* スレッド処理.
*/
void threadFunctionEnd( OCISvcCtx *svchp, OCIError *errhp, OCIStmt *stmthp, sword status )
{
sword ret = 0;
checkerr( errhp, status );
if ( stmthp ) {
// 文ハンドル解放
checkerr( NULL, OCIHandleFree( (dvoid *)stmthp, (ub4)OCI_HTYPE_STMT ) );
}
/* ■データベース接続終了 */
// シングルセッション・ログオフ
ret = OCILogoff( svchp, errhp );
if ( ret != OCI_SUCCESS ) {
checkerr( errhp, ret );
}
}
/*
* チェックエラー処理.
*/
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()
{
int i = 0;
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;
}
水曜日, 6月 16, 2010
[C言語・C++]OCIで次のエラー?!「kgepop: no error frame to pop to for error 21500」
▼質問
OCIThreadからOCIConnectionPoolを使ってOCILogon2にログインすると次のエラーが出るんだ。
「kgepop: no error frame to pop to for error 21500」
どうしてこうなるか教えてくれ!!
▼回答
OCIInitialize()をコールした時のmodeを確認してくれ!!
OCIThreadを使う時のmodeは、次の様な指定の仕方にするんだ。
「(ub4)(OCI_THREADED | OCI_OBJECT)」
OCIInitialize( (ub4)(OCI_THREADED | OCI_OBJECT), (dvoid *)0,
( dvoid * (*)(dvoid *, size_t) )0,
( dvoid * (*)(dvoid *, dvoid *, size_t) )0,
( void (*)(dvoid *, dvoid *) )0 );
OCIEnvCreate()をコールした時の指定の仕方。
OCIEnvCreate( (OCIEnv **)&envhp, (ub4)OCI_THREADED, (dvoid *)0,
( dvoid * (*)(dvoid *, size_t) )0,
( dvoid * (*)(dvoid *, dvoid *, size_t) )0,
( void (*)(dvoid *, dvoid *) )0, (size_t)0, (dvoid **)0 );
■参考サイト
Re: kgepop: no error frame to pop to for error 21500
Oracle ABC Wiki: Ora 19999 Ora 24279 Jp
OCIThreadからOCIConnectionPoolを使ってOCILogon2にログインすると次のエラーが出るんだ。
「kgepop: no error frame to pop to for error 21500」
どうしてこうなるか教えてくれ!!
▼回答
OCIInitialize()をコールした時のmodeを確認してくれ!!
OCIThreadを使う時のmodeは、次の様な指定の仕方にするんだ。
「(ub4)(OCI_THREADED | OCI_OBJECT)」
OCIInitialize( (ub4)(OCI_THREADED | OCI_OBJECT), (dvoid *)0,
( dvoid * (*)(dvoid *, size_t) )0,
( dvoid * (*)(dvoid *, dvoid *, size_t) )0,
( void (*)(dvoid *, dvoid *) )0 );
OCIEnvCreate()をコールした時の指定の仕方。
OCIEnvCreate( (OCIEnv **)&envhp, (ub4)OCI_THREADED, (dvoid *)0,
( dvoid * (*)(dvoid *, size_t) )0,
( dvoid * (*)(dvoid *, dvoid *, size_t) )0,
( void (*)(dvoid *, dvoid *) )0, (size_t)0, (dvoid **)0 );
■参考サイト
Re: kgepop: no error frame to pop to for error 21500
Oracle ABC Wiki: Ora 19999 Ora 24279 Jp
[C言語・C++]OCI(Oracle Call Interface)サンプル(OCILogon版)
次のテーブルを使用したシングルセッション・ログイン(OCILogon)のサンプルを示す。
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
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;
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 **)&svchp, (ub4)OCI_HTYPE_SVCCTX, (size_t)0, (dvoid **)0 );
if ( ret != OCI_SUCCESS ) {
checkerr( NULL, ret );
cleanup();
return ret;
}
// シングルセッション・ログイン
ret = OCILogon( envhp, errhp, (OCISvcCtx **)&svchp,
(OraText *)username, (ub4)strlen( (char *)username ),
(OraText *)password, (ub4)strlen( (char *)password ),
(OraText *)database, (ub4)strlen( (char*)database ) );
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 );
}
}
}
}
/* ■データベース接続終了 */
// シングルセッション・ログオフ
ret = OCILogoff( svchp, errhp );
if ( ret != OCI_SUCCESS ) {
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 ( 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;
}
土曜日, 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
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;
}
土曜日, 4月 17, 2010
[C言語・C++]OCI(Oracle Call Interface)メモ
■検索サイト
otndnld.oracle.co.jpのサイト内検索
■参考サイト
http://otn.oracle.co.jp/sample_code/db_connect/oci/oci3.txt
http://otndnld.oracle.co.jp/tech/db_connect/pdf/oci8.pdf
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/appdev.102/B19246-02/oci02bas.htm#i462054
http://blog.npo-mash.org/i/?itemid=73189&catid=9898
http://forums.oracle.com/forums/thread.jspa?threadID=839708&tstart=180
http://otn.oracle.co.jp/forum/thread.jspa?threadID=28001059&tstart=1768
http://wakuteka.sakura.ne.jp/diary/
http://itref.fc2web.com/oracle/oci.html
http://blog.csdn.net/fjcailei/archive/2009/06/17/4276450.aspx
■簡易メモ
・問合せから行をフェッチする関数OCIStmtFetch()は使わない方が良いようだ。代わりに
OCIStmtFetch2()を使うことをオラクルのサイトでは薦めている。その他のOCIリレーショナル関数
・Prepareは、OCIStmtPrepare()よりOCIStmtPrepare2()を使用した方が処理速度が速くなる。
otndnld.oracle.co.jpのサイト内検索
■参考サイト
http://otn.oracle.co.jp/sample_code/db_connect/oci/oci3.txt
http://otndnld.oracle.co.jp/tech/db_connect/pdf/oci8.pdf
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/appdev.102/B19246-02/oci02bas.htm#i462054
http://blog.npo-mash.org/i/?itemid=73189&catid=9898
http://forums.oracle.com/forums/thread.jspa?threadID=839708&tstart=180
http://otn.oracle.co.jp/forum/thread.jspa?threadID=28001059&tstart=1768
http://wakuteka.sakura.ne.jp/diary/
http://itref.fc2web.com/oracle/oci.html
http://blog.csdn.net/fjcailei/archive/2009/06/17/4276450.aspx
■簡易メモ
・問合せから行をフェッチする関数OCIStmtFetch()は使わない方が良いようだ。代わりに
OCIStmtFetch2()を使うことをオラクルのサイトでは薦めている。その他のOCIリレーショナル関数
・Prepareは、OCIStmtPrepare()よりOCIStmtPrepare2()を使用した方が処理速度が速くなる。
日曜日, 3月 21, 2010
[JavaScript]XMLHttpRequestのstatusで「エラーを特定できません」のエラーが出る!
▼質問
XMLHttpRequestのstatusで次のJavaScriptエラーが出るんだ!
「エラーを特定できません」
どうしてかわかるかい?
プログラムはこんな感じだ。
簡単に説明すると
非同期(Async)通信でサーバにある適当なファイルを
使って動作確認をするプログラムを作成したんだ。
request変数でXMLHttpRequestオブジェクトを取得して
div要素に各情報を出力しているプログラムなんだ。
request.onreadystatechange = function() {
document.getElementById( "request_readyState" ).innerHTML = request.readyState;
document.getElementById( "request_status" ).innerHTML = request.status;
if ( (request.readyState == 4) && (request.status == 200) ) {
document.getElementById( "request_result" ).innerHTML = "正常";
}
else {
document.getElementById( "request_result" ).innerHTML = "異常";
}
}
request.open( "POST", url, true );
request.send("");
次の行でエラーになるんだ。
「document.getElementById( "request_status" ).innerHTML = request.status;」
▼回答
onreadystatechangeイベントは、XMLHttpRequestオブジェクトの
ready状態(readyState)が変化したときに発生するため、
XMLHttpRequestオブジェクトのstatusを取得する時は、
readyStateを考慮する必要があるんだ。
0 = uninitialized(初期化されてない)
1 = loading(読み込み中)
2 = loaded(読み込み完了)
3 = interactive(相互通信可能)
4 = complete(全ての処理が完了した)
すると、次の様なプログラムになるから参考にしてみてくれ!
request.onreadystatechange = function() {
document.getElementById( "request_readyState" ).innerHTML = request.readyState;
if ( request.readyState == 4 ) {
document.getElementById( "request_status" ).innerHTML = request.status;
if ( request.status == 200 ) {
document.getElementById( "request_result" ).innerHTML = "正常";
}
else {
document.getElementById( "request_result" ).innerHTML = "異常";
}
}
}
request.open( "POST", url, true );
request.send("");
■参考サイト
XMLHttpRequest
Status codes in HTTP
XMLHttpRequestのstatusで次のJavaScriptエラーが出るんだ!
「エラーを特定できません」
どうしてかわかるかい?
プログラムはこんな感じだ。
簡単に説明すると
非同期(Async)通信でサーバにある適当なファイルを
使って動作確認をするプログラムを作成したんだ。
request変数でXMLHttpRequestオブジェクトを取得して
div要素に各情報を出力しているプログラムなんだ。
request.onreadystatechange = function() {
document.getElementById( "request_readyState" ).innerHTML = request.readyState;
document.getElementById( "request_status" ).innerHTML = request.status;
if ( (request.readyState == 4) && (request.status == 200) ) {
document.getElementById( "request_result" ).innerHTML = "正常";
}
else {
document.getElementById( "request_result" ).innerHTML = "異常";
}
}
request.open( "POST", url, true );
request.send("");
次の行でエラーになるんだ。
「document.getElementById( "request_status" ).innerHTML = request.status;」
▼回答
onreadystatechangeイベントは、XMLHttpRequestオブジェクトの
ready状態(readyState)が変化したときに発生するため、
XMLHttpRequestオブジェクトのstatusを取得する時は、
readyStateを考慮する必要があるんだ。
0 = uninitialized(初期化されてない)
1 = loading(読み込み中)
2 = loaded(読み込み完了)
3 = interactive(相互通信可能)
4 = complete(全ての処理が完了した)
すると、次の様なプログラムになるから参考にしてみてくれ!
request.onreadystatechange = function() {
document.getElementById( "request_readyState" ).innerHTML = request.readyState;
if ( request.readyState == 4 ) {
document.getElementById( "request_status" ).innerHTML = request.status;
if ( request.status == 200 ) {
document.getElementById( "request_result" ).innerHTML = "正常";
}
else {
document.getElementById( "request_result" ).innerHTML = "異常";
}
}
}
request.open( "POST", url, true );
request.send("");
■参考サイト
XMLHttpRequest
Status codes in HTTP
日曜日, 3月 14, 2010
[JavaScript]XMLHttpRequestの使用方法
▼質問
JavaScriptを使って簡単にWEBサーバの状態を監視したいんだ。
何かいい方法はないか教えてくれないか!
▼回答
それなら、XMLHttpRequestを使うとできると思うよ。
簡単な手順とサンプルを教えてあげるから参考にしてくれ!
① XMLHttpRequestオブジェクト生成(IE用とそれ以外で処理分岐)
② 非同期通信の時は、onreadystatechangeイベントの登録
③ openメソッドを使って、サーバへのリクエスト方法を指定
④ sendメソッドを使って、サーバへのリクエストする(データ送信)
⑤ readyStateプロパティを使ってサーバからデータを受信できたか調べる
⑥ statusプロパティを使って正常に取得できたか調べる
⑦ responseText・responseXMLプロパティを使って受信データを処理する
同期(Sync)通信
非同期(Async)通信
出力
■参考サイト
IEのonreadystatechangeイベントハンドラは、1回しか反応しないんでしょうか? - Yahoo!知恵袋
JavaScriptを使って簡単にWEBサーバの状態を監視したいんだ。
何かいい方法はないか教えてくれないか!
▼回答
それなら、XMLHttpRequestを使うとできると思うよ。
簡単な手順とサンプルを教えてあげるから参考にしてくれ!
① XMLHttpRequestオブジェクト生成(IE用とそれ以外で処理分岐)
② 非同期通信の時は、onreadystatechangeイベントの登録
③ openメソッドを使って、サーバへのリクエスト方法を指定
④ sendメソッドを使って、サーバへのリクエストする(データ送信)
⑤ readyStateプロパティを使ってサーバからデータを受信できたか調べる
⑥ statusプロパティを使って正常に取得できたか調べる
⑦ responseText・responseXMLプロパティを使って受信データを処理する
同期(Sync)通信
function send_sync() {
var now = new Date();
var url = "test.jsp?NOW_DATE=" + now;
var ret = false;
var request = null;
if ( window.XMLHttpRequest ) {
// Mozilla, Safari, etc
request = new XMLHttpRequest();
}
else if ( window.ActiveXObject ) {
// IE
try {
request = new ActiveXObject( "Msxml2.XMLHTTP" );
} catch (e) {
try {
request = new ActiveXObject( "Microsoft.XMLHTTP" );
} catch (e) {}
}
}
if ( !request ) {
alert( 'Giving up :( Cannot create an XMLHTTP instance' );
return;
}
request.open( "POST", url, false );
request.send("");
document.getElementById( "request_readyState" ).innerHTML = request.readyState;
document.getElementById( "request_status" ).innerHTML = request.status;
if ( (request.readyState == 4) && (request.status == 200) ) {
request_Headers.innerHTML = request.getAllResponseHeaders();
document.getElementById( "result_post" ).innerHTML = "正常";
}
else {
document.getElementById( "result_post" ).innerHTML = "異常";
}
}
非同期(Async)通信
function send_async() {
var now = new Date();
var url = "test.jsp?NOW_DATE=" + now;
var ret = false;
var request = null;
if ( window.XMLHttpRequest ) {
// Mozilla, Safari, etc
request = new XMLHttpRequest();
}
else if ( window.ActiveXObject ) {
// IE
try {
request = new ActiveXObject( "Msxml2.XMLHTTP" );
} catch (e) {
try {
request = new ActiveXObject( "Microsoft.XMLHTTP" );
} catch (e) {}
}
}
if ( !request ) {
alert( 'Giving up :( Cannot create an XMLHTTP instance' );
return;
}
request.onreadystatechange = function() {
document.getElementById( "request_readyState" ).innerHTML = request.readyState;
if ( request.readyState == 4 ) {
document.getElementById( "request_status" ).innerHTML = request.status;
if ( request.status == 200 ) {
request_Headers.innerHTML = request.getAllResponseHeaders();
document.getElementById( "result_post" ).innerHTML = "正常";
}
else {
document.getElementById( "result_post" ).innerHTML = "異常";
}
}
}
request.open( "POST", url, true );
request.send("");
}
出力
結果:<div id="request_result"></div>
readyState:<div id="request_readyState"></div>
status:<div id="request_status"></div>
ResponseHeaders:<div id="request_Headers"></div>
■参考サイト
IEのonreadystatechangeイベントハンドラは、1回しか反応しないんでしょうか? - Yahoo!知恵袋
木曜日, 3月 11, 2010
[Excel]相対位置にある合計範囲をコピーでリンク
▼質問
ある列のデータ範囲に相対位置で合計したい範囲が12点づつあるんだ。
その合計だけをあるセルに一列で並べたいんだ。
どうやったらできるか教えてくれ!!
▼回答
OFFSET関数とROW関数で実現できるよ!
E列に12点づつ合計したいものがあるとする。
その合計をA1からリストすると次の様になる。
A1=SUM(OFFSET($E$1,12*(ROW()-1),0*1,12,1))
A2=SUM(OFFSET($E$1,12*(ROW()-1),0*1,12,1))
A3=SUM(OFFSET($E$1,12*(ROW()-1),0*1,12,1))
:
:
A1だけコピぺして後はセルのコピーで簡単にできるよ!!
ある列のデータ範囲に相対位置で合計したい範囲が12点づつあるんだ。
その合計だけをあるセルに一列で並べたいんだ。
どうやったらできるか教えてくれ!!
▼回答
OFFSET関数とROW関数で実現できるよ!
E列に12点づつ合計したいものがあるとする。
その合計をA1からリストすると次の様になる。
A1=SUM(OFFSET($E$1,12*(ROW()-1),0*1,12,1))
A2=SUM(OFFSET($E$1,12*(ROW()-1),0*1,12,1))
A3=SUM(OFFSET($E$1,12*(ROW()-1),0*1,12,1))
:
:
A1だけコピぺして後はセルのコピーで簡単にできるよ!!
金曜日, 2月 26, 2010
[Java]JSPでサーバーOSの判定
▼質問
JSPファイルが文字化けするんだ。
Windowsで開発している環境では文字化けの対応をしたんだが
Linuxで動かすと文字化けしてしまうんだ。
そこで、JSPでサーバーOSの判定をして処理を分けたいんだ。
どうしたら、サーバーのOSを判定できるか教えてくれないか?
▼回答
次の様にやれば判定は可能だよ!
参考にしてくれ!!
JSPファイルが文字化けするんだ。
Windowsで開発している環境では文字化けの対応をしたんだが
Linuxで動かすと文字化けしてしまうんだ。
そこで、JSPでサーバーOSの判定をして処理を分けたいんだ。
どうしたら、サーバーのOSを判定できるか教えてくれないか?
▼回答
次の様にやれば判定は可能だよ!
参考にしてくれ!!
if ( System.getProperty( "os.name" ).toLowerCase().indexOf("win") > -1 ) {
// Windows
}
else {
// Windows以外
}
日曜日, 2月 21, 2010
[JavaScript]ブラウザの閉じるボタン([×]ボタン)
▼質問
ブラウザの閉じるボタン([×]ボタン)を押されても
閉じない方法(キャンセルする方法)はないのかな?
▼回答
閉じない方法(キャンセルする方法)はないけど
閉じる前に自分のウィンドウを出し直す方法で
閉じないようにすることはできるよ。
サンプルを作ってみたから参考にしてくれ!!
CloseTest.htmlファイルを作成する。
ブラウザの閉じるボタン([×]ボタン)を押されても
閉じない方法(キャンセルする方法)はないのかな?
▼回答
閉じない方法(キャンセルする方法)はないけど
閉じる前に自分のウィンドウを出し直す方法で
閉じないようにすることはできるよ。
サンプルを作ってみたから参考にしてくれ!!
CloseTest.htmlファイルを作成する。
<html>
<head>
<script language="javascript">
<!--
var flag = true;
-->
</script>
</head>
<body onBeforeUnload="if ( flag ) alert( 'ブラウザの[×]ボタンでは、閉じることはできません。\n[閉じる]ボタンを使用してください。' );" onUnload="if ( flag ) window.open( 'CloseTest.html' );">
<input type="button" value="閉じる" onClick="flag = false; window.close();">
</body>
</html>
火曜日, 2月 09, 2010
[VBA]IADsでの削除方法
▼質問
文字列で扱われている情報を削除したいんだ。
次ぎ様にしたんだがうまく削除されないんだ。
IADs.PutEx ADS_PROPERTY_DELETE, PropertyItem, vbNullString
どうしてかわかるかな?
▼回答
次の様にしていたらどうかな?
IADs.PutEx ADS_PROPERTY_CLEAR, PropertyItem, vbNullString
文字列で扱われている情報を削除したいんだ。
次ぎ様にしたんだがうまく削除されないんだ。
IADs.PutEx ADS_PROPERTY_DELETE, PropertyItem, vbNullString
どうしてかわかるかな?
▼回答
次の様にしていたらどうかな?
IADs.PutEx ADS_PROPERTY_CLEAR, PropertyItem, vbNullString
月曜日, 2月 01, 2010
[VBA]IADsで「オートメーション エラーです。エラーを特定できません」のエラーがでる
▼質問
Active Directory(Active DS Type Libray)のPutメソッドを使って
下記の関数を作ったら次のエラーが出る。
「オートメーション エラーです。エラーを特定できません (-2147467259)」
どうしてなんだ。
▼回答
PutメソッドのPropertyValue値の型がVariantじゃないと出るエラーなんだ。
IADs.Put PropertyItem, PropertyValue
だから、次の様にしないといけないんだ。
Private Sub SetIADsValue(ByVal IADs As Object, ByVal PropertyItem As String, ByVal PropertyValue As Variant)
Active Directory(Active DS Type Libray)のPutメソッドを使って
下記の関数を作ったら次のエラーが出る。
Private Sub SetIADsValue(ByVal IADs As Object,
ByVal PropertyItem As String,
ByVal PropertyValue As String)
On Error GoTo doError
IADs.Put PropertyItem, PropertyValue
Exit Sub
doError:
Debug.Print (Err.Description & "(" & Err.Number & ")")
End Sub
「オートメーション エラーです。エラーを特定できません (-2147467259)」
どうしてなんだ。
▼回答
PutメソッドのPropertyValue値の型がVariantじゃないと出るエラーなんだ。
IADs.Put PropertyItem, PropertyValue
だから、次の様にしないといけないんだ。
Private Sub SetIADsValue(ByVal IADs As Object, ByVal PropertyItem As String, ByVal PropertyValue As Variant)
木曜日, 1月 21, 2010
Active Directoryメモ
■OU:組織単位(Organizational Unit)
■Active Directoryオブジェクト:
ユーザー・オブジェクト、グループ・オブジェクト、コンピュータ・オブジェクト
■識別名(DN):
/O=Internet/DC=COM/DC=Microsoft/CN=Users/CN=James Smith
このDNは、Microsoft.comドメイン内のJames Smithユーザーオブジェクトを識別。
■O:Organization
■DC:Domain Component
■CN:Common Name
■CN=Users:Usersコンテナ
■CN=Computers:Computersコンテナ
■相対識別名(RDN):
/O=Internet/DC=COM/DC=Microsoft/CN=Users/CN=James Smith
CN=James SmithがJames SmithユーザーオブジェクトのRDN。親オブジェクトのRDNはCN=Users。
■GUID(Globally Unique Identifier):一意性が保証された 128 ビットの番号
■ユーザープリンシパル名(UPN):
ユーザー名およびユーザーオブジェクトの所属先ドメインツリーのDSN名を"略記"した名前。
microsoft.comツリー内のユーザーJames SmithのUPNは、JamesS@Microsoft.comなどとなる。
■ADSI(Active Directory Service Interfaces):
ユーザーがLDAP通信の詳細を意識せずにActive Directoryにアクセスできるようになるシンプルかつ
強力なオブジェクト指向インターフェイスを提供するAPI。
■参考サイト
Active Directory 技術概要
スクリプト一覧 : Active Directory
Active Directoryオブジェクトの識別名(DN)とは - @IT
csvdeコマンド - 管理者必見! ネットワーク・コマンド集:ITpro
■Active Directoryオブジェクト:
ユーザー・オブジェクト、グループ・オブジェクト、コンピュータ・オブジェクト
■識別名(DN):
/O=Internet/DC=COM/DC=Microsoft/CN=Users/CN=James Smith
このDNは、Microsoft.comドメイン内のJames Smithユーザーオブジェクトを識別。
■O:Organization
■DC:Domain Component
■CN:Common Name
■CN=Users:Usersコンテナ
■CN=Computers:Computersコンテナ
■相対識別名(RDN):
/O=Internet/DC=COM/DC=Microsoft/CN=Users/CN=James Smith
CN=James SmithがJames SmithユーザーオブジェクトのRDN。親オブジェクトのRDNはCN=Users。
■GUID(Globally Unique Identifier):一意性が保証された 128 ビットの番号
■ユーザープリンシパル名(UPN):
ユーザー名およびユーザーオブジェクトの所属先ドメインツリーのDSN名を"略記"した名前。
microsoft.comツリー内のユーザーJames SmithのUPNは、JamesS@Microsoft.comなどとなる。
■ADSI(Active Directory Service Interfaces):
ユーザーがLDAP通信の詳細を意識せずにActive Directoryにアクセスできるようになるシンプルかつ
強力なオブジェクト指向インターフェイスを提供するAPI。
■参考サイト
Active Directory 技術概要
スクリプト一覧 : Active Directory
Active Directoryオブジェクトの識別名(DN)とは - @IT
csvdeコマンド - 管理者必見! ネットワーク・コマンド集:ITpro
登録:
投稿 (Atom)