AnsweredAssumed Answered

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

Question asked by ranja on Mar 1, 2014
Latest reply on May 12, 2015 by TSGal

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.

Outcomes