SQLBindCol、SQLBindParameter、SQLGetData などの ODBC 関数を使用する場合、一部のパラメーターは SQLLEN や SQLULEN として関数プロトタイプに型指定されます。参照している Microsoft の『ODBC API Reference』マニュアルによっては、同じパラメーターが SQLINTEGER や SQLUINTEGER として記述されている場合があります。
SQLLEN および SQLULEN のデータ項目は、64 ビットの ODBC アプリケーションでは 64 ビット、32 ビットの ODBC アプリケーションでは 32 ビットになります。SQLINTEGER および SQLUINTEGER のデータ項目は、すべてのプラットフォームで 32 ビットです。
この問題を説明するために、次の ODBC 関数プロトタイプを Microsoft の旧版の『ODBC API Reference』から抜粋しました。
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 パラメーターが、SQLINTEGER 型ではなく SQLLEN 型と指定されるようになったことがわかります。64 ビットのプラットフォームでは、32 ビット数ではなく 64 ビット数であることが Microsoft のマニュアルからわかります。
異種プラットフォーム間でのコンパイルの問題を回避するために、SQL Anywhere には独自の ODBC ヘッダーファイルがあります。Windows プラットフォームの場合は、ntodbc.h ヘッダーファイルをインクルードしてください。Linux などの UNIX プラットフォームの場合は、unixodbc.h ヘッダーファイルをインクルードしてください。これらのヘッダーファイルを使用することで、対象プラットフォーム用の SQL Anywhere ODBC ドライバーとの互換性が確保されます。
次の表に示すのは、一般的な ODBC のタイプの一部です。64 ビットのプラットフォームと 32 ビットのプラットフォームでストレージサイズが同じものもあれば、異なるものもあります。
ODBC API | 64 ビットのプラットフォーム | 32 ビットのプラットフォーム |
---|---|---|
SQLINTEGER | 32 ビット | 32 ビット |
SQLUINTEGER | 32 ビット | 32 ビット |
SQLLEN | 64 ビット | 32 ビット |
SQLULEN | 64 ビット | 32 ビット |
SQLSETPOSIROW | 64 ビット | 16 ビット |
SQL_C_BOOKMARK | 64 ビット | 32 ビット |
BOOKMARK | 64 ビット | 32 ビット |
データ変数とパラメーターを間違って宣言すると、ソフトウェアが正しく動作しない可能性があります。
次の表は、64 ビットのサポートの導入とともに変更された、ODBC API の関数プロトタイプを示します。影響を受けるパラメーターが記載されています。関数プロトタイプで使用される実際のパラメーター名と Microsoft のマニュアルに記載されているパラメーター名が異なる場合は、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) |
SQLColAttribute | SQLLEN *NumericAttribute |
SQLColAttributes | SQLLEN *pfDesc |
SQLDescribeCol | SQLULEN *ColumnSize (ColumnSizePtr) |
SQLDescribeParam | SQLULEN *pcbParamDef (ParameterSizePtr) |
SQLExtendedFetch |
SQLLEN irow (FetchOffset) SQLULEN *pcrow (RowCountPtr) |
SQLFetchScroll | SQLLEN FetchOffset |
SQLGetData |
SQLLEN BufferLength SQLLEN *Strlen_or_Ind (Strlen_or_IndPtr) |
SQLGetDescRec | SQLLEN *Length (LengthPtr) |
SQLParamOptions |
SQLULEN crow, SQLULEN *pirow |
SQLPutData | SQLLEN Strlen_or_Ind |
SQLRowCount | SQLLEN *RowCount (RowCountPtr) |
SQLSetConnectOption | SQLULEN Value |
SQLSetDescRec |
SQLLEN Length SQLLEN *StringLength (StringLengthPtr) SQLLEN *Indicator (IndicatorPtr) |
SQLSetParam |
SQLULEN LengthPrecision SQLLEN *Strlen_or_Ind (Strlen_or_IndPtr) |
SQLSetPos | SQLSETPOSIROW irow (RowNumber) |
SQLSetScrollOptions | SQLLEN crowKeyset |
SQLSetStmtOption | SQLULEN Value |
ポインターを介して ODBC API 呼び出しに渡され、ODBC API 呼び出しから返される値の一部は、64 ビットのアプリケーションに対応するために変更されました。たとえば、次の SQLSetStmtAttr および SQLSetDescField 関数の値は、SQLINTEGER/SQLUINTEGER ではなくなりました。SQLGetStmtAttr および SQLGetDescField 関数の該当するパラメーターに関しても同様です。
ODBC API | Value/ValuePtr 変数の型 |
---|---|
SQLSetStmtAttr(SQL_ATTR_FETCH_BOOKMARK_PTR) | SQLLEN * value |
SQLSetStmtAttr(SQL_ATTR_KEYSET_SIZE) | SQLULEN value |
SQLSetStmtAttr(SQL_ATTR_MAX_LENGTH) | SQLULEN value |
SQLSetStmtAttr(SQL_ATTR_MAX_ROWS) | SQLULEN value |
SQLSetStmtAttr(SQL_ATTR_PARAM_BIND_OFFSET_PTR) | SQLULEN * value |
SQLSetStmtAttr(SQL_ATTR_PARAMS_PROCESSED_PTR) | SQLULEN * value |
SQLSetStmtAttr(SQL_ATTR_PARAMSET_SIZE) | SQLULEN value |
SQLSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE) | SQLULEN value |
SQLSetStmtAttr(SQL_ATTR_ROW_BIND_OFFSET_PTR) | SQLULEN * value |
SQLSetStmtAttr(SQL_ATTR_ROW_NUMBER) | SQLULEN value |
SQLSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR) | SQLULEN * value |
SQLSetDescField(SQL_DESC_ARRAY_SIZE) | SQLULEN value |
SQLSetDescField(SQL_DESC_BIND_OFFSET_PTR) | SQLLEN * value |
SQLSetDescField(SQL_DESC_ROWS_PROCESSED_PTR) | SQLULEN * value |
SQLSetDescField(SQL_DESC_DISPLAY_SIZE) | SQLLEN value |
SQLSetDescField(SQL_DESC_INDICATOR_PTR) | SQLLEN * value |
SQLSetDescField(SQL_DESC_LENGTH) | SQLLEN value |
SQLSetDescField(SQL_DESC_OCTET_LENGTH) | SQLLEN value |
SQLSetDescField(SQL_DESC_OCTET_LENGTH_PTR) | SQLLEN * value |
Microsoft の現在の『ODBC API Reference』では、SQLSetConnectAttr/SQLGetConnectAttr に関して、数値属性値が SQLUINTEGER として記述されています。これらの属性値の型は、SQLULEN として記述されている SQLSetStmtAttr/SQLGetStmtAttr 属性値とは異なります。
Microsoft ODBC ドライバーマネージャーによって処理される接続属性に、SQL_ATTR_ODBC_CURSORS があります。Microsoft の『ODBC API Reference』には、この属性が、ドライバーマネージャーによる ODBC カーソルライブラリの使用方法を指定する SQLUINTEGER 値であると記載されていますが、64 ビットバージョンのドライバーマネージャーは、SQLGetConnectAttr に対して 64 ビットの SQLULEN 値を返します。
__int64 datavalue = 0x1234567812345678; rc = SQLGetConnectAttr( hdbc, attr, &datavalue, 0, 0 ); |
SQLGetConnectAttr を呼び出した後、datavalue
の値は 0x0000000000000002
となり、64 ビットの値が格納されたことがわかります。Microsoft ドライバーマネージャーのこのバグを回避するよう、十分注意してください。他の属性値は SQL Anywhere ODBC ドライバーで処理され、『ODBC API Reference』に記載されているように、SQLUINTEGER
値がドライバーによって返されます。
詳細については、 http://support.microsoft.com/kb/298678にある Microsoft のアーティクル『ODBC 64-Bit API Changes in MDAC 2.7』を参照してください。
![]() |
DocCommentXchange で意見交換できます
|
Copyright © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |