2

我正在构建自定义 ODBC 驱动程序。

我的主要方法:

int main(int argc, char** argv) {

    SQLRETURN status;
    //SQLHANDLE hEnv;
    //SQLHANDLE hStmt;
    SQLHENV hEnv;
    SQLHDBC dbc = 0;
    SQLHSTMT hStmt;
    SQLCHAR ConnStrOut[1024];

    SQLSMALLINT x;

    // startup banner
    //printf();

    MessageBox(GetDesktopWindow(), "ODBC Client\n\n", "Driver", MB_OK);

    // show query to be executed
    printf("Query: %s\n", "SELECT VISITS FROM TRAFFIC");

    // allocate ENVIRONMENT
    status = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);

    // check for error
    ODBC_CHK_ERROR(SQL_HANDLE_ENV, hEnv, status, "");

    // set the ODBC version for behaviour expected
    status = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
    CHECK_STATUS(status, (UCHAR*)"SQLSetEnvAttr", hEnv, SQL_HANDLE_ENV);

    // check for error
    ODBC_CHK_ERROR(SQL_HANDLE_ENV, hEnv, status, "");

    // allocate CONNECTION
    status = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &dbc);

    // check for error
    ODBC_CHK_ERROR(SQL_HANDLE_ENV, hEnv, status, "");


    // ----------- real connection takes place at this point 

   status = SQLDriverConnect(dbc, GetDesktopWindow(),
            (unsigned char*) "DSN=myDSN",
            SQL_NTS, ConnStrOut, 1024, &x,
            SQL_DRIVER_PROMPT);


    if (SQL_SUCCEEDED(status)) {
        printf("Connected\n");
        printf("Returned connection string was:\n\t%s\n", ConnStrOut);
        //SQLDisconnect(dbc);   
    }

当我使用示例客户端运行 main 时,一切正常。

但是,当我尝试使用 odbc 测试工具 odbcte32 或其他 odbc 客户端(如 SqlDbx 或 QTODBC)时,一旦我尝试使用“myDSN”(使用我的自定义驱动程序)建立连接,我总是得到:[Microsoft][ODBC Driver Manager] 驱动程序不支持此功能

我已经正确实现了 SQLDriverConnect 函数,通过从使用我编译的驱动程序 DLL 的用户 DSN 读取键值对来创建 OutConnectionString。

我已经为所有 odbc 函数定义了骨架http://msdn.microsoft.com/en-us/library/windows/desktop/ms714562(v=vs.85).aspx

我使用 minGW 编译器(32 位)编译我的自定义潜水员。我有 64 位 Windows 7 操作系统,但我正在运行 32 位 ODBC 测试工具。

这真让我抓狂。我不明白我的驱动程序不支持哪个特定功能。同样,我为所有需要的功能创建了骨架。这是列表:

SQLAllocConnect , SQLAllocEnv , SQLAllocStmt , SQLAllocHandle , SQLFreeConnect , SQLFreeEnv , SQLFreeStmt , SQLBindCol , SQLCancel , SQLConnect , SQLDescribeCol , SQLDisconnect , SQLExecDirect , SQLExecute , SQLExtendedFetch , SQLFetch , SQLGetCursorName , SQLNumResultCols , SQLPrepare , SQLRowCount , SQLSetCursorName , SQLColumns , SQLDriverConnect , SQLGetData , SQLGetInfo , SQLGetTypeInfo,SQLParamData,SQLPutData,SQLStatistics,SQLTables,SQLBrowseConnect,SQLColumnPrivileg,SQLDescribeParam,SQLForeignKeys,SQLMoreResults,SQLNativeSql,SQLNumParams,SQLPrimaryKeys , SQLProcedureColum, SQLProcedures , SQLSetPos , SQLTablePrivilege, SQLBindParameter , SQLCloseCursor , SQLColAttribute , SQLCopyDesc , SQLEndTran , SQLFetchScroll , SQLFreeHandle , SQLGetConnectAttr, SQLGetDescField , SQLGetDescRec , SQLGetDiagField , SQLGetDiagRec , SQLGetEnvAttr , SQLGetStmtAttr , SQLSetConnectAttr, SQLSetDescField , SQLSetDescRec , SQLSetEnvAttr , SQLSetStmtAttr , SQLBulkOperations, SQLSpecialColumns。SQLFreeHandle、SQLGetConnectAttr、SQLGetDescField、SQLGetDescRec、SQLGetDiagField、SQLGetDiagRec、SQLGetEnvAttr、SQLGetStmtAttr、SQLSetConnectAttr、SQLSetDescField、SQLSetDescRec、SQLSetEnvAttr、SQLSetStmtAttr、SQLBulkOperations、SQLSpecialColumns。SQLFreeHandle、SQLGetConnectAttr、SQLGetDescField、SQLGetDescRec、SQLGetDiagField、SQLGetDiagRec、SQLGetEnvAttr、SQLGetStmtAttr、SQLSetConnectAttr、SQLSetDescField、SQLSetDescRec、SQLSetEnvAttr、SQLSetStmtAttr、SQLBulkOperations、SQLSpecialColumns。

编辑:

弄清楚了。SQLDisconnect 定义不正确。确保传递的所有参数都是正确的。正确的定义是:

RETCODE SQL_API SQLDisconnect(SQLHDBC pHandle) {
    __CHK_HANDLE(pHandle, SQL_HANDLE_DBC, SQL_ERROR);
    _SQLFreeDiag(_DIAGCONN(pHandle));
    _SQLDisconnect((PGENODBCCONN) pHandle);

    return (SQL_SUCCESS);
}

我想出来的方法:创建.def文件(将其命名为与驱动程序DLL文件名相同,即在我的情况下是axodbc.def),列出驱动程序中存在的所有函数,如下所示:

LIBRARY   axodbc
DESCRIPTION "Driver 1 definitions"
EXPORTS
    SQLAllocConnect
    SQLAllocEnv
    SQLAllocStmt
    SQLAllocHandle
    SQLFreeConnect
    SQLFreeEnv
    SQLFreeStmt
    SQLBindCol
    SQLCancel
    SQLConnect
    SQLDescribeCol
    SQLExecDirect
    SQLExecute
    SQLDisconnect
    SQLExtendedFetch
    SQLFetch
    SQLGetCursorName
    SQLNumResultCols
    SQLPrepare
    SQLRowCount
    SQLSetCursorName
    SQLColumns
    SQLDriverConnect
    SQLGetData
    SQLGetInfo
    SQLGetTypeInfo
    SQLParamData
    SQLPutData
    SQLStatistics
    SQLTables
    SQLBrowseConnect
    SQLColumnPrivileges
    SQLDescribeParam
    SQLForeignKeys
    SQLMoreResults
    SQLNativeSql
    SQLNumParams
    SQLPrimaryKeys
    SQLProcedureColumns
    SQLProcedures
    SQLSetPos
    SQLTablePrivileges
    SQLBindParameter
    SQLCloseCursor
    SQLColAttribute
    SQLCopyDesc
    SQLEndTran
    SQLFetchScroll
    SQLFreeHandle
    SQLGetConnectAttr
    SQLGetDescField
    SQLGetDescRec
    SQLGetDiagField
    SQLGetDiagRec
    SQLGetEnvAttr
    SQLGetStmtAttr
    SQLSetConnectAttr
    SQLSetDescField
    SQLSetDescRec
    SQLSetEnvAttr
    SQLSetStmtAttr
    SQLBulkOperations
    SQLSpecialColumns

编译 DLL(使用 mingw (g++))并包含您的 .def 文件,例如:

g++ -shared -o axodbc.dll axodbc.cpp connectionmanager.cpp diagnostics.cpp myresources.res axodbc.def -lodbc32 -lodbccp32 

编译器此时给了我一个错误,即 SQLDisconnect 定义不正确

4

1 回答 1

1

我不在该列表中使用 SQLGetFunctions。您始终可以在驱动程序管理器中启用 ODBC 跟踪,它将显示进行了哪些 ODBC 调用以及结果是什么。

于 2013-07-18T08:03:42.490 回答