64 位 ODBC 注意事项

来源:互联网 发布:最好的增高鞋垫知乎 编辑:程序博客网 时间:2024/05/09 09:32

使用 SQLBindCol、SQLBindParameter 或 SQLGetData 这类的 ODBC 函数时,某些参数的类型在函数原型中被设置为 SQLLEN 或 SQLULEN。视您所查看的 Microsoft ODBC API 参考文档的日期而定,您可能会看到被描述为 SQLINTEGER 或 SQLUINTEGER 的相同参数。

SQLLEN 和 SQLULEN 数据项在 64 位 ODBC 应用程序中为 64 位,在 32 位 ODBC 应用程序中为 32 位。SQLINTEGER 和 SQLUINTEGER 数据项在所有平台上均为 32 位。

为说明该问题,从旧版 Microsoft ODBC API 参考中摘选了以下 ODBC 函数原型。

SQLRETURN SQLGetData(     SQLHSTMT     StatementHandle,     SQLUSMALLINT ColumnNumber,     SQLSMALLINT  TargetType,     SQLPOINTER   TargetValuePtr,     SQLINTEGER   BufferLength,     SQLINTEGER  *StrLen_or_IndPtr);

将该函数原型与在 Microsoft Visual Studio 版本 8 的 sql.h 中找到的实际函数原型相比较。

SQLRETURN  SQL_API SQLGetData(    SQLHSTMT      StatementHandle,    SQLUSMALLINT  ColumnNumber,     SQLSMALLINT   TargetType,    SQLPOINTER    TargetValue,     SQLLEN        BufferLength,    SQLLEN       *StrLen_or_Ind);

正如您所见,BufferLength 和 StrLen_or_Ind 参数的类型现在被设置为 SQLLEN,而不是 SQLINTEGER。对于 64 位平台,它们是 64 位,而不是 Microsoft 文档中所述的 32 位。

为避免出现跨平台编译问题,SQL Anywhere 提供了自己的 ODBC 头文件。对于 Windows 平台,您应包括 ntodbc.h 头文件。对于 Unix 平台(如 Linux),您应包括 unixodbc.h 头文件。使用这些头文件可确保与目标平台上的相应 SQL Anywhere ODBC 驱动程序兼容。

下表列出了一些在 64 位和 32 位平台上具有相同或不同存储大小的常见 ODBC 类型。

ODBC API64 位平台32 位平台SQLINTEGER32 位32 位SQLUINTEGER32 位32 位SQLLEN64 位32 位SQLULEN64 位32 位SQLSETPOSIROW64 位16 位SQL_C_BOOKMARK64 位32 位BOOKMARK64 位32 位

如果对数据变量和参数的声明不正确,则您可能会遇到不正确的软件行为。

下表汇总了引入 64 位支持以来发生更改的 ODBC API 函数原型。已对受影响的参数进行注释。Microsoft 文档中的参数名与函数原型中使用的实际参数名不同时,前者将显示在括号中。参数名是指 Microsoft Visual Studio 版本 8 的头文件中使用的参数名。

ODBC API参数(文档中的参数名)SQLBindCol

SQLLEN BufferLength

SQLLEN *Strlen_or_Ind

SQLBindParam

SQLULEN LengthPrecision

SQLLEN *Strlen_or_Ind

SQLBindParameter

SQLULEN cbColDef (ColumnSize)

SQLLEN cbValueMax (BufferLength)

SQLLEN *pcbValue (Strlen_or_IndPtr)

SQLColAttributeSQLLEN *NumericAttributeSQLColAttributesSQLLEN *pfDescSQLDescribeColSQLULEN *ColumnSize (ColumnSizePtr)SQLDescribeParamSQLULEN *pcbParamDef (ParameterSizePtr)SQLExtendedFetch

SQLLEN irow (FetchOffset)

SQLULEN *pcrow (RowCountPtr)

SQLFetchScrollSQLLEN FetchOffsetSQLGetData

SQLLEN BufferLength

SQLLEN *Strlen_or_Ind (Strlen_or_IndPtr)

SQLGetDescRecSQLLEN *Length (LengthPtr)SQLParamOptions

SQLULEN crow,

SQLULEN *pirow

SQLPutDataSQLLEN Strlen_or_IndSQLRowCountSQLLEN *RowCount (RowCountPtr)SQLSetConnectOptionSQLULEN ValueSQLSetDescRec

SQLLEN Length

SQLLEN *StringLength (StringLengthPtr)

SQLLEN *Indicator (IndicatorPtr)

SQLSetParam

SQLULEN LengthPrecision

SQLLEN *Strlen_or_Ind (Strlen_or_IndPtr)

SQLSetPosSQLSETPOSIROW irow (RowNumber)SQLSetScrollOptionsSQLLEN crowKeysetSQLSetStmtOptionSQLULEN Value

某些通过指针传递到 ODBC API 并从其返回的值已经更改,以符合 64 位应用程序的需要。例如,以下的 SQLSetStmtAttr 和 SQLSetDescField 函数值不再是 SQLINTEGER/SQLUINTEGER。此规则同样适用于 SQLGetStmtAttr 和 SQLGetDescField 函数的相应参数。

ODBC APIValue/ValuePtr 变量的类型SQLSetStmtAttr(SQL_ATTR_FETCH_BOOKMARK_PTR)SQLLEN * valueSQLSetStmtAttr(SQL_ATTR_KEYSET_SIZE)SQLULEN valueSQLSetStmtAttr(SQL_ATTR_MAX_LENGTH)SQLULEN valueSQLSetStmtAttr(SQL_ATTR_MAX_ROWS)SQLULEN valueSQLSetStmtAttr(SQL_ATTR_PARAM_BIND_OFFSET_PTR)SQLULEN * valueSQLSetStmtAttr(SQL_ATTR_PARAMS_PROCESSED_PTR)SQLULEN * valueSQLSetStmtAttr(SQL_ATTR_PARAMSET_SIZE)SQLULEN valueSQLSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE)SQLULEN valueSQLSetStmtAttr(SQL_ATTR_ROW_BIND_OFFSET_PTR)SQLULEN * valueSQLSetStmtAttr(SQL_ATTR_ROW_NUMBER)SQLULEN valueSQLSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR)SQLULEN * valueSQLSetDescField(SQL_DESC_ARRAY_SIZE)SQLULEN valueSQLSetDescField(SQL_DESC_BIND_OFFSET_PTR)SQLLEN * valueSQLSetDescField(SQL_DESC_ROWS_PROCESSED_PTR)SQLULEN * valueSQLSetDescField(SQL_DESC_DISPLAY_SIZE)SQLLEN valueSQLSetDescField(SQL_DESC_INDICATOR_PTR)SQLLEN * valueSQLSetDescField(SQL_DESC_LENGTH)SQLLEN valueSQLSetDescField(SQL_DESC_OCTET_LENGTH)SQLLEN valueSQLSetDescField(SQL_DESC_OCTET_LENGTH_PTR)SQLLEN * value

请注意,当前 Microsoft ODBC API 参考的 SQLSetConnectAttr/SQLGetConnectAttr 部分将数字属性的值描述为 SQLUINTER。请注意,这些属性值的类型与描述为 SQLULEN 的 SQLSetStmtAttr/SQLGetStmtAttr 属性值不同。

小心

有一个连接属性,SQL_ATTR_ODBC_CURSORS,由 Microsoft ODBC 驱动程序管理器处理。尽管 Microsoft ODBC API 参考中说该属性是 SQLUINTEGER 值,用于指定驱动程序管理器如何使用 ODBC 游标库,但 64 位版本的驱动程序管理器为 SQLGetConnectAttr 返回一个 64 位的 SQLULEN 值。

__int64 datavalue = 0x1234567812345678;rc = SQLGetConnectAttr( hdbc, attr, &datavalue, 0, 0 );

调用 SQLGetConnectAttr 后,datavalue 的值为 0x0000000000000002,说明了存储的是 64 位值。请务必小心避免这个 Microsoft 驱动程序管理器错误。其它属性值由 SQL Anywhere ODBC 驱动程序来处理,返回 SQLUINTEGER 值,如同 ODBC API 参考中所述。

有关详细信息,请参见 Microsoft 文章 "ODBC 64 位 API 更改在 MDAC 2.7 中" ([external link] http://support.microsoft.com/kb/298678)。

原创粉丝点击