Share via


TN042:ODBC 驱动程序开发人员建议

注意

以下技术说明在首次包括在联机文档中后未更新。 因此,某些过程和主题可能已过时或不正确。 要获得最新信息,建议你在联机文档索引中搜索热点话题。

此说明介绍 ODBC 驱动程序编写器的指南。 它概述了 MFC 数据库类对 ODBC 功能提出的一般要求和假设,以及各种预期的语义详细信息。 介绍支持三种 CRecordset 打开模式(只进、快照和动态集)所需的驱动程序功能。

ODBC 的游标库

MFC 数据库类向用户提供的功能在许多情况下超过大多数级别 1 ODBC 驱动程序提供的功能。 幸运的是,ODBC 的游标库会将自己置于数据库类和驱动程序之间,并且会自动提供大部分附加功能。

例如,大多数 1.0 驱动程序不支持向后滚动。 游标库可以检测到这一点,并且将缓存驱动程序中的行,然后按 SQLExtendedFetch 中的 FETCH_PREV 调用的请求显示这些行。

游标库依赖的另一个重要示例是定位更新。 大多数 1.0 驱动程序也没有定位更新,但游标库将生成更新语句,这些语句根据数据源的当前缓存数据值或缓存时间戳值来标识数据源上的目标行。

类库从不使用多个行集。 因此,少数 SQLSetPos 语句始终应用于行集的第 1 行。

CDatabases

每个 CDatabase 分配单个 HDBC。 (如果使用 CDatabaseExecuteSQL 函数,则暂时分配 HSTMT。)因此,如果需要多个 CDatabase,则必须支持每个 HENV 的多个 HDBC

数据库类需要游标库。 这反映在 SQLSetConnections 调用 SQL_ODBC_CURSORS、SQL_CUR_USE_ODBC 中。

SQLDriverConnect,SQL_DRIVER_COMPLETECDatabase::Open 用来建立与数据源的连接。

驱动程序必须支持 SQLGetInfo SQL_ODBC_API_CONFORMANCE>= SQL_OAC_LEVEL1SQLGetInfo 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

可以在 CDatabase的 HDBC 上调用 SQLSetStmtOption SQL_QUERY_TIMEOUT 和 SQL_ASYNC_ENABLE

可以使用任何或所有参数 NULL 调用 SQLError

当然,必须支持 SQLAllocEnvSQLAllocConnectSQLDisconnectSQLFreeConnect

ExecuteSQL

除了分配和释放临时 HSTMTExecuteSQL 还调用 SQLExecDirectSQLFetchSQLNumResultColSQLMoreResults。 可以在 HSTMT 上调用 SQLCancel

GetDatabaseName

将调用 SQLGetInfo SQL_DATABASE_NAME

BeginTrans、CommitTrans、Rollback

如果发出事务请求,将调用 SQLSetConnectOption SQL_AUTOCOMMITSQLTransact SQL_COMMIT、SQL_ROLLBACK 和 SQL_AUTOCOMMIT

CRecordsets

必须支持 SQLAllocStmtSQLPrepareSQLExecute(对于 OpenRequery)、SQLExecDirect(对于更新操作)、SQLFreeStmt。 将在各种时间对结果集调用 SQLNumResultColsSQLDescribeCol

SQLSetParam 广泛用于绑定参数数据和 DATA_AT_EXEC 功能。

SQLBindCol 广泛用于向 ODBC 注册输出列数据存储位置。

两个 SQLGetData 调用用于检索 SQL_LONG_VARCHAR 和 SQL_LONG_VARBINARY 数据。 第一次调用尝试通过调用 cbMaxValue 为 0 但具有有效的 pcbValue 的 SQLGetData 来查找列值的总长度。 如果 pcbValue 保留 SQL_NO_TOTAL,则会引发异常。 否则,会分配 HGLOBAL,并进行另一个 SQLGetData 调用来检索整个结果。

更新

如果请求悲观锁定,则会查询 SQLGetInfo SQL_LOCK_TYPES。 如果不支持 SQL_LCK_EXCLUSIVE,则会引发异常。

尝试更新 CRecordset(快照或动态集)将导致分配第二个 HSTMT。 对于不支持第二个 HSTMT 的驱动程序,游标库将模拟此功能。 遗憾的是,这有时可能意味着在处理第二个 HSTMT 的请求之前,迫使第一个 HSTMT 上的当前查询完成。

将在更新操作期间调用 SQLFreeStmt SQL_CLOSE、SQL_RESET_PARAMSSQLGetCursorName

如果 outputColumns 中有 CLongBinary,则必须支持 ODBC 的 DATA_AT_EXEC 功能。 这包括从 SQLExecDirectSQLParamDataSQLPutData 返回 SQL_NEED_DATA

执行后调用 SQLRowCount 以验证只有 1 条记录已由 SQLExecDirect 更新。

只进游标

只有 SQLFetchMove 操作是必需的。 请注意,只进游标不支持更新。

快照游标

快照功能需要 SQLExtendedFetch 支持。 如上所述,ODBC 游标库将检测驱动程序何时不支持 SQLExtendedFetch,并本身提供必要的支持。

SQLGetInfo、SQL_SCROLL_OPTIONS 必须支持 SQL_SO_STATIC

动态集游标

下面是打开动态集所需的最低支持:

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_EXCLUSIVESQLSetPos

另请参阅

按编号列出的技术说明
按类别列出的技术说明