Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 12.0.1 » SQL Anywhere サーバー プログラミング » ODBC サポート

 

64 ビット ODBC での考慮事項

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 値がドライバーによって返されます。

詳細については、[external link] http://support.microsoft.com/kb/298678にある Microsoft のアーティクル『ODBC 64-Bit API Changes in MDAC 2.7』を参照してください。