有没有办法用 C++ 查询 .accdb/.mdb 文件?

Posted

技术标签:

【中文标题】有没有办法用 C++ 查询 .accdb/.mdb 文件?【英文标题】:Is there a way to query .accdb/.mdb files with C++? 【发布时间】:2019-05-05 00:40:11 【问题描述】:

我有一个学校项目,我需要开发一个应用程序来查询和写入 Access 数据库文件,但使用 C++。

经过一些关于 ODBC 的研究,我发现它可以帮助我,但我没有运气。我尝试了不同的连接字符串,但似乎没有任何效果。

到目前为止我做了什么:


    #include "pch.h"
    #include <windows.h>
    #include <sqlext.h>
    #include <stdio.h>
    #include <stdlib.h>



    int main()
    
    char szDSN[256] = "Driver=Microsoft Access Driver (*.mdb, 
    *.accdb);DBQ=C:\\EntrySystem.mdb";
    /* Data Access Method used in this sample */
    const char* DAM = "Direct ODBC";

    HENV    hEnv;
    HDBC    hDbc;

    /* ODBC API return status */
    RETCODE rc;

    int     iConnStrLength2Ptr;
    char    szConnStrOut[256];

    unsigned char query[] = "SELECT * from Condomino;";

    SQLCHAR         chval1[128], chval2[128], colName[128];
    int             ret1;
    int             ret2;

    /* Number of rows and columns in result set */
    SQLINTEGER      rowCount = 0;
    SQLSMALLINT     fieldCount = 0, currentField = 0;
    HSTMT           hStmt;

    /* Allocate an environment handle */
    rc = SQLAllocEnv(&hEnv);
    /* Allocate a connection handle */
    rc = SQLAllocConnect(hEnv, &hDbc);

    /* Connect to the 'Northwind 2007.accdb' database */
    rc = SQLDriverConnect(hDbc, NULL, (SQLWCHAR*)szDSN,
        SQL_NTS, (SQLWCHAR*)szConnStrOut,
        255, (SQLSMALLINT*)&iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
    if (SQL_SUCCEEDED(rc))
    
        printf("%s: Successfully connected to database. Data source name: \n  %s\n",
            DAM, szConnStrOut);

        /* Prepare SQL query */
        printf("%s: SQL query:\n  %s\n", DAM, query);

        rc = SQLAllocStmt(hDbc, &hStmt);
        rc = SQLPrepare(hStmt, (SQLWCHAR*)query, SQL_NTS);

        /* Bind result set columns to the local buffers */
        rc = SQLBindCol(hStmt, 1, SQL_C_CHAR, chval1, 128, (SQLINTEGER*)&ret1);
        rc = SQLBindCol(hStmt, 2, SQL_C_CHAR, chval2, 128, (SQLINTEGER*)&ret2);

        /* Excecute the query and create a record set */
        rc = SQLExecute(hStmt);
        if (SQL_SUCCEEDED(rc))
        
            printf("%s: Retrieve schema info for the given result set:\n", DAM);
            SQLNumResultCols(hStmt, &fieldCount);
            if (fieldCount > 0)
            
                for (currentField = 1; currentField <= fieldCount; currentField++)
                
                    SQLDescribeCol(hStmt, currentField,
                        (SQLWCHAR*)colName, sizeof(colName), 0, 0, 0, 0, 0);
                    printf(" | %s", colName);
                
                printf("\n");
            
            else
            
                printf("%s: Error: Number of fields in the result set is 0.\n", DAM);
            

            printf("%s: Fetch the actual data:\n", DAM);
            /* Loop through the rows in the result set */
            rc = SQLFetch(hStmt);
            while (SQL_SUCCEEDED(rc))
            
                printf(" | %s | %s\n", chval1, chval2);
                rc = SQLFetch(hStmt);
                rowCount++;
            ;

            printf("%s: Total Row Count: %d\n", DAM, rowCount);
            rc = SQLFreeStmt(hStmt, SQL_DROP);
        
    
    else
    
        printf("%s: Couldn't connect to %s.\nLastError: %d\n", DAM, szDSN, GetLastError());
    

    /* Disconnect and free up allocated handles */
      SQLDisconnect(hDbc);
      SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
      SQLFreeHandle(SQL_HANDLE_ENV, hEnv);

      printf("%s: Cleanup. Done.\n", DAM);

      return 0;
    

我希望它查询我的表“condomino”中的所有行,但库 (sqlext) 不断给我错误“0”。欢迎任何帮助,如果您有任何其他解决方案,请告诉我。

【问题讨论】:

你看social.msdn.microsoft.com/Forums/vstudio/en-US/…了吗? 【参考方案1】:

是的。

您似乎在使用 Access 连接字符串时遇到问题。另一种方法是创建 User DNS ;转到控制面板/管理工具/ODBC 数据源/选择 Microsoft Access 数据库 - 配置并设置您的 *.mdb 路径(推荐使用 *.accdb)

现在您的连接字符串将被简化为(驱动程序名称区分大小写):

SQLWCHAR outstr[1024];
SQLSMALLINT outstrlen;
SQLReturnCode = SQLDriverConnect(hDatabase, NULL, L"DSN=Microsoft Access Driver;", SQL_NTS,
            outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);

【讨论】:

以上是关于有没有办法用 C++ 查询 .accdb/.mdb 文件?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法证明我的 C++ 程序的属性?

有没有办法读取 C++ 中连续特定行上的数字?

有没有办法用 pgpromse 查看限制偏移查询是不是已经结束?

有没有办法在运行时检测堆栈溢出? (c++)

在 django 中,有没有办法在单个查询中直接用相关对象注释查询?

有没有办法用查询字符串填充表单?