为啥我的代码不适用于较旧的访问驱动程序?

Posted

技术标签:

【中文标题】为啥我的代码不适用于较旧的访问驱动程序?【英文标题】:why doesn't my code work with older access drivers?为什么我的代码不适用于较旧的访问驱动程序? 【发布时间】:2013-11-14 14:59:50 【问题描述】:
// SQLTables.cpp
// compile with: user32.lib odbc32.lib
#include <windows.h>
#include <sqlext.h>
#include <stdio.h>

// simple helper functions
int mysqlSuccess(SQLRETURN rc) 
   return (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO);


struct DataBinding 
   SQLSMALLINT TargetType;
   SQLPOINTER TargetValuePtr;
   SQLINTEGER BufferLength;
   SQLLEN StrLen_or_Ind;
;

void printCatalog(const struct DataBinding* catalogResult, int numCols) 
    for(int i = 0; i < numCols; i++)
       if (catalogResult[i].StrLen_or_Ind != SQL_NULL_DATA) 
          printf("Catalog Name(%d) = %s \t", i + 1, (char *)catalogResult[i].TargetValuePtr);
    printf("\n");


// remember to disconnect and free memory, and free statements and handles
int main() 
   int bufferSize = 1024, i, numCols = 18;
   struct DataBinding* catalogResult = (struct DataBinding*) malloc( numCols * sizeof(struct DataBinding) );
   wchar_t* dbName = (wchar_t *)malloc( sizeof(wchar_t)*bufferSize );
   wchar_t* userName = (wchar_t *)malloc( sizeof(wchar_t)*bufferSize );

   // declare and initialize the environment, connection, statement handles
   SQLHENV henv = NULL;   // Environment   
   SQLHDBC hdbc = NULL;   // Connection handle
   SQLHSTMT hstmt = NULL;   // Statement handle

   SQLRETURN retCode;
   HWND desktopHandle = GetDesktopWindow();   // desktop's window handle
   SQLWCHAR connStrbuffer[1024];
   SQLSMALLINT connStrBufferLen;

   retCode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
   retCode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, -6);
   retCode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
   //retCode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)10, 0);
   //retCode = SQLSetConnectAttr(hdbc,fOption,(SQLPOINTER)(size_t)param,0);
   //retCode = SQLDriverConnect(hdbc, desktopHandle, (SQLCHAR*)"DSN=footballDB1;UID=\"\";PWD=\"\"", SQL_NTS, (SQLCHAR*)connStrbuffer, 1024 + 1, &connStrBufferLen, SQL_DRIVER_NOPROMPT);
   retCode = SQLDriverConnect(hdbc, desktopHandle, (SQLCHAR*)"DSN=footballDB;UID=\"\";PWD=\"\"", SQL_NTS, (SQLCHAR*)connStrbuffer, 1024 + 1, &connStrBufferLen, SQL_DRIVER_NOPROMPT);
   retCode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
   retCode = SQLGetInfo(hdbc, SQL_DBMS_NAME , dbName, (SQLSMALLINT)bufferSize, (SQLSMALLINT *)&bufferSize);
   printf("%s\n", dbName);
   retCode = SQLGetInfo(hdbc, SQL_USER_NAME, userName, (SQLSMALLINT)bufferSize, (SQLSMALLINT *)&bufferSize);

   bufferSize = 1024;

   // allocate memory for the binding
   // free this memory when done
   for ( i = 0 ; i < numCols ; i++ ) 
      catalogResult[i].TargetType = SQL_C_CHAR;
      catalogResult[i].BufferLength = (bufferSize + 1);
      catalogResult[i].TargetValuePtr = malloc( sizeof(unsigned char)*catalogResult[i].BufferLength );
   

   // setup the binding (can be used even if the statement is closed by closeStatementHandle)
   for ( i = 0 ; i < numCols ; i++ )
      retCode = SQLBindCol(hstmt, (SQLUSMALLINT)i + 1, catalogResult[i].TargetType, catalogResult[i].TargetValuePtr, catalogResult[i].BufferLength, &(catalogResult[i].StrLen_or_Ind));

   // all catalogs query
   printf( "A list of names of all catalogs\n" );
   //retCode = SQLTables( hstmt, (SQLCHAR*)"%", SQL_NTS, (SQLCHAR*)NULL, SQL_NTS, (SQLCHAR*)NULL, SQL_NTS, (SQLCHAR*)NULL, SQL_NTS );   
   retCode = SQLTables( hstmt, (unsigned char*)NULL, SQL_NTS, (unsigned char*)NULL, SQL_NTS, (unsigned char*)NULL, SQL_NTS, (unsigned char*)"'VIEW','TABLE'", SQL_NTS );
   //retCode = SQLTables( hstmt, (SQLCHAR*)NULL, 0, (SQLCHAR*)"schema1", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"'VIEW','TABLE'", SQL_NTS );
   //retCode = SQLTables( hstmt, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"%", SQL_NTS, (SQLCHAR*)"test", SQL_NTS);
   //retCode = SQLColumns(hstmt, (SQLCHAR*)NULL, 0, (SQLCHAR*)NULL, SQL_NTS, (SQLCHAR*)"test", SQL_NTS, (SQLCHAR*)NULL, 0);
   //retCode = SQLColumns(hstmt, (SQLCHAR*)NULL, 0, (SQLCHAR*)NULL, SQL_NTS, (SQLCHAR*)"CLAIMS_HISTORY_1", SQL_NTS, (SQLCHAR*)NULL, 0);
   printf( "retCode = %d:%d\n", retCode, SQL_SUCCESS);   
   for ( retCode = SQLFetch(hstmt) ;  MySQLSuccess(retCode) ; retCode = SQLFetch(hstmt) )
      printCatalog( catalogResult, numCols );
   getchar();

这段代码应该返回数据库中的表名,并适用于访问保存有 *.accdb(即 Microsoft 驱动程序)扩展名的数据库,我猜这是最新的驱动程序之一,但我不是能够弄清楚为什么它不能与 Driver do Microsoft Access (*.mdb) 一起使用。谁能告诉我为什么会这样?

这是使用最新驱动程序创建 DSN 时的示例输出。

ACCESS
A list of names of all catalogs
retCode = 0:0
Catalog Name(1) = C:\Users\akisho02\Desktop\New folder (4)\football club db2.acc
db      Catalog Name(3) = db_clubs      Catalog Name(4) = TABLE         Catalog
≡¡║ε½½½½½½½½■ε■ε■ε■     Catalog Name(18) =
Catalog Name(1) = C:\Users\akisho02\Desktop\New folder (4)\football club db2.acc
db      Catalog Name(3) = db_items      Catalog Name(4) = TABLE         Catalog
≡¡║ε½½½½½½½½■ε■ε■ε■     Catalog Name(18) =
Catalog Name(1) = C:\Users\akisho02\Desktop\New folder (4)\football club db2.acc
db      Catalog Name(3) = db_REGION     Catalog Name(4) = TABLE         Catalog

这是我使用早期驱动程序创建 DSN 时的示例输出

ACCESS
A list of names of all catalogs
retCode = 0:0
Catalog Name(1) = C:\Users\akisho02\Desktop\football club db    Catalog Name(3)
≡¡║ε½½½½½½½½■ε■ε■ε■     Catalog Name(18) =      Catalog Name(6) =
Catalog Name(1) = C:\Users\akisho02\Desktop\football club db    Catalog Name(3)
≡¡║ε½½½½½½½½■ε■ε■ε■     Catalog Name(18) =      Catalog Name(6) =
Catalog Name(1) = C:\Users\akisho02\Desktop\football club db    Catalog Name(3)
≡¡║ε½½½½½½½½■ε■ε■ε■     Catalog Name(18) =      Catalog Name(6) =

【问题讨论】:

你从哪里得到哪个错误? 我没有收到错误消息。 目录名称(1) = C:\Users\akisho02\Desktop\football club db 目录名称(3) ≡¡║ε½½½½½½½■ε■ε■ε■ 目录名称(18) = 目录名称(6) = 目录名称(1) = C:\Users\akisho02\Desktop\football club db 目录名称(3) ≡¡║ε½½½½½½½■ε■ε■ε■ 目录名称(18) = 目录名称(6) =目录名称(1) = C:\Users\akisho02\Desktop\football club db 目录名称(3) ≡¡║ε½½½½½½½■ε■ε■ε■ 目录名称(18) = 目录名称(6) = 目录名称(1 ) = C:\Users\akisho02\Desktop\football club db 目录名称(3) 这是我使用旧版驱动程序运行代码时的示例输出 请将您的问题的更新/添加添加到问题本身。您的评论或多或少难以阅读。谢谢。 【参考方案1】:

这是我在微软访问驱动程序中看到的一个错误。我建议您在设置数据库连接时使用系统提供的最新版本。

【讨论】:

以上是关于为啥我的代码不适用于较旧的访问驱动程序?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 C 程序不适用于评分?

无法在 xCode 12 上以编程方式为较旧的 iOS 版本创建应用程序

哪个 CUDA Toolkit 版本适用于较旧的 NVIDIA 驱动程序

如何在较旧的 GPU 上测试 OpenGL 应用程序?

SumoSelect 处理事件不适用于 Android 设备

以编程方式将PC置于睡眠模式