TimesTenデータベース接続の管理
TimesTenデータベース接続を管理する方法について説明します。
TimesTen接続の概要
ODBCアプリケーションは、属性(ホストやポート番号など)またはデータソース名(DSN)のいずれかを参照してデータベースに接続できます。TimesTen Classicでは、ユーザーはDSNを直接作成できます。TimesTen Scaleoutでは、グリッドに定義する接続可能オブジェクトごとにDSNが作成されます。
この項では、TimesTen接続に関する基本事項をいくつか説明し、詳細の参照先を示します。
TimesTen Scaleoutの場合の、データベース作成方法、および直接接続またはクライアント/サーバー接続の使用によるデータベースへの接続方法の詳細は、Oracle TimesTen In-Memory Database Scaleoutユーザーズ・ガイドを参照してください。データベースの作成およびデータベースへの接続を参照してください。
TimesTen Classicの場合の、データベースのDSNの作成方法の詳細は、Oracle TimesTen In-Memory Databaseオペレーション・ガイドを参照してください。作成するDSNのタイプは、アプリケーションがデータベースに直接接続するか、クライアント接続するかによって異なります。
-
データベースに直接接続する予定の場合は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のTimesTenデータベースの管理を参照してください。LinuxまたはUNIXから、あるいはWindowsから、直接接続するためのDSNの作成方法に関する説明があります。
-
データベースへのクライアント接続を作成する予定の場合は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のTimesTenクライアントおよびサーバーの使用を参照してください。LinuxまたはUNIXから、あるいはWindowsから、クライアント/サーバー接続を行うためのDSNの作成方法に関する説明があります。
ノート:
-
TimesTenでは、ユーザー名およびパスワードは、データベースに接続するための
CREATE SESSION権限を付与されている有効なユーザーのものである必要があります。 -
TimesTen接続は、親プロセスから継承することはできません。プロセスが子プロセスを作成(分岐)する前にデータベース接続をオープンした場合、子プロセスではそのデータベース接続を使用しないでください。
SQLConnect関数、SQLDriverConnect関数、SQLAllocConnect関数、SQLDisconnect関数
データベースへの接続、接続のメモリーの割当て、データベースからの切断に使用できるODBC関数を示します。
-
SQLConnect: ドライバをロードしてデータベースに接続します。接続ハンドルは、ステータス、トランザクションの状態、結果およびエラー情報などの接続情報が格納される場所を指します。次に、
SQLConnectコール・シーケンスを示します。SQLRETURN SQLConnect( SQLHDBC ConnectionHandle, SQLCHAR * ServerName, SQLSMALLINT NameLength1, SQLCHAR * UserName, SQLSMALLINT NameLength2, SQLCHAR * Authentication, SQLSMALLINT NameLength3); -
SQLDriverConnect:SQLConnectでサポートされている情報(データソース(データベース)、ユーザー名およびパスワード)よりも詳細な情報が必要な場合に、SQLConnectのかわりに使用します。次に、
SQLDriverConnectコール・シーケンスを示します。SQLRETURN SQLDriverConnect( SQLHDBC ConnectionHandle, SQLHWND WindowHandle, SQLCHAR * InConnectionString, SQLSMALLINT StringLength1, SQLCHAR * OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength2Ptr, SQLUSMALLINT DriverCompletion); -
SQLAllocConnect: 指定した環境内の接続ハンドルにメモリーを割り当てます。次に、
SQLAllocConnectコール・シーケンスを示します。SQLRETURN SQLAllocConnect( SQLHENV EnvironmentHandle, SQLHDBC PointerToConnectionHandle); -
SQLDisconnect: データベースから切断します。既存の接続ハンドルを唯一の引数として使用します。次に、
SQLDisconnectコール・シーケンスを示します。SQLRETURN SQLDisconnect( SQLHDBC ConnectionHandle);
これらの関数の詳細は、ODBC APIのリファレンス・マニュアルを参照してください。
デフォルトDSNの使用
次に、デフォルトのDSNが使用される状況を示します。
TimesTen Classicでは、defaultという名前が付けられているデフォルトDSNは、odbc.iniファイルまたはsys.odbc.iniファイルで定義できます。『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のTimesTen ClassicでのデフォルトDSNの設定を参照してください。
SQLConnectでは、デフォルトのDSNが定義されている場合は、次の状況でそれが使用されます。
-
ServerNameで、見つからないデータソースが指定されている場合。 -
ServerNameがNULLポインタの場合。 -
defaultがサーバー名として指定されている場合。ユーザー名と認証値はそのまま使用します。
SQLDriverConnectでは、デフォルトのDSNが定義されている場合は、次の状況でそれが使用されます。
-
接続文字列に
DSNキーワードが含まれていない場合。 -
データ・ソースが見つからない場合。
-
defaultがDSNキーワードとして指定されている場合。ユーザー名とパスワードはそのまま使用します。
直接モードまたは汎用ドライバ・マネージャを備えたクライアント/サーバー・モードの場合、次の使用上のノートに注意してください。
-
汎用ドライバ・マネージャを使用していない場合、TimesTenがこの機能を管理します。デフォルトDSNは、TimesTenデータベースである必要があります。
-
汎用ドライバ・マネージャを使用している場合、ドライバ・マネージャがこの機能を管理します。デフォルトDSNは、TimesTenデータベースである必要はありません。
データベースに対する接続および切断
データベースに対する接続および切断の方法について説明します。
このコード部分では、SQLConnectおよびSQLDisconnectを起動して、FixedDsというデータベースに対する接続および切断を行います。アプリケーションで初めてSQLConnectを起動すると、データベースFixedDsが作成されます。その後のSQLConnectの起動では、既存のデータベースに接続されます。
#include <timesten.h>
SQLRETURN retcode;
SQLHDBC hdbc;
...
retcode = SQLConnect(hdbc,
(SQLCHAR*)"FixedDs", SQL_NTS,
(SQLCHAR*)"johndoe", SQL_NTS,
(SQLCHAR*)"opensesame", SQL_NTS);
...
retcode = SQLDisconnect(hdbc);
...次に、データベースを作成し、データベースに接続し、その接続を切断する完成されたプログラムを示します。この例では、SQLConnectではなくSQLDriverConnectを使用して接続を設定し、SQLAllocConnectを使用してメモリーを割り当てます。また、エラー・メッセージの取得方法についても示します。(「エラー処理」も参考になる可能性があります。)
#include <timesten.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void chkReturnCode(SQLRETURN rc, SQLHENV henv,
SQLHDBC hdbc, SQLHSTMT hstmt,
char* msg, char* filename,
int lineno, BOOL err_is_fatal);
#define DEFAULT_CONNSTR "DSN=sampledb;PermSize=32"
int
main(int ac, char** av)
{
SQLRETURN rc = SQL_SUCCESS;
/* General return code for the API */
SQLHENV henv = SQL_NULL_HENV;
/* Environment handle */
SQLHDBC hdbc = SQL_NULL_HDBC;
/* Connection handle */
SQLHSTMT hstmt = SQL_NULL_HSTMT;
/* Statement handle */
SQLCHAR connOut[255];
/* Buffer for completed connection string */
SQLSMALLINT connOutLen;
/* Number of bytes returned in ConnOut */
SQLCHAR *connStr = (SQLCHAR*)DEFAULT_CONNSTR;
/* Connection string */
rc = SQLAllocEnv(&henv);
if (rc != SQL_SUCCESS) {
fprintf(stderr, "Unable to allocate an "
"environment handle\n");
exit(1);
}
rc = SQLAllocConnect(henv, &hdbc);
chkReturnCode(rc, henv, SQL_NULL_HDBC,
SQL_NULL_HSTMT,
"Unable to allocate a "
"connection handle\n",
__FILE__, __LINE__, 1);
rc = SQLDriverConnect(hdbc, NULL,
connStr, SQL_NTS,
connOut, sizeof(connOut),
&connOutLen,
SQL_DRIVER_NOPROMPT);
chkReturnCode(rc, henv, hdbc, SQL_NULL_HSTMT,
"Error in connecting to the"
" database\n",
__FILE__, __LINE__, 1);
rc = SQLAllocStmt(hdbc, &hstmt);
chkReturnCode(rc, henv, hdbc, SQL_NULL_HSTMT,
"Unable to allocate a "
"statement handle\n",
__FILE__, __LINE__, 1);
/* Your application code here */
if (hstmt != SQL_NULL_HSTMT) {
rc = SQLFreeStmt(hstmt, SQL_DROP);
chkReturnCode(rc, henv, hdbc, hstmt,
"Unable to free the "
"statement handle\n",
__FILE__, __LINE__, 0);
}
rc = SQLDisconnect(hdbc);
chkReturnCode(rc, henv, hdbc,
SQL_NULL_HSTMT,
"Unable to close the "
"connection\n",
__FILE__, __LINE__, 0);
rc = SQLFreeConnect(hdbc);
chkReturnCode(rc, henv, hdbc,
SQL_NULL_HSTMT,
"Unable to free the "
"connection handle\n",
__FILE__, __LINE__, 0);
rc = SQLFreeEnv(henv);
chkReturnCode(rc, henv, SQL_NULL_HDBC,
SQL_NULL_HSTMT,
"Unable to free the "
"environment handle\n",
__FILE__, __LINE__, 0);
return 0;
}
}
static void
chkReturnCode(SQLRETURN rc, SQLHENV henv,
SQLHDBC hdbc, SQLHSTMT hstmt,
char* msg, char* filename,
int lineno, BOOL err_is_fatal)
{
#define MSG_LNG 512
SQLCHAR sqlState[MSG_LNG];
/* SQL state string */
SQLINTEGER nativeErr;
/* Native error code */
SQLCHAR errMsg[MSG_LNG];
/* Error msg text buffer pointer */
SQLSMALLINT errMsgLen;
/* Error msg text Available bytes */
SQLRETURN ret = SQL_SUCCESS;
if (rc != SQL_SUCCESS &&
rc != SQL_NO_DATA_FOUND ) {
if (rc != SQL_SUCCESS_WITH_INFO) {
/*
* It's not just a warning
*/
fprintf(stderr, "*** ERROR in %s, line %d:"
" %s\n",
filename, lineno, msg);
}
/*
* Now see why the error/warning occurred
*/
while (ret == SQL_SUCCESS ||
ret == SQL_SUCCESS_WITH_INFO) {
ret = SQLError(henv, hdbc, hstmt,
sqlState, &nativeErr,
errMsg, MSG_LNG,
&errMsgLen);
switch (ret) {
case SQL_SUCCESS:
fprintf(stderr, "*** %s\n"
"*** ODBC Error/Warning = %s, "
"TimesTen Error/Warning "
" = %d\n",
errMsg, sqlState,
nativeErr);
break;
case SQL_SUCCESS_WITH_INFO:
fprintf(stderr, "*** Call to SQLError"
" failed with return code of "
"SQL_SUCCESS_WITH_INFO.\n "
"*** Need to increase size of"
" message buffer.\n");
break;
case SQL_INVALID_HANDLE:
fprintf(stderr, "*** Call to SQLError"
" failed with return code of "
"SQL_INVALID_HANDLE.\n");
break;
case SQL_ERROR:
fprintf(stderr, "*** Call to SQLError"
" failed with return code of "
"SQL_ERROR.\n");
break;
case SQL_NO_DATA_FOUND:
break;
} /* switch */
} /* while */
if (rc != SQL_SUCCESS_WITH_INFO && err_is_fatal) {
fprintf(stderr, "Exiting.\n");
exit(-1);
}
}プログラムでの接続属性の設定
次に、データベースへの接続時に接続文字列を指定することで、プログラムで接続属性を設定または上書きする方法を示します。
このコード部分では、mydsnというデータベースに接続して、SQLDriverConnectコールで、アプリケーションがパススルー設定の3を使用することを示します。PassThroughは一般接続属性であることに注意してください。
SQLHDBC hdbc;
SQLCHAR ConnStrOut[512];
SQLSMALLINT cbConnStrOut;
SQLRETURN rc;
rc = SQLDriverConnect(hdbc, NULL,
"DSN=mydsn;PassThrough=3", SQL_NTS,
ConnStrOut, sizeof (ConnStrOut),
&cbConnStrOut, SQL_DRIVER_NOPROMPT);ノート:
-
データベースへの直接接続ごとに、いくつかのファイルがオープンします。多数のスレッドを使用し、スレッドごとに別々の接続を使用するアプリケーションでは、各スレッドに対して複数のファイルがオープンします。このようなアプリケーションでは、オペレーティング・システムで同時にオープンできるファイル記述子の許可された最大数(構成されている最大値)を超える可能性があります。この場合は、多数のオープン・ファイルを許可するようシステムを設定します。『Oracle TimesTen In-Memory Databaseリファレンス』のオープン・ファイルの数の制限を参照してください。
-
接続属性に関する一般情報は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のTimesTenデータベースの管理を参照してください。一般接続属性には、特に権限は必要ありません。データベースが初めてロードされたときに最初の接続属性が設定され、すべての接続に持続的に使用されます。最初の接続属性の設定を変更してデータベースをロードできるのは、インスタンス管理者のみです。『Oracle TimesTen In-Memory Databaseリファレンス』の接続属性を参照してください。