4 Replies Latest reply on May 12, 2015 6:41 AM by TSGal

    64-bit ODBC driver fails on SQLColAttribute call but not on SQLColAttributes call

    ranja

      Summary

      64-bit ODBC driver fails on SQLColAttribute call but not on SQLColAttributes call

      Product

      FileMaker Server

      Version

      13

      Operating system version

      Windows Server 2008R2 SP1

      Description of the issue

      In 64bit Windows, the SQLColAttribute ODBC function returns an error code -2, whereas the old SQLColAttributes function, which is now deprecated, returns 0 (success).

      Steps to reproduce the problem

      I wrote the following Win64 console application with MFC enabled.  This code accesses a FileMaker database via FileMaker ODBC 64bit driver.

      // ODBCTest.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
      //

      #include "stdafx.h"
      #include "ODBCTest.h"
      #include "afxdb.h"
      #ifdef _DEBUG
      #define new DEBUG_NEW
      #endif


      // 唯一のアプリケーション オブジェクトです。

      CWinApp theApp;

      using namespace std;

      int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
      {
           int nRetCode = 0;

           HMODULE hModule = ::GetModuleHandle(NULL);

           if (hModule != NULL)
           {
                // MFC を初期化して、エラーの場合は結果を印刷します。
                if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
                {

                     _tprintf(_T("Fatal error: MFC の初期化ができませんでした。\n"));
                     nRetCode = 1;
                }
                else
                {
                     {
                          CDatabase db;
                          if (db.OpenEx(_T("DRIVER={FileMaker ODBC};Database=TestODBC;Server=gaia;UID=admin;PWD=;"), CDatabase::noOdbcDialog))
                          {
                               _tprintf(_T("Opened\n"));

                               //実行
                               CRecordset rs(&db);
                               try{
                                    rs.Open(CRecordset::forwardOnly, _T("SELECT Field2  FROM TestODBC WHERE Field1 = 4"));

                                    CODBCFieldInfo fi;

                                    short nFields = rs.GetODBCFieldCount();


                                    if (!rs.IsEOF()) {
                                         SWORD cbDescMax = 256;
                                         LPWSTR p = new wchar_t[cbDescMax];

                                         SQLSMALLINT cbDesc;
                                         SQLLEN fDesc;
                                         RETCODE r = ::SQLColAttributesW(rs.m_hstmt, 1, SQL_DESC_NAME, p, cbDescMax, &cbDesc, &fDesc);

                                         if (r == 0){

                                              _tprintf(_T("%s\n"), p);
                                         }
                                         else{

                                              _tprintf(_T("Error=%d\n"), r);
                                         }
                                         r = ::SQLColAttributeW(rs.m_hstmt, 1, SQL_DESC_NAME, p, cbDescMax, &cbDesc, &fDesc);
                                         if (r == 0){

                                              _tprintf(_T("%s\n"), p);
                                         }
                                         else{

                                              _tprintf(_T("Error=%d\n"), r);
                                         }
                                         delete[] p;

                                    }


                               }
                               catch (...){}
                               rs.Close();
                               db.Close();
                          }
                     }
                }
           }
           else
           {
                _tprintf(_T("Fatal error: GetModuleHandle failed.\n"));
                nRetCode = 1;
           }

           return nRetCode;
      }

      When I run this code, the SQLColAttributesW call ends successfully but the SQLColAttributeW call fails with an error code -2.
      This issue occurs only in 64bit Windows environment.

      Since Microsoft .NET Framework's ODBC layer now relies on SQLColAttribute call, this problem should be fixed as soon as possible.

      Expected result

      SQLColAttribute must return 0.

      Actual result

      SQLColAttribute returns -2.

      Workaround

      Use SQLDescribeCol instead if possible.
      Or open the FMODBC64.DLL file with a hex editor and change the entry point of SQLColAttributeW to the same value as of SQLColAttributesW.