次の方法で共有


テクニカル ノート 42: ODBC ドライバーの開発に関する推奨事項

注意

次のテクニカル ノートは、最初にオンライン ドキュメントの一部とされてから更新されていません。 結果として、一部のプロシージャおよびトピックが最新でないか、不正になります。 最新の情報について、オンライン ドキュメントのキーワードで関係のあるトピックを検索することをお勧めします。

このテクニカル ノートは、ODBC (Open Database Connectivity) ドライバーを作成する場合のガイドラインです。 MFC (Microsoft Foundation Class) データベース クラスを使用した ODBC 機能に対する条件や前提、および要求される構文の詳細について説明します。 また、CRecordset の 3 つのオープン モード (forwardOnlysnapshotdynaset) に必要なドライバーの機能についても説明します。

ODBC カーソル ライブラリ

多くの場合、MFC データベース クラスでは、レベル 1 の ODBC ドライバーよりも高度な機能が用意されています。 ODBC カーソル ライブラリはデータベース クラスとドライバーの間に位置するため、カーソル ライブラリの追加機能の多くはそのまま利用できます。

たとえば、1.0 ドライバーの多くは後方スクロールをサポートしていません。 しかし、カーソル ライブラリを使用すると、行の内容をドライバーからキャッシュして、SQLExtendedFetch の FETCH_PREV の呼び出しに応じて表示できます。

他にも、カーソル ライブラリの機能を利用している重要な例として、位置を指定した更新機能があります。 ほとんどの 1.0 ドライバーは位置を指定した更新を行うことはできませんでしたが、カーソル ライブラリは、キャッシュされているデータ値またはタイムスタンプ値から、データ ソース内のターゲット行を特定する更新ステートメントを作成します。

クラス ライブラリは複数行セットを利用しません。 したがって、いくつかの SQLSetPos ステートメントは、常に行セットの最初の行に適用されます。

CDatabase

CDatabase ごとに HDBC を 1 つずつ割り当てます。 CDatabaseExecuteSQL 関数が使用されると、一時的に HSTMT が割り当てられます。したがって、複数の CDatabase を使用する場合は、1 つの HENV に対して複数の HDBC が利用可能であることが必要です。

データベース クラスは、カーソル ライブラリを必要とします。 これは、SQLSetConnections から SQL_ODBC_CURSORSSQL_CUR_USE_ODBC が呼び出されるためです。

SQLDriverConnectSQL_DRIVER_COMPLETE は、データ ソースと接続するために CDatabase::Open 関数で使われます。

ドライバーは、SQLGetInfo SQL_ODBC_API_CONFORMANCE >= SQL_OAC_LEVEL1 および SQLGetInfo SQL_ODBC_SQL_CONFORMANCE >= SQL_OSC_MINIMUM をサポートする必要があります。

CDatabase およびそれに依存するレコードセットでトランザクションをサポートするには、SQLGetInfoSQL_CURSOR_COMMIT_BEHAVIORSQL_CURSOR_ROLLBACK_BEHAVIORSQL_CR_PRESERVE が必要です。 SQL_CR_PRESERVE がないと、トランザクションは無視されます。

SQLGetInfoSQL_DATA_SOURCE_READ_ONLY がサポートされている必要もあります。 この関数が "Y" を返す場合は、データ ソースに対する更新操作は行われません。

CDatabase を読み取り専用で開くと、データ ソースは SQLSetConnectOptionSQL_ACCESS_MODESQL_MODE_READ_ONLY によって読み取り専用に設定されます。

SQLGetInfoSQL_IDENTIFIER_QUOTE_CHAR を呼び出すと、識別子を二重引用符で囲む必要があるかどうかを示す情報がドライバーによって返されます。

デバッグ用に、SQLGetInfo の SQL_DBMS_VER および SQL_DBMS_NAME がドライバーから取得されます。

CDatabaseHDBC に対して SQLSetStmtOptionSQL_QUERY_TIMEOUT および SQL_ASYNC_ENABLE を呼び出すことができます。

SQLError は、任意の引数またはすべての引数を NULL にして呼び出すことができます。

SQLAllocEnvSQLAllocConnectSQLDisconnect、および SQLFreeConnect は、当然サポートする必要があります。

ExecuteSQL

ExecuteSQL は、一時的な HSTMT の割り当てと解放を行うだけでなく、SQLExecDirectSQLFetchSQLNumResultColSQLMoreResults を呼び出します。 SQLCancel は、HSTMT に対して呼び出されます。

GetDatabaseName

SQLGetInfoSQL_DATABASE_NAME が呼び出されます。

BeginTrans、CommitTrans、Rollback

トランザクション要求が発生すると、SQLSetConnectOptionSQL_AUTOCOMMIT および SQLTransactSQL_COMMITSQL_ROLLBACKSQL_AUTOCOMMIT が呼び出されます。

CRecordsets

SQLAllocStmtSQLPrepareSQLExecute (OpenRequery 用)、SQLExecDirect (更新操作用)、および SQLFreeStmt がサポートされている必要があります。 SQLNumResultColsSQLDescribeCol は、さまざまな場合に結果セットに対して呼び出されます。

SQLSetParam は、パラメーター データと DATA_AT_EXEC 機能を結び付けるために使用されます。

SQLBindCol は、出力列のデータ格納位置を ODBC に登録するために使用します。

SQL_LONG_VARCHARSQL_LONG_VARBINARY のデータを取得するには、SQLGetData を 2 回呼び出します。 最初の呼び出しでは、cbMaxValue に 0、pcbValue に有効な値を指定して SQLGetData を呼び出し、列の値を格納するために必要な領域の大きさを取得します。 pcbValue に SQL_NO_TOTAL を設定すると、例外がスローされます。 それ以外の場合は、HGLOBAL が割り当てられ、次の SQLGetData 呼び出しで列の値が返されます。

更新

排他ロックが要求された場合は、SQLGetInfoSQL_LOCK_TYPES を問い合わせます。 SQL_LCK_EXCLUSIVE がサポートされていない場合は、例外がスローされます。

CRecordset (snapshot または dynaset) を更新するときは、別の HSTMT が割り当てられます。 複数の HSTMT をサポートしないドライバーの場合は、カーソル ライブラリがその機能を実現します。 このとき、2 番目の HSTMT への要求が処理される前に、最初の HSTMT への現在のクエリが完了してしまうことがあります。

SQLFreeStmtSQL_CLOSESQL_RESET_PARAMSSQLGetCursorName が更新操作の間に呼び出されます。

outputColumns の中に CLongBinarys がある場合は、ODBC の DATA_AT_EXEC 機能をサポートする必要があります。 SQLExecDirectSQLParamDataSQLPutDataSQL_NEED_DATA を返す必要があります。

SQLExecDirect によってレコードが 1 つだけ更新されたことを確認するために、実行後に SQLRowCount が呼び出されます。

前方向カーソル

Move 操作に必要なのは、SQLFetch のみです。 forwardOnly カーソルは更新をサポートしません。

スナップショット カーソル

スナップショット機能を使用するには、SQLExtendedFetch がサポートされている必要があります。 ドライバーで SQLExtendedFetch がサポートされていない場合は、上に述べたように、ODBC カーソル ライブラリによって必要なサポートが提供されます。

SQLGetInfoSQL_SCROLL_OPTIONSSQL_SO_STATIC をサポートする必要があります。

ダイナセット カーソル

ダイナセットを開くために必要な最小限のサポートを次に示します。

SQLGetInfoSQL_ODBC_VER は "01" より大きな値を返します。

SQLGetInfoSQL_SCROLL_OPTIONSSQL_SO_KEYSET_DRIVEN をサポートする必要があります。

SQLGetInfoSQL_ROW_UPDATES は "Y" を返す必要があります。

SQLGetInfoSQL_POSITIONED_UPDATESSQL_PS_POSITIONED_DELETESQL_PS_POSITIONED_UPDATE をサポートする必要があります。

さらに、排他ロックが必要な場合は、irow を 1、fRefresh を FALSE、fLock を SQL_LCK_EXCLUSIVE として SQLSetPos を呼び出します。

参照

その他の技術情報

番号順テクニカル ノート

カテゴリ別テクニカル ノート