Oracle® Database管理者リファレンス 11gリリース2 (11.2) for Linux and UNIX-Based Operating Systems B56317-12 |
|
前 |
次 |
この付録では、Oracle ODBC Driverの使用方法について説明します。内容は次のとおりです。
UNIXプラットフォームでは、Oracle ODBCドライバはunixODBC.orgのOpen Source Driver Managerを使用する次のオペレーティング・システムで動作保証されています。
プラットフォーム | 32ビットまたは64ビット | UnixODBC DMバージョン |
---|---|---|
Linux x86 | 32ビット | 2.2.14 |
Linux x86-64 | 32ビット、64ビット | 2.2.14 |
IBM: Linux on System z | 32ビット、64ビット | 2.2.14 |
Oracle Solaris on SPARC | 32ビット、64ビット | 2.2.14 |
IBM AIX on POWER Systems | 32ビット、64ビット | 2.2.12 |
Oracle Solaris on x86-64 | 64ビット | 2.2.14 |
HP-UX Itanium | 32ビット、64ビット | 2.2.14 |
Oracle ODBC Driverは、次のODBC 3.0機能をサポートしていません。
間隔データ型
SQL_C_UBIGINT
およびSQL_C_SBIGINT
Cデータ型識別子
共有接続
共有環境
SQLSetConnectAttr
のSQL_LOGIN_TIMEOUT属性
期限切れパスワード・オプション
Oracle ODBC Driverは、次の表に示すSQL関数をサポートしていません。
文字列関数 | 数値関数 | 時間関数、日付関数および間隔関数 |
---|---|---|
BIT_LENGTH |
ACOS |
CURRENT_DATE |
CHAR_LENGTH |
ASIN |
CURRENT_TIME |
CHARACTER_LENGTH |
ATAN |
CURRENT_TIMESTAMP |
DIFFERENCE |
ATAN2 |
EXTRACT |
OCTET_LENGTH |
COT |
TIMESTAMPDIFF |
POSITION |
DEGREES
|
この項では、DATE
、TIMESTAMP
および浮動小数点の各データ型について説明します。
DATEおよびTIMESTAMP
OracleのDATE
およびTIMESTAMP
データ型のセマンティクスは、同名のODBCデータ型と必ずしも正確に対応していません。OracleのDATE
データ型には、日付と時間の両方の情報が格納されています。これに対して、SQL_DATE
データ型に格納されているのは、日付情報のみです。OracleのTIMESTAMP
データ型にも日付と時間の情報が格納されていますが、その小数秒の精度は他方に比較して高くなります。Oracle ODBC Driverは、情報が失われるのを防ぐために、OracleのDATE
列とTIMESTAMP
列の両方のデータ型をSQL_TIMESTAMP
として報告します。同様に、Oracle ODBC DriverはSQL_TIMESTAMP
パラメータをOracleのTIMESTAMP値としてバインドします。
浮動小数点データ型
Oracle Database 11gリリース2 (11.2)以上に接続すると、Oracle ODBC Driverは、Oracleの浮動小数点データ型BINARY_FLOAT
とBINARY_DOUBLE
をODBCデータ型SQL_REAL
とSQL_DOUBLE
にそれぞれマップします。これより前のリリースでは、SQL_REAL
とSQL_DOUBLE
がOracleの汎用数値データ型にマップされていました。
Oracle ODBC DriverおよびOracle Databaseには、データ型に関する制限事項があります。次の表に制限事項を示します。
制限があるデータ型 | 説明 |
---|---|
リテラル | Oracle Databaseでは、SQL文のリテラルは4000バイトに制限されています。 |
SQL_LONGVARCHAR およびSQL_WLONGVARCHAR |
Oracleでは、列型がLONG のSQL_LONGVARCHAR データは2,147,483,647バイトに制限されます。また、Oracleでは、列型がCLOB のSQL_LONGVARCHAR データは4GBに制限されます。これは、クライアント・ワークステーションのメモリーによる制限です。 |
SQL_LONGVARCHAR およびSQL_LONGVARBINARY |
Oracle Databaseで使用できるのは、表ごとに1列のLONGデータ列のみです。LONGデータ型とは、SQL_LONGVARCHAR (LONG )およびSQL_LONGVARBINARY (LONG RAW )です。かわりに、CLOB およびBLOB 列の使用をお薦めします。1つの表で使用できるCLOB およびBLOB の列数に制限はありません。 |
SQLDriverConnect
関数は、Oracle ODBC Driverによって実装される関数の1つです。次の表に、SQLDriverConnect
関数コールの接続文字列の引数に含めることができるキーワードを示します。
キーワード | 意味 | 値 |
---|---|---|
DSN |
ODBCデータソース名 | ユーザー指定の名前。
これは必須のキーワードです。 |
DBQ |
TNSサービス名 | ユーザー指定の名前。
これは必須のキーワードです。 |
UID |
ユーザーIDまたはユーザー名 | ユーザー指定の名前。
これは必須のキーワードです。 |
PWD |
パスワード | ユーザー指定の名前。
パスワードがない場合は これは必須のキーワードです。 |
DBA |
データベース属性 | W は書込みアクセスを意味します。
|
APA |
アプリケーション属性 | T はスレッド・セーフティを有効にすることを意味します
|
RST |
結果セット | T は結果セットを有効にすることを意味します。
|
QTO |
問合せタイムアウト・オプション | T は問合せタイムアウトを有効にすることを意味します。
|
CSR |
カーソルのクローズ | T はカーソルのクローズを有効にすることを意味します。
|
BAM |
バッチ自動コミット・モード | IfAllSuccessful は、すべての文が成功した場合のみコミットすることを意味します(古い動作)。
|
FBS |
フェッチ・バッファ・サイズ | ユーザー指定の数値(0バイト以上の値を指定します)。デフォルトは60,000バイトです。 |
FEN |
フェイルオーバー | T はフェイルオーバーを有効にすることを意味します。
|
FRC |
フェイルオーバー再試行数 | ユーザー指定の数値。
デフォルトは10です。 |
FDL |
フェイルオーバーの遅延 | ユーザー指定の数値。
デフォルトは10です。 |
LOB |
LOB書込み | T はLOBを有効にすることを意味します。
|
FWC |
SQL_WCHAR 強制サポート |
T はForce SQL_WCHAR を有効にすることを意味します。
|
EXC |
EXEC 構文 |
T はEXEC 構文を有効にすることを意味します。
|
XSM |
スキーマ・フィールド | Default はデフォルト値が使用されることを意味します。
|
MDI |
METADATA IDデフォルトの設定 | TはSQL_ATTR_METADATA_ID のデフォルト値がSQL_TRUE であることを意味します。
|
DPM |
SQLDescribeParam の無効化 |
T はSQLDescribeParam を無効にすることを意味します。
|
BTD |
TIMESTAMP をDATE としてバインド |
TはSQL_TIMESTAMP がOracleのDATE としてバインドされることを意味します。
|
NUM |
数値の設定 | NLS は、グローバリゼーション・サポートの数値の設定が使用されることを意味します(小数点およびグループのセパレータを判断するため)。 |
Oracle Databaseは、トランザクション間のロックの競合が解決されるまで無期限に待機します。ただし、Oracle Databaseがロックの解決を待機する時間は制限できます。制限するには、ODBCのSQLSetStmtAttr
関数のコール時にSQL_ATTR_QUERY_TIMEOUT
属性を設定してから、データソースに接続します。
プログラムをリンクする場合は、そのプログラムをDriver Managerライブラリlibodbc.so
にリンクする必要があります。
ODBCのSQLSpecialColumns
関数は、表内の列に関する情報を返します。Oracle ODBC Driverで使用すると、この関数はOracle表に関連付けられたOracle ROWIDに関する情報を返します。
ROWIDは、SQL文のWHERE
句で使用できます。ただし、ROWID値はパラメータ・マーカー内に存在している必要があります。
Oracle参照カーソル(結果セットとも呼ばれます)によって、アプリケーションでは、ストアド・プロシージャとストアド・ファンクションを使用してデータを取得できます。ここでは、参照カーソルを使用してODBCを介して結果セットを有効にする方法を説明します。
ストアド・プロシージャをコールするには、ODBC構文を使用する必要があります。システム固有のPL/SQLは、ODBCを介してサポートされていません。次のコード例は、プロシージャまたはファンクションを、パッケージなしでコールする方法、およびパッケージ内でコールする方法を示します。このコード例でのパッケージ名はRSET
です。
Procedure call: {CALL Example1(?)} {CALL RSET.Example1(?)} Function Call: {? = CALL Example1(?)} {? = CALL RSET.Example1(?)}
PL/SQLの参照カーソル・パラメータは、プロシージャのコール時には省略されます。たとえば、プロシージャExample2
には4つのパラメータが定義されているとします。パラメータ1と3は参照カーソル・パラメータで、パラメータ2と4は文字列です。コールは、次のように指定されます。
{CALL RSET.Example2("Literal 1", "Literal 2")}
次のサンプル・アプリケーションは、Oracle ODBC Driverを使用して結果セットを返す方法を示します。
/*
* Sample Application using Oracle reference cursors through ODBC
*
* Assumptions:
*
* 1) Oracle Sample database is present with data loaded for the EMP table.
*
* 2) Two fields are referenced from the EMP table, ename and mgr.
*
* 3) A data source has been setup to access the sample database.
*
*
* Program Description:
*
* Abstract:
*
* This program demonstrates how to return result sets using
* Oracle stored procedures
*
* Details:
*
* This program:
* Creates an ODBC connection to the database.
* Creates a Packaged Procedure containing two result sets.
* Executes the procedure and retrieves the data from both result sets.
* Displays the data to the user.
* Deletes the package then logs the user out of the database.
*
*
* The following is the actual PL/SQL this code generates to
* create the stored procedures.
*
DROP PACKAGE ODBCRefCur;
CREATE PACKAGE ODBCRefCur AS
TYPE ename_cur IS REF CURSOR;
TYPE mgr_cur IS REF CURSOR;
PROCEDURE EmpCurs(Ename IN OUT ename_cur, Mgr IN OUT mgr_cur, pjob IN VARCHAR2);
END;
/
CREATE PACKAGE BODY ODBCRefCur AS
PROCEDURE EmpCurs(Ename IN OUT ename_cur, Mgr IN OUT mgr_cur, pjob IN VARCHAR2)
AS
BEGIN
IF NOT Ename%ISOPEN
THEN
OPEN Ename for SELECT ename from emp;
END IF;
IF NOT Mgr%ISOPEN
THEN
OPEN Mgr for SELECT mgr from emp where job = pjob;
END IF;
END;
END;
/
*
* End PL/SQL for Reference Cursor.
*/
/*
* Include Files
*/
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
/*
* Defines
*/
#define JOB_LEN 9
#define DATA_LEN 100
#define SQL_STMT_LEN 500
/*
* Procedures
*/
void DisplayError( SWORD HandleType, SQLHANDLE hHandle, char *Module );
/*
* Main Program
*/
int main()
{
SQLHENV hEnv;
SQLHDBC hDbc;
SQLHSTMT hStmt;
SQLRETURN rc;
char *DefUserName ="jones";
char *DefPassWord ="password";
SQLCHAR ServerName[DATA_LEN];
SQLCHAR *pServerName=ServerName;
SQLCHAR UserName[DATA_LEN];
SQLCHAR *pUserName=UserName;
SQLCHAR PassWord[DATA_LEN];
SQLCHAR *pPassWord=PassWord;
char Data[DATA_LEN];
SQLINTEGER DataLen;
char error[DATA_LEN];
char *charptr;
SQLCHAR SqlStmt[SQL_STMT_LEN];
SQLCHAR *pSqlStmt=SqlStmt;
char *pSalesMan = "SALESMAN";
SQLINTEGER sqlnts=SQL_NTS;
/*
* Allocate the Environment Handle
*/
rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv );
if (rc != SQL_SUCCESS)
{
printf( "Cannot Allocate Environment Handle\n");
printf( "\nHit Return to Exit\n");
charptr = gets ((char *)error);
exit(1);
}
/*
* Set the ODBC Version
*/
rc = SQLSetEnvAttr( hEnv,SQL_ATTR_ODBC_VERSION,(void *)SQL_OV_ODBC3,0);
if (rc != SQL_SUCCESS)
{
printf( "Cannot Set ODBC Version\n");
printf( "\nHit Return to Exit\n");
charptr = gets ((char *)error);
exit(1);
}
/*
* Allocate the Connection handle
*/
rc = SQLAllocHandle( SQL_HANDLE_DBC, hEnv, &hDbc );
if (rc != SQL_SUCCESS)
{
printf( "Cannot Allocate Connection Handle\n");
printf( "\nHit Return to Exit\n");
charptr = gets ((char *)error);
exit(1);
}
/*
* Get User Information
*/
strcpy ((char *) pUserName, DefUserName );
strcpy ((char *) pPassWord, DefPassWord );
/*
* Data Source name
*/
printf( "\nEnter the ODBC Data Source Name\n" );
charptr = gets ((char *) ServerName);
/*
* User Name
*/
printf ( "\nEnter User Name Default [%s]\n", pUserName);
charptr = gets ((char *) UserName);
if (*charptr == '\0')
{
strcpy ((char *) pUserName, (char *) DefUserName );
}
/*
* Password
*/
printf ( "\nEnter Password Default [%s]\n", pPassWord);
charptr = gets ((char *)PassWord);
if (*charptr == '\0')
{
strcpy ((char *) pPassWord, (char *) DefPassWord );
}
/*
* Connection to the database
*/
rc = SQLConnect( hDbc,pServerName,(SQLSMALLINT) strlen((char *)pServerName),pUserName,(SQLSMALLINT) strlen((char *)pUserName),pPassWord,(SQLSMALLINT) strlen((char *)pPassWord));
if (rc != SQL_SUCCESS)
{
DisplayError(SQL_HANDLE_DBC, hDbc, "SQLConnect");
}
/*
* Allocate a Statement
*/
rc = SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt );
if (rc != SQL_SUCCESS)
{
printf( "Cannot Allocate Statement Handle\n");
printf( "\nHit Return to Exit\n");
charptr = gets ((char *)error);
exit(1);
}
/*
* Drop the Package
*/
strcpy( (char *) pSqlStmt, "DROP PACKAGE ODBCRefCur");
rc = SQLExecDirect(hStmt, pSqlStmt, strlen((char *)pSqlStmt));
/*
* Create the Package Header
*/
strcpy( (char *) pSqlStmt, "CREATE PACKAGE ODBCRefCur AS\n");
strcat( (char *) pSqlStmt, " TYPE ename_cur IS REF CURSOR;\n");
strcat( (char *) pSqlStmt, " TYPE mgr_cur IS REF CURSOR;\n\n");
strcat( (char *) pSqlStmt, " PROCEDURE EmpCurs (Ename IN OUT ename_cur,");
strcat( (char *) pSqlStmt, "Mgr IN OUT mgr_cur,pjob IN VARCHAR2);\n\n");
strcat( (char *) pSqlStmt, "END;\n");
rc = SQLExecDirect(hStmt, pSqlStmt, strlen((char *)pSqlStmt));
if (rc != SQL_SUCCESS)
{
DisplayError(SQL_HANDLE_STMT, hStmt, "SQLExecDirect");
}
/*
* Create the Package Body
*/
strcpy( (char *) pSqlStmt, "CREATE PACKAGE BODY ODBCRefCur AS\n");
strcat( (char *) pSqlStmt, " PROCEDURE EmpCurs (Ename IN OUT ename_cur,");
strcat( (char *) pSqlStmt, "Mgr IN OUT mgr_cur, pjob IN VARCHAR2)\n AS\n BEGIN\n");
strcat( (char *) pSqlStmt, " IF NOT Ename%ISOPEN\n THEN\n");
strcat( (char *) pSqlStmt, " OPEN Ename for SELECT ename from emp;\n");
strcat( (char *) pSqlStmt, " END IF;\n\n");
strcat( (char *) pSqlStmt, " IF NOT Mgr%ISOPEN\n THEN\n");
strcat( (char *) pSqlStmt, " OPEN Mgr for SELECT mgr from emp where job = pjob;\n");
strcat( (char *) pSqlStmt, " END IF;\n");
strcat( (char *) pSqlStmt, " END;\n");
strcat( (char *) pSqlStmt, "END;\n");
rc = SQLExecDirect(hStmt, pSqlStmt, strlen((char *)pSqlStmt));
if (rc != SQL_SUCCESS)
{
DisplayError(SQL_HANDLE_STMT, hStmt, "SQLExecDirect");
}
/*
* Bind the Parameter
*/
rc = SQLBindParameter(hStmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,JOB_LEN,0,pSalesMan,0,&sqlnts);
/*
* Call the Store Procedure which executes the Result Sets
*/
strcpy( (char *) pSqlStmt, "{CALL ODBCRefCur.EmpCurs(?)}");
rc = SQLExecDirect(hStmt, pSqlStmt, strlen((char *)pSqlStmt));
if (rc != SQL_SUCCESS)
{
DisplayError(SQL_HANDLE_STMT, hStmt, "SQLExecDirect");
}
/*
* Bind the Data
*/
rc = SQLBindCol( hStmt,1,SQL_C_CHAR,Data,sizeof(Data),&DataLen);
if (rc != SQL_SUCCESS)
{
DisplayError(SQL_HANDLE_STMT, hStmt, "SQLBindCol");
}
/*
* Get the data for Result Set 1
*/
printf( "\nEmployee Names\n\n");
while ( rc == SQL_SUCCESS )
{
rc = SQLFetch( hStmt );
if ( rc == SQL_SUCCESS )
{
printf("%s\n", Data);
}
else
{
if (rc != SQL_NO_DATA)
{
DisplayError(SQL_HANDLE_STMT, hStmt, "SQLFetch");
}
}
}
printf( "\nFirst Result Set - Hit Return to Continue\n");
charptr = gets ((char *)error);
/*
* Get the Next Result Set
*/
rc = SQLMoreResults( hStmt );
if (rc != SQL_SUCCESS)
{
DisplayError(SQL_HANDLE_STMT, hStmt, "SQLMoreResults");
}
/*
* Get the data for Result Set 2
*/
printf( "\nManagers\n\n");
while ( rc == SQL_SUCCESS )
{
rc = SQLFetch( hStmt );
if ( rc == SQL_SUCCESS )
{
printf("%s\n", Data);
}
else
{
if (rc != SQL_NO_DATA)
{
DisplayError(SQL_HANDLE_STMT, hStmt, "SQLFetch");
}
}
}
printf( "\nSecond Result Set - Hit Return to Continue\n");
charptr = gets ((char *)error);
/*
* Should Be No More Results Sets
*/
rc = SQLMoreResults( hStmt );
if (rc != SQL_NO_DATA)
{
DisplayError(SQL_HANDLE_STMT, hStmt, "SQLMoreResults");
}
/*
* Drop the Package
*/
strcpy( (char *) pSqlStmt, "DROP PACKAGE ODBCRefCur");
rc = SQLExecDirect(hStmt, pSqlStmt, strlen((char *)pSqlStmt));
/*
* Free handles close connections to the database
*/
SQLFreeHandle( SQL_HANDLE_STMT, hStmt );
SQLDisconnect( hDbc );
SQLFreeHandle( SQL_HANDLE_DBC, hDbc );
SQLFreeHandle( SQL_HANDLE_ENV, hEnv );
printf( "\nAll Done - Hit Return to Exit\n");
charptr = gets ((char *)error);
return(0);
}
/*
* Display Error Messages
*/
void DisplayError( SWORD HandleType, SQLHANDLE hHandle, char *Module )
{
SQLCHAR MessageText[255];
SQLCHAR SQLState[80];
SQLRETURN rc=SQL_SUCCESS;
long NativeError;
SWORD RetLen;
SQLCHAR error[25];
char *charptr;
rc =
SQLGetDiagRec(HandleType,hHandle,1,SQLState,&NativeError,MessageText,255,&RetLen);
printf( "Failure Calling %s\n", Module );
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
printf( "\t\t\t State: %s\n", SQLState);
printf( "\t\t\t Native Error: %d\n", NativeError );
printf( "\t\t\t Error Message: %s\n", MessageText );
}
printf( "\nHit Return to Exit\n");
charptr = gets ((char *)error);
exit(1);
}
使用しているSQL ServerのEXEC
文の構文を変更せずに同等のOracleプロシージャ・コールに容易に変換できる場合、その構文は、このオプションを有効にすると、Oracle ODBC Driverで変換できます。
SQL Serverプロシージャの完全な名前は、次に示す最大4つの識別子で構成されます。
サーバー名
データベース名
所有者名
プロシージャ名
この名前の書式は次のとおりです。
[[[server.][database].][owner_name].]procedure_name
Microsoft SQL ServerデータベースからOracle Databaseに移行する際、各SQL Serverプロシージャまたはファンクションの定義は同等のOracle Database構文に変換され、Oracle Databaseのスキーマで定義されます。移行したプロシージャは、多くの場合、次のいずれかの方法で再編成(およびスキーマで作成)されます。
すべてのプロシージャが1つのスキーマに移行されます(デフォルト・オプション)。
1つのSQL Serverデータベースに定義されているすべてのプロシージャが、そのデータベース名の付いたスキーマに移行されます。
特定のユーザーが所有するすべてのプロシージャが、そのユーザー名の付いたスキーマに移行されます。
移行したプロシージャを編成するこれら3通りの方法をサポートするためには、いずれかのスキーマ名オプションを指定してプロシージャ名を変換できます。変換したOracleプロシージャ・コールのオブジェクト名では、大/小文字が区別されません。
この項では、Oracle ODBC Driverでサポートされている機能について説明します。内容は次のとおりです。
Oracle ODBC Driverリリース10.2.0.1.0以上では、コア、レベル2およびレベル1のすべての関数をサポートしています。
次の表に、Oracle ODBC Driverが特定の関数を実装する方法を示します。
機能 | 説明 |
---|---|
SQLConnect |
SQLConnect で必要なのは、DBQ 、ユーザーIDおよびパスワードのみです。 |
SQLDriverConnect |
SQLDriverConnect では、DSN 、DBQ 、UID およびPWD の各キーワードが使用されます。 |
SQLSpecialColumns |
SQL_BEST_ROWID 属性を指定してSQLSpecialColumns をコールすると、常にROWID列を返します。 |
SQLProcedures およびSQLProcedureColumns |
次の項の説明を参照してください。 |
すべてのカタログ関数 | SQL_ATTR_METADATA_ID 文の属性がSQL_TRUE に設定されている場合、文字列の引数は、識別子の引数として処理されますが、このケースはあまり重要ではありません。この場合、アンダースコア(_)およびパーセント記号(%)は検索用パターン文字ではなく、実際の文字として処理されます。これに対して、この属性をSQL_FALSE に設定すると、文字列の引数は、通常の引数またはパターン値の引数となり、リテラルに処理されるため、このケースは重要です。 |
SQLProceduresおよびSQLProcedureColumns
SQLProcedures
コールおよびSQLProcedureColumns
コールは、パッケージ内に含まれている場合でも、すべてのプロシージャおよびファンクションに関する情報を検索して返すように変更されました。これより前のリリースでは、これらのコールで検索されるのは、パッケージ外のプロシージャとファンクションのみでした。次の例では、SQL_ATTR_METADATA_ID
属性をSQL_FALSE
に設定した場合に返されるプロシージャまたはファンクションを示します。
この例では、次のストアド・プロシージャがあるとします。
"BAR" "BARX" "XBAR" "XBARX" "SQLPROCTEST.BAR" "SQLPROCTEST.BARX" "SQLPROCTEST.XBAR" "SQLPROCTEST.XBARX"
%
または%%%%%%
と指定して検索すると、これら8つのプロシージャがすべて返されます。
%_
または_%
と指定して検索すると、次のプロシージャが返されます。
BAR BARX XBAR XBARX
.
、.%
、%.%
、SQLPROC%.
またはSQLPROC%.%
と指定して検索すると、次のプロシージャが返されます。
SQLPROCTEST.BAR SQLPROCTEST.BARX SQLPROCTEST.XBAR SQLPROCTEST.XBARX
%BAR
と指定して検索すると、次のプロシージャが返されます。
BAR XBAR
.%BAR
または%.%BAR
と指定して検索すると、次のプロシージャが返されます。
SQLPROCTEST.BAR SQLPROCTEST.XBAR
SQLPROC%
または.SQLPROC%
と指定して検索すると、次のプロシージャが返されます。
nothing (0 rows)
比較述語で比較の2番目の式としてパラメータ・マーカーが使用され、そのパラメータの値がSQLBindParameter
を使用してSQL_NULL_DATA
に設定されている場合、比較は失敗します。これは、ODBC SQLのNULL述語構文と一致しています。
プログラマがデータ型を実装する際に最も考慮する必要があるのは、CHAR
、VARCHAR
およびVARCHAR2
の各データ型です。
SQL_VARCHAR
の値がfSqlType
の場合、SQLGetTypeInfo
はOracle Databaseデータ型VARCHAR2
を返します。SQL_CHAR
の値がfSqlType
の場合、SQLGetTypeInfo
はOracle Databaseデータ型CHAR
を返します。
この項では、Unicodeのサポートについて説明します。内容は次のとおりです。
ODBC Driver Managerを使用すると、すべてのODBCドライバは、Unicodeをサポートしているかどうかに関係なくUnicode準拠と同様に動作します。これによって、ODBCアプリケーションは、基礎となるODBCドライバのUnicode機能に関係なく記述できます。
Driver ManagerがANSI ODBCドライバに対するUnicodeサポートをエミュレートできる範囲は、Unicodeデータとローカル・コード・ページ間で可能な変換内容によって制限されます。Driver ManagerがデータをUnicodeからローカル・コード・ページに変換する際、データが失われる場合があります。基礎となるODBCドライバがUnicodeをサポートしていないかぎり、Unicodeの完全なサポートは不可能です。Oracle ODBC Driverは、Unicodeを完全にサポートしています。
ODBC APIは、W
およびA
接尾辞の変換を使用して、UnicodeおよびANSIエントリ・ポイントの両方をサポートします。ODBCアプリケーション開発者は、接尾辞を指定してエントリ・ポイントを明示的にコールする必要はありません。UNICODE
および_UNICODE
プリプロセッサ定義を使用してコンパイルされたODBCアプリケーションによって、適切なコールが生成されます。たとえば、SQLPrepare
へのコールは、SQLPrepareW
としてコンパイルされます。
Cデータ型のSQL_C_WCHAR
がODBCインタフェースに追加されたため、アプリケーションでは、入力パラメータをUnicodeとしてエンコードするように指定するか、またはUnicodeとして返された列データを要求できます。マクロのSQL_C_TCHAR
は、UnicodeおよびANSIの両方で作成する必要があるアプリケーションで有効です。SQL_C_TCHAR
マクロは、Unicodeアプリケーションの場合はSQL_C_WCHAR
として、ANSIアプリケーションの場合はSQL_C_CHAR
としてコンパイルされます。
SQLデータ型のSQL_WCHAR
、SQL_WVARCHAR
およびSQL_WLONGVARCHAR
がODBCインタフェースに追加され、表内で定義された列がUnicodeで表現されるようになりました。これらの値は、SQLDescribeCol
、SQLColAttribute
、SQLColumns
およびSQLProcedureColumns
へのコールから返すことも可能です。
Unicodeエンコーディングは、SQL列型のNCHAR、NVARCHAR2およびNCLOBに対してサポートされています。さらに、文字セマンティクスが列定義で指定されている場合、UnicodeエンコーディングはSQL列型のCHARおよびVARCHAR2に対してもサポートされています。
Oracle ODBC Driverは、これらのSQL列型をサポートしてODBC SQLデータ型にマップします。次の表に、サポートされているSQLデータ型および対応するODBC SQLデータ型を示します。
SQLデータ型 | ODBC SQLデータ型 |
---|---|
CHAR |
SQL_CHAR またはSQL_WCHAR |
VARCHAR2 |
SQL_VARCHAR またはSQL_WVARCHAR |
NCHAR |
SQL_WCHAR |
NVARCHAR2 |
SQL_WVARCHAR |
NCLOB |
SQL_WLONGVARCHAR |
SQLGetData
関数を使用すると、ODBCアプリケーションはデータ型を指定して、データのフェッチ後に列を取得できます。OCIでは、Oracle ODBC Driverはデータ型を指定してからフェッチする必要があります。この場合、Oracle ODBC Driverは(データベースで定義された)列のデータ型に関する情報を使用し、OCIを介して列をフェッチする最適なデフォルト方法を判断します。
文字データを含む列がSQLBindCol
によってバインドされていない場合、Oracle ODBC Driverは、その列をUnicodeとしてフェッチするか、またはローカル・コード・ページとしてフェッチするかを判断する必要があります。ドライバは、列をUnicodeとして受け入れるように常にデフォルト設定できます。ただし、この設定では、2回の不要な変換が実行されます。たとえば、データベース内のデータがANSIとしてエンコードされた場合、データをOracle ODBC DriverにフェッチするためにANSIからUnicodeへの変換が実行されます。次に、ODBCアプリケーションがそのデータをSQL_C_CHAR
として要求すると、データを元のエンコーディングに戻すための変換が実行されます。
Oracle Database Clientのデフォルト・エンコーディングは、データをフェッチする際に使用されます。ただし、ODBCアプリケーションでは、このデフォルトを上書きし、列またはパラメータをWCHARデータ型としてバインドすることによって、データをUnicodeとしてフェッチできます。
Oracle ODBC Driver自体がTCHAR
マクロを使用して実装されているため、ODBCアプリケーション・プログラムでは、TCHAR
を使用して、このドライバを利用することをお薦めします。
次の例では、UNICODE
および_UNICODE
を指定してコンパイルするとWCHAR
データ型になるTCHAR
の使用方法を示します。
例E-1 データベースへの接続
このコードを使用するには、SQLConnect
にUnicodeリテラルのみ指定する必要があります。
HENV envHnd;
HDBC conHnd;
HSTMT stmtHnd;
RETCODE rc;
rc = SQL_SUCCESS;
// ENV is allocated
rc = SQLAllocEnv(&envHnd);
// Connection Handle is allocated
rc = SQLAllocConnect(envHnd, &conHnd);
rc = SQLConnect(conHnd, _T("stpc19"), SQL_NTS, _T("jones"), SQL_NTS, _T("password"), SQL_NTS);
.
.
.
if (conHnd)
SQLFreeConnect(conHnd);
if (envHnd)
SQLFreeEnv(envHnd);
例E-2 単純な取得
次の例では、EMP
表から従業員名と役職名を取得します。すべてのODBC関数にTCHAR
準拠のデータを指定する必要があることを除いて、ANSIの場合と違いはありません。Unicodeアプリケーションの場合は、SQLBindColのコール時にバッファ長をBYTE
長に指定する必要があります。たとえば、sizeof(ename)
の場合は次のとおりです。
/* ** Execute SQL, bind columns, and Fetch. ** Procedure: ** ** SQLExecDirect ** SQLBindCol ** SQLFetch ** */ static SQLTCHAR *sqlStmt = _T("SELECT ename, job FROM emp"); SQLTCHAR ename[50]; SQLTCHAR job[50]; SQLINTEGER enamelen, joblen; _tprintf(_T("Retrieve ENAME and JOB using SQLBindCol 1.../n[%s]/n"), sqlStmt); // Step 1: Prepare and Execute rc = SQLExecDirect(stmtHnd, sqlStmt, SQL_NTS); // select checkSQLErr(envHnd, conHnd, stmtHnd, rc); // Step 2: Bind Columns rc = SQLBindCol(stmtHnd, 1, SQL_C_TCHAR, ename, sizeof(ename), &enamelen); checkSQLErr(envHnd, conHnd, stmtHnd, rc); rc = SQLBindCol(stmtHnd, 2, SQL_C_TCHAR, job, sizeof(job), &joblen); checkSQLErr(envHnd, conHnd, stmtHnd, rc); do { // Step 3: Fetch Data rc = SQLFetch(stmtHnd); if (rc == SQL_NO_DATA) break; checkSQLErr(envHnd, conHnd, stmtHnd, rc); _tprintf(_T("ENAME = %s, JOB = %s/n"), ename, job); } while (1); _tprintf(_T("Finished Retrieval/n/n"));
例E-3 SQLGetDataを使用した取得(フェッチ後のバインド)
この例では、SQLGetData
の使用方法を示します。Unicode固有の事項に関しては、ANSIアプリケーションとの違いはありません。
/* ** Execute SQL, bind columns, and Fetch. ** Procedure: ** ** SQLExecDirect ** SQLFetch ** SQLGetData */ static SQLTCHAR *sqlStmt = _T("SELECT ename,job FROM emp"); // same as Case 1. SQLTCHAR ename[50]; SQLTCHAR job[50]; _tprintf(_T("Retrieve ENAME and JOB using SQLGetData.../n[%s]/n"), sqlStmt); if (rc != SQL_SUCCESS) { _tprintf(_T("Failed to allocate STMT/n")); goto exit2; } // Step 1: Prepare and Execute rc = SQLExecDirect(stmtHnd, sqlStmt, SQL_NTS); // select checkSQLErr(envHnd, conHnd, stmtHnd, rc); do { // Step 2: Fetch rc = SQLFetch(stmtHnd); if (rc == SQL_NO_DATA) break; checkSQLErr(envHnd, conHnd, stmtHnd, rc); // Step 3: GetData rc = SQLGetData(stmtHnd, 1, SQL_C_TCHAR, (SQLPOINTER)ename, sizeof(ename), NULL); checkSQLErr(envHnd, conHnd, stmtHnd, rc); rc = SQLGetData(stmtHnd, 2, SQL_C_TCHAR, (SQLPOINTER)job, sizeof(job), NULL); checkSQLErr(envHnd, conHnd, stmtHnd, rc); _tprintf(_T("ENAME = %s, JOB = %s/n"), ename, job); } while (1); _tprintf(_T("Finished Retrieval/n/n"));
例E-4 単純な更新
この例では、データの更新方法を示します。SQLBindParameter
のデータ長は、UnicodeアプリケーションでもBYTE長で指定する必要があります。
/* ** Execute SQL, bind columns, and Fetch. ** Procedure: ** ** SQLPrepare ** SQLBindParameter ** SQLExecute */ static SQLTCHAR *sqlStmt = _T("INSERT INTO emp(empno,ename,job) VALUES(?,?,?)"); static SQLTCHAR *empno = _T("9876"); // Emp No static SQLTCHAR *ename = _T("ORACLE"); // Name static SQLTCHAR *job = _T("PRESIDENT"); // Job _tprintf(_T("Insert User ORACLE using SQLBindParameter.../n[%s]/n"), sqlStmt); // Step 1: Prepare rc = SQLPrepare(stmtHnd, sqlStmt, SQL_NTS); // select checkSQLErr(envHnd, conHnd, stmtHnd, rc); // Step 2: Bind Parameter rc = SQLBindParameter(stmtHnd, 1, SQL_PARAM_INPUT, SQL_C_TCHAR, SQL_DECIMAL, 4, // 4 digit 0, (SQLPOINTER)empno, 0, NULL); checkSQLErr(envHnd, conHnd, stmtHnd, rc); rc = SQLBindParameter(stmtHnd, 2, SQL_PARAM_INPUT, SQL_C_TCHAR, SQL_CHAR, lstrlen(ename)*sizeof(TCHAR), 0, (SQLPOINTER)ename, lstrlen(ename)*sizeof(TCHAR), NULL); checkSQLErr(envHnd, conHnd, stmtHnd, rc); rc = SQLBindParameter(stmtHnd, 3, SQL_PARAM_INPUT, SQL_C_TCHAR, SQL_CHAR, lstrlen(job)*sizeof(TCHAR), 0, (SQLPOINTER)job, lstrlen(job)*sizeof(TCHAR), NULL); checkSQLErr(envHnd, conHnd, stmtHnd, rc); // Step 3: Execute rc = SQLExecute(stmtHnd); checkSQLErr(envHnd, conHnd, stmtHnd, rc);
例E-5 長いデータ(CLOB)の更新と取得
ここでは、CLOB
などの長いデータをOracle Databaseで更新および取得する最も複雑な例を示します。データ長は常にBYTE
長であるため、BYTE
長を導出するには式lstrlen(TCHAR data)*sizeof(TCHAR)
が必要です。
/* ** Execute SQL, bind columns, and Fetch. ** Procedure: ** ** SQLPrepare ** SQLBindParameter ** SQLExecute ** SQLParamData ** SQLPutData ** ** SQLExecDirect ** SQLFetch ** SQLGetData */ static SQLTCHAR *sqlStmt1 = _T("INSERT INTO clobtbl(clob1) VALUES(?)"); static SQLTCHAR *sqlStmt2 = _T("SELECT clob1 FROM clobtbl"); SQLTCHAR clobdata[1001]; SQLTCHAR resultdata[1001]; SQLINTEGER ind = SQL_DATA_AT_EXEC; SQLTCHAR *bufp; int clobdatalen, chunksize, dtsize, retchklen; _tprintf(_T("Insert CLOB1 using SQLPutData.../n[%s]/n"), sqlStmt1); // Set CLOB Data { int i; SQLTCHAR ch; for (i=0, ch=_T('A'); i< sizeof(clobdata)/sizeof(SQLTCHAR); ++i, ++ch) { if (ch > _T('Z')) ch = _T('A'); clobdata[i] = ch; } clobdata[sizeof(clobdata)/sizeof(SQLTCHAR)-1] = _T('/0'); } clobdatalen = lstrlen(clobdata); // length of characters chunksize = clobdatalen / 7; // 7 times to put // Step 1: Prepare rc = SQLPrepare(stmtHnd, sqlStmt1, SQL_NTS); checkSQLErr(envHnd, conHnd, stmtHnd, rc); // Step 2: Bind Parameter with SQL_DATA_AT_EXEC rc = SQLBindParameter(stmtHnd, 1, SQL_PARAM_INPUT, SQL_C_TCHAR, SQL_LONGVARCHAR, clobdatalen*sizeof(TCHAR), 0, (SQLPOINTER)clobdata, clobdatalen*sizeof(TCHAR), &ind); checkSQLErr(envHnd, conHnd, stmtHnd, rc); // Step 3: Execute rc = SQLExecute(stmtHnd); checkSQLErr(envHnd, conHnd, stmtHnd, rc); // Step 4: ParamData (initiation) rc = SQLParamData(stmtHnd, (SQLPOINTER*)&bufp); // set value checkSQLErr(envHnd, conHnd, stmtHnd, rc); for (dtsize=0, bufp = clobdata; dtsize < clobdatalen; dtsize += chunksize, bufp += chunksize) { int len; if (dtsize+chunksize<clobdatalen) len = chunksize; else len = clobdatalen-dtsize; // Step 5: PutData rc = SQLPutData(stmtHnd, (SQLPOINTER)bufp, len*sizeof(TCHAR)); checkSQLErr(envHnd, conHnd, stmtHnd, rc); } // Step 6: ParamData (temination) rc = SQLParamData(stmtHnd, (SQLPOINTER*)&bufp); checkSQLErr(envHnd, conHnd, stmtHnd, rc); rc = SQLFreeStmt(stmtHnd, SQL_CLOSE); _tprintf(_T("Finished Update/n/n")); rc = SQLAllocStmt(conHnd, &stmtHnd); if (rc != SQL_SUCCESS) { _tprintf(_T("Failed to allocate STMT/n")); goto exit2; } // Clear Result Data memset(resultdata, 0, sizeof(resultdata)); chunksize = clobdatalen / 15; // 15 times to put // Step 1: Prepare rc = SQLExecDirect(stmtHnd, sqlStmt2, SQL_NTS); // select checkSQLErr(envHnd, conHnd, stmtHnd, rc); // Step 2: Fetch rc = SQLFetch(stmtHnd); checkSQLErr(envHnd, conHnd, stmtHnd, rc); for(dtsize=0, bufp = resultdata; dtsize < sizeof(resultdata)/sizeof(TCHAR) && rc != SQL_NO_DATA; dtsize += chunksize-1, bufp += chunksize-1) { int len; // len should contain the space for NULL termination if (dtsize+chunksize<sizeof(resultdata)/sizeof(TCHAR)) len = chunksize; else len = sizeof(resultdata)/sizeof(TCHAR)-dtsize; // Step 3: GetData rc = SQLGetData(stmtHnd, 1, SQL_C_TCHAR, (SQLPOINTER)bufp, len*sizeof(TCHAR), &retchklen); } if (!_tcscmp(resultdata, clobdata)) { _tprintf(_T("Succeeded!!/n/n")); } else { _tprintf(_T("Failed!!/n/n")); }
この項では、次の項目について説明します。
ODBCアプリケーションのパフォーマンスを向上させるには、次のプログラミング・ガイドラインを適用してください。
アプリケーションがデータソースに頻繁に接続したり切断する場合は、接続プーリングを使用可能にします。プールされた接続の再利用は、接続の再確立に比べて非常に効率的です。
文を準備する回数を最小限にします。可能な場合は、バインド・パラメータを使用し、別のパラメータ値に対して文を再利用できるようにします。SQLExecute
ごとに文を準備するよりも、1つの文を1回準備して複数回実行する方が効率的です。
アプリケーションが取得しないことが判明している列、特にLONG
列をSELECT
文に含めないでください。LONG
列がSELECT
文に含まれていると、データベース・サーバー・プロトコルの特性上、アプリケーションが列をバインドするかSQLGetData
操作を実行するかに関係なく、Oracle ODBC Driverでは列全体をフェッチする必要があるためです。
データソースを更新しないトランザクションを実行する場合は、ODBCのSQLSetConnectAttr
関数のSQL_ATTR_ACCESS_MODE
属性をSQL_MODE_READ_ONLY
に設定します。
ODBCのエスケープ句を使用しない場合は、そのODBCのSQLSetConnectAttr
関数またはSQLSetStmtAttr
関数のSQL_ATTR_NOSCAN
属性をtrueに設定します。
行数の多い表からデータを取得する場合は、ODBCのSQLFetch
関数のかわりにODBCのSQLFetchScroll
関数を使用します。
この項では、次のODBCデータソース構成オプションを使用した場合のパフォーマンスへの影響を説明します。
結果セットを有効化
このオプションによって、プロシージャ・コールから結果セット(RefCursor
など)を返すサポートが有効になります。デフォルトでは、結果セットを返すサポートが有効です。
Oracle ODBC Driverでは、RefCursor
パラメータが存在するかどうかを判断するために、データベース・サーバーを問い合せてプロシージャのパラメータ・セットとそのデータ型を判別する必要があります。この問合せによって、最初にプロシージャが準備完了になり実行されると、追加のネットワーク・ラウンドトリップが発生します。
LOBを有効化
このオプションによって、LOBを挿入および更新するサポートが有効になります。デフォルトではこのサポートが有効です。
Oracle ODBC Driverでは、LOBパラメータがあるかどうかを判断するために、データベース・サーバーを問い合せて、INSERT
文またはUPDATE
文の各パラメータのデータ型を判別する必要があります。この問合せによって、最初にINSERT
またはUPDATE
が準備完了になり実行されると、追加のネットワーク・ラウンドトリップが発生します。
関連項目: LOBの詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。 |
注意: LOBデータ圧縮を行うと、SecureFilesを圧縮して、ディスク、入出力およびREDOログを節約できます。この場合、圧縮により領域の使用効率が上がるため、コストが低減されます。また、圧縮により入出力およびREDOログが縮小するため、SecureFilesのパフォーマンスが向上します。LOBデータを暗号化すると、データベースのセキュリティが強化されます。ランダムな読取りおよび書込みに対して暗号化データが使用可能になっている間、データのセキュリティは向上します。 データを圧縮および暗号化する場合、追加のメモリーが消費されます。 |
TIMESTAMPをDATEとしてバインド
SQL_TIMESTAMP
パラメータを適切なOracle Databaseデータ型としてバインドします。このオプションをTRUE
に設定すると、SQL_TIMESTAMP
はOracleのDATE
データ型としてバインドされます。このオプションをFALSE
に設定すると、SQL_TIMESTAMP
はOracleのTIMESTAMP
データ型としてバインドされます。これがデフォルトです。
カーソル・クローズを有効化
ODBC関数SQLFreeStmt
のSQL_CLOSE
オプションは、関連するカーソルを文とともにクローズし、保留中のすべての結果を廃棄します。アプリケーションでは文を再度実行することによってカーソルを再オープンでき、SQLPrepareを再度実行する必要はありません。このオプションを使用する典型的な例は、しばらくの間アイドル状態になり、後で同じSQL文を再利用するアプリケーションの場合です。この場合、アプリケーションがアイドル状態になっている間、関連するサーバー・リソースを解放できます。
Oracle ODBC Driverが位置するOCIでは、カーソルをクローズする機能をサポートしていません。したがって、デフォルトでは、SQL_CLOSE
オプションはOracle ODBC Driverに影響を与えません。カーソルおよび関連するリソースはデータベース上でオープンしたままです。
このオプションを有効にすると、データベース・サーバー上の関連するカーソルがクローズします。ただし、その結果、SQL文の解析コンテキストが失われます。ODBCアプリケーションは文を再度実行でき、SQLPrepare
をコールする必要はありません。ただし、内部的には、Oracle ODBC Driverは文全体を準備して実行する必要があります。このオプションを有効にすると、文を1回準備して繰り返し実行するアプリケーションのパフォーマンスに大きな影響を与えます。
このオプションは、サーバー上のリソースを解放する必要がある場合のみ有効にしてください。
フェッチ・バッファ・サイズ
odbc.ini
ファイルのフェッチ・バッファ・サイズ(FetchBufferSize
)を、バイト単位で指定した値に設定します。この値は、Oracle ODBC DriverがOracle Databaseからクライントのキャッシュに1回にプリフェッチするデータの行数を決定するのに必要なメモリー量で、アプリケーション・プログラムが1回の問合せで要求する行数とは関係ありません。これによって、パフォーマンスが向上します。
また、1回にフェッチするデータが20行未満であることが多いアプリケーションで、特に、速度の遅いネットワーク接続である場合や負荷の大きいサーバーからフェッチする場合は、アプリケーションの応答時間が改善されます。この設定値が高すぎると、応答時間に悪影響が生じたり、大量のメモリーが消費される可能性があります。デフォルトは64,000バイトです。アプリケーションに対して最適な値を選択してください。
LONG
およびLOB
データ型がある場合、Oracle ODBC Driverがプリフェッチする行数はこのフェッチ・バッファ・サイズで決まりません。LONG
およびLOB
データ型が含まれると、パフォーマンスの向上は最小限になり、過剰にメモリーが使用される可能性があります。Oracle ODBC Driverはこのフェッチ・バッファ・サイズを無視し、LONG
およびLOB
データ型が存在する場合は一定の行数のみプリフェッチします。
WHERE
句でデータベースのDATE
列が使用され、その列に索引がある場合は、パフォーマンスに影響を与える可能性があります。次に例を示します。
SELECT * FROM EMP WHERE HIREDATE = ?
この例では、HIREDATE
列の索引を使用して、問合せを迅速に実行できます。ただし、HIREDATE
がDATE
値で、Oracle ODBC Driverはこのパラメータ値をTIMESTAMP
として提供しているため、Oracle Databaseの問合せオプティマイザは変換関数を適用する必要があります。誤った結果(パラメータ値に0以外の小数秒がある場合に発生する可能性があります)を防ぐために、オプティマイザは、HIREDATE
列に変換を適用するため、次のような文になります。
SELECT * FROM EMP WHERE TO_TIMESTAMP(HIREDATE) = ?
ただし、この場合はHIREDATE
列で索引を使用できなくなります。かわりに、サーバーでは表の順次スキャンを実行します。したがって、表に多数の行がある場合は時間がかかる可能性があります。このような場合の次善策として、Oracle ODBC DriverにはTIMESTAMP
をDATE
としてバインドする接続オプションが用意されています。このオプションを有効にすると、Oracle ODBC Driverは、SQL_TIMESTAMP
パラメータをOracleのTIMESTAMP
データ型ではなくOracleのDATE
データ型としてバインドします。これによって、問合せオプティマイザはDATE
列で索引を使用できます。
注意: このオプションは、DATE 列をTIMESTAMP 列としてバインドするMicrosoft Accessや類似のプログラムで使用することを目的にしています。実際のTIMESTAMP 列がある場合、またはデータが失われる可能性がある場合は使用しないでください。Microsoft Accessでは、主キーとして選択されたすべての列を使用してこの問合せを実行します。 |
エラーが発生すると、Oracle ODBC Driverは、システム固有のエラー番号、SQLSTATE
(ODBCエラー・コード)およびエラー・メッセージを返します。ドライバは、ドライバが検出したエラーおよびOracle Databaseから返されたエラーの両方からこれらの情報を導出します。
システム固有のエラー
データソースでエラーが発生した場合、Oracle ODBC Driverは、Oracle Databaseから返されたシステム固有のエラーを返します。Oracle ODBC DriverまたはDriver Managerがエラーを検出した場合、Oracle ODBC Driverはシステム固有のエラー番号として0(ゼロ)を返します。
SQLSTATE
データソースでエラーが発生した場合、Oracle ODBC Driverは、返されたシステム固有のエラーを適切なSQLSTATE
にマップします。Oracle ODBC DriverまたはDriver Managerがエラーを検出した場合は、適切なSQLSTATE
を生成します。
エラー・メッセージ
データソースでエラーが発生した場合、Oracle ODBC Driverは、Oracle Databaseから返されたメッセージに基づいてエラー・メッセージを返します。Oracle ODBC DriverまたはDriver Managerでエラーが発生した場合、Oracle ODBC Driverは、SQLSTATE
に関連付けられたテキストに基づいてエラー・メッセージを返します。
エラー・メッセージの書式は次のとおりです。
[vendor] [ODBC-component] [data-source] error-message
大カッコ([ ])内の接頭辞によって、エラーの発生場所を識別します。次の表に、Oracle ODBC Driverから返される接頭辞の値を示します。データソースでエラーが発生した場合は、vendor
およびODBC-component
接頭辞によって、データソースからエラーを受け取ったODBCコンポーネントのベンダーと名前を識別します。
エラーの発生場所 | 接頭辞 | 値 |
---|---|---|
ドライバ・マネージャ | [vendor]
[ODBC-component] [data-source] |
[unixODBC]
[Driver Manager] 該当なし |
Oracle ODBC Driver | [vendor]
[ODBC-component] [data-source] |
[ORACLE]
[Oracle ODBC Driver] 該当なし |
Oracle Database | [vendor]
[ODBC-component] [data-source] |
[ORACLE]
[Oracle ODBC Driver] [Oracle OCI] |
たとえば、次の書式に示すように、エラー・メッセージにOra
接頭辞が付いていない場合、そのエラーはOracle ODBC Driverのエラーであることがわかります。
[Oracle][ODBC]Error message text here
また、次の書式に示すように、エラー・メッセージにOra
接頭辞が付いている場合、このエラーはOracle ODBC Driverのエラーではありません。
[Oracle][ODBC][Ora]Error message text here
注意: エラー・メッセージにORA- 接頭辞が付いている場合でも、実際のエラーは複数のソースのいずれかで発生している場合があります。 |
エラー・メッセージのテキストがORA-
接頭辞で始まっている場合、そのエラーの詳細はOracle Databaseのドキュメントを参照してください。