テクニカル ノート 42: ODBC ドライバーの開発に関する推奨事項
Note
次のテクニカル ノートは、最初にオンライン ドキュメントの一部とされてから更新されていません。 結果として、一部のプロシージャおよびトピックが最新でないか、不正になります。 最新の情報について、オンライン ドキュメントのキーワードで関係のあるトピックを検索することをお勧めします。
このノートでは、ODBC ドライバー作成者向けのガイドラインについて説明します。 MFC データベース クラスで作成する ODBC 機能の一般的な要件と前提条件、および想定されるさまざまなセマンティックの詳細について説明します。 3 つの CRecordset
オープン モード (forwardOnly、snapshot、および dynaset) をサポートするために必要なドライバー機能について説明します。
ODBC のカーソル ライブラリ
MFC データベース クラスは、多くの場合、ほとんどのレベル 1 ODBC ドライバーによって提供される機能を上回る機能をユーザーに提供します。 さいわい、ODBC のカーソル ライブラリは、データベース クラスとドライバーの間でそれ自体をレイヤー化し、この追加機能の多くを自動的に提供します。
たとえば、ほとんどの 1.0 ドライバーでは後方スクロールをサポートしていません。 カーソル ライブラリはこれを検出し、ドライバーから行をキャッシュし、SQLExtendedFetch
の FETCH_PREV 呼び出し時にそれらを要求に応じて提供します。
カーソル ライブラリの依存のもう 1 つの重要な例は、位置指定更新です。 ほとんどの 1.0 ドライバーには位置指定更新もありませんが、カーソル ライブラリは現在キャッシュされているデータ値またはキャッシュされたタイムスタンプ値に基づいて、データ ソース上のターゲット行を識別する更新ステートメントを生成します。
クラス ライブラリが複数の行セットを使用することは決してありません。 したがって、常にいくつかの SQLSetPos
ステートメントが行セットの 1 行目に適用されます。
CDatabase
各 CDatabase
は 1 つの HDBC を割り当てます ('s ExecuteSQL
関数が使用されている場合CDatabase
、HSTMT は一時的に割り当てられます。)そのため、複数CDatabase
の HDBC が必要な場合は、HENV ごとに複数の HDBCをサポートする必要があります。
データベース クラスにはカーソル ライブラリが必要です。 これは、SQLSetConnections
呼び出しの SQL_ODBC_CURSORS、SQL_CUR_USE_ODBC に反映されます。
SQLDriverConnect
の SQL_DRIVER_COMPLETE は、データ ソースへの接続を確立するために CDatabase::Open
によって使用されます。
ドライバーは、SQLGetInfo SQL_ODBC_API_CONFORMANCE
>= SQL_OAC_LEVEL1、SQLGetInfo SQL_ODBC_SQL_CONFORMANCE
>= SQL_OSC_MINIMUM をサポートする必要があります。
CDatabase
とその依存レコードセットに対するトランザクションをサポートするには、SQLGetInfo SQL_CURSOR_COMMIT_BEHAVIOR
および SQL_CURSOR_ROLLBACK_BEHAVIOR に SQL_CR_PRESERVE が必要です。 そうしないと、トランザクション制御の実行を試みても無視されます。
SQLGetInfo SQL_DATA_SOURCE_READ_ONLY
がサポートされている必要があります。 それから "Y" が返された場合、データ ソースに対する更新操作は実行されません。
CDatabase
が ReadOnly で開いている場合、データ ソースを読み取り専用に設定する試みは、SQLSetConnectOption SQL_ACCESS_MODE
の SQL_MODE_READ_ONLY を使用して行います。
識別子に引用符が必要な場合は、SQLGetInfo SQL_IDENTIFIER_QUOTE_CHAR
を呼び出して、この情報をドライバーから返す必要があります。
デバッグ目的の場合は、SQLGetInfo SQL_DBMS_VER
と SQL_DBMS_NAME をドライバーから取得します。
SQLSetStmtOption SQL_QUERY_TIMEOUT
と SQL_ASYNC_ENABLE は CDatabase
の HDBC に対して呼び出されることがあります。
SQLError
は、いずれかまたはすべての引数が NULL の場合に呼び出されることがあります。
もちろん、SQLAllocEnv
、SQLAllocConnect
、SQLDisconnect
、および SQLFreeConnect
がサポートされている必要があります。
ExecuteSQL
一時的な HSTMT の割り当てと解放に加えて、ExecuteSQL
は、SQLExecDirect
、SQLFetch
、SQLNumResultCol
、および SQLMoreResults
を呼び出します。 SQLCancel
は HSTMT に対して呼び出されることがあります。
GetDatabaseName
SQLGetInfo SQL_DATABASE_NAME
が呼び出されます。
BeginTrans、CommitTrans、Rollback
SQLSetConnectOption SQL_AUTOCOMMIT
および SQLTransact SQL_COMMIT
の SQL_ROLLBACK と SQL_AUTOCOMMIT は、トランザクション要求が行われた場合に呼び出されます。
CRecordsets
SQLAllocStmt
、SQLPrepare
, SQLExecute
(Open
および Requery
の場合)、SQLExecDirect
(更新操作の場合)、SQLFreeStmt
がサポートされている必要があります。 SQLNumResultCols
と SQLDescribeCol
は、さまざまな時間に設定された結果に対して呼び出されます。
SQLSetParam
は、パラメーター データのバインドと DATA_AT_EXEC 機能に広く使用されます。
SQLBindCol
は、出力列データ ストレージの場所を ODBC に登録するために広く使用されます。
2 つの SQLGetData
呼び出しは、SQL_LONG_VARCHAR および SQL_LONG_VARBINARY データを取得するために使用されます。 最初の呼び出しでは、SQLGetData
を呼び出して、cbMaxValue が 0 だが、pcbValue が有効な列値の合計長の検索が試みられます。 pcbValue が SQL_NO_TOTAL を保持している場合、例外がスローされます。 それ以外の場合は、HGLOBAL が割り当てられ、結果全体を取得するために別の SQLGetData
の呼び出しが行われます。
更新中
ペシミスティック ロックが要求された場合、SQLGetInfo SQL_LOCK_TYPES
が照会されます。 SQL_LCK_EXCLUSIVE がサポートされていない場合、例外がスローされます。
CRecordset
(snapshot または dynaset) の更新を試みると、2 つ目の HSTMT が割り当てられます。 2 つ目の HSTMT をサポートしないドライバーの場合、カーソル ライブラリによってこの機能がシミュレートされます。 残念ながら、これは、2 つ目の HSTMT の要求を処理する前に、最初の HSTMT に対する現在の照会を強制的に完了することを意味する場合があります。
SQLFreeStmt SQL_CLOSE
と SQL_RESET_PARAMS および SQLGetCursorName
は、更新操作中に呼び出されます。
outputColumns に CLongBinarys がある場合は、ODBC のDATA_AT_EXEC 機能がサポートされている必要があります。 これには、SQLExecDirect
、SQLParamData
、および SQLPutData
から SQL_NEED_DATA を返すことが含まれます。
SQLRowCount
は、実行後に、SQLExecDirect
によって更新されたレコードが 1 つのみであることを確認するために呼び出されます。
forwardOnly カーソル
Move
操作には、SQLFetch
のみが必要です。 forwardOnly カーソルは更新をサポートしていない点に注意してください。
snapshot カーソル
スナップショット機能には、SQLExtendedFetch
のサポートが必要です。 上記のように、ODBC カーソル ライブラリは、ドライバーが SQLExtendedFetch
をサポートしていない場合を検出し、必要なサポート自体を提供します。
SQLGetInfo
の SQL_SCROLL_OPTIONS では、SQL_SO_STATIC をサポートする必要があります。
dynaset カーソル
ダイナセットを開くために必要な最小のサポートを次に示します。
SQLGetInfo
の SQL_ODBC_VER が > "01" を返す必要がある。
SQLGetInfo
の SQL_SCROLL_OPTIONS では、SQL_SO_KEYSET_DRIVEN をサポートする必要がある。
SQLGetInfo
の SQL_ROW_UPDATES が "Y" を返す必要がある。
SQLGetInfo
の SQL_POSITIONED_UPDATES では、SQL_PS_POSITIONED_DELETE および SQL_PS_POSITIONED_UPDATE をサポートする必要がある。
さらに、ペシミスティック ロックが要求された場合は、irow 1、fRefresh FALSE、fLock SQL_LCK_EXCLUSIVE を使用して、SQLSetPos
が呼び出されます。