使用C+;连接到MySQL服务器+; 我试图用Visual C++ 2008快速版上的MySQL ODBC 5.1驱动程序与C++连接到MySQL服务器。

使用C+;连接到MySQL服务器+; 我试图用Visual C++ 2008快速版上的MySQL ODBC 5.1驱动程序与C++连接到MySQL服务器。,c++,mysql,odbc,driver,visual-c++-2008,C++,Mysql,Odbc,Driver,Visual C++ 2008,我遵循MSDN的以下说明: 唯一的区别是我必须将所有的SQLCHAR转换为SQLWCHAR,以匹配函数参数,希望这不会影响连接字符串 每次连接时,我都会得到SQL\u ERROR作为返回值。 所以我假设连接字符串或连接语句有问题 我试过了 DNS=TestConnection;UID=用户;PSW=密码 及 SERVER=localhost;DRIVER={MySQL ODBC 5.1 DRIVER};端口=3306;UID=用户;PSW=密码;数据库=dbo 和其他类似的连接字符串

我遵循MSDN的以下说明:

唯一的区别是我必须将所有的
SQLCHAR
转换为
SQLWCHAR
,以匹配函数参数,希望这不会影响连接字符串

每次连接时,我都会得到
SQL\u ERROR
作为返回值。 所以我假设连接字符串或连接语句有问题

我试过了

DNS=TestConnection;UID=用户;PSW=密码

SERVER=localhost;DRIVER={MySQL ODBC 5.1 DRIVER};端口=3306;UID=用户;PSW=密码;数据库=dbo
和其他类似的连接字符串

名为
TestConnection
的DNS与后一个连接字符串具有相同的信息

该模式是
dbo
,有一个名为
testfire
的表,其列规格如下:

TEST_ID( INT(11), PRIMARY, AUTO INCREMENT)
TEST_STRING( VARCHAR(50) )
TEST_INTEGER( INT(11) )
TEST_FLOAT( FLOAT )
TEST_DATE( DATETIME )
有3行:

  ID    STRING    INT   FLOAT           DATE
------------------------------------------------------
| 1  |  Test 1  |  1  |  0.1  |  2001-01-01 00:00:00 |
| 2  |  Test 2  |  2  |  0.2  |  2002-01-01 00:00:00 |
| 3  |  Test 3  |  3  |  0.3  |  2003-01-01 00:00:00 |
------------------------------------------------------
我尝试使用Excel连接检索数据,主要是为了查看驱动程序是否正常工作。Excel成功检索到数据,没有问题,因此名为TestConnection的DNS有效,凭据也有效

  • 我做错了什么
  • 我应该换什么
  • 是转换到
    MYSQLWCHAR*
    时弄乱了连接字符串吗
  • 是否有一种不同的、也许更好、更有效的方法?(可能除了类封装,这是测试成功后我要做的事情)
哦,而且编译器没有给出任何错误或警告,代码编译并运行时没有任何问题

下面是返回“查询执行错误”的测试代码:

所以。。。这是什么意思? 我怎么能没有许可?
这怎么会产生语法错误,这显然是一个有效的查询?

在Mat的一点帮助下,我能够找出问题所在,但由于他没有以答案的形式给出答案,因此我必须回答,以便有相同问题的人可以共享,并标记为已回答

所以,我的问题是我无法连接到数据库。正如Mat所建议的,我应该使用扩展的错误信息,即
SQLGetDiagRec
,并根据文档修复参数。我花了一点时间来学习
SQLGetDiagRec
函数是如何工作的,但一旦我成功地将
wchar\u t
转换为
char*
时,我就能够看到它产生的错误

连接尝试给了我错误
找不到数据源,并且没有指定默认驱动程序
。这给了我一个线索,表明我要么写了不正确的连接字符串,要么文本字符串被曲解或损坏

做了一些事情让我意识到字符串被误解了,为了修复它,我必须将它变成一个文本字符串。果然,在绳子前面放一个L就解决了这个问题

retcode = SQLDriverConnect(hdbc, 0, 
                           (SQLWCHAR*)L"DSN=TestConnection;SERVER=localhost;UID=user;PWD=password;DRIVER=MySQL Server;", 
                           _countof(L"DSN=TestConnection;SERVER=localhost;UID=user;PWD=password;DRIVER=MySQL Server;"), 
                           OutConnStr, 255, &OutConnStrLen, SQL_DRIVER_COMPLETE);
同时,我学会了如何摆脱提示符,在纠正了最初的问题后,这很容易理解。为窗口句柄指定null,将驱动程序完成设置为
SQL\u driver\u COMPLETE
,并确保在连接字符串中添加所需的所有信息

因此,我在使用
SQLExecDirect
查询时遇到的下一个问题是给出了一个错误,称为
语法错误或访问冲突
。问题显然与连接字符串相同。当然足够了

retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);
工作得很有魅力

以下是完整的、功能齐全的代码:

#include <iostream>
#include <windows.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
#include <string>

using namespace std;

int main(){
    SQLHENV henv;
    SQLHDBC hdbc;
    SQLHSTMT hstmt;
    SQLRETURN retcode;

    SQLWCHAR OutConnStr[255];
    SQLSMALLINT OutConnStrLen;

    // Allocate environment handle
    retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

    // Set the ODBC version environment attribute
    if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
        retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); 

        // Allocate connection handle
        if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
            retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); 

             // Set login timeout to 5 seconds
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
                SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);

                // Connect to data source
                retcode = SQLDriverConnect(
                    hdbc, 
                    0,
                    (SQLWCHAR*)L"DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL Server;", 
                    _countof(L"DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL Server;"),
                    OutConnStr,
                    255, 
                    &OutConnStrLen,
                    SQL_DRIVER_COMPLETE );

                // Allocate statement handle
                if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
                    retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 

                    // Process data
                    retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);

                    if (retcode == SQL_SUCCESS) {
                        SQLINTEGER sTestInt, cbTestStr, cbTestInt, cbTestFloat, iCount = 1;
                        SQLFLOAT dTestFloat;
                        SQLCHAR szTestStr[200];
                        while (TRUE) {
                            retcode = SQLFetch(hstmt);
                            if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {
                                cout<<"An error occurred";
                            }
                            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){

                                SQLGetData(hstmt, 1, SQL_C_CHAR, szTestStr, 200, &cbTestStr);
                                SQLGetData(hstmt, 2, SQL_C_ULONG, &sTestInt, 0, &cbTestInt);
                                SQLGetData(hstmt, 3, SQL_C_DOUBLE, &dTestFloat, 0,&cbTestFloat);

                                /* Print the row of data */
                                cout<<"Row "<<iCount<<":"<<endl;
                                cout<<szTestStr<<endl;
                                cout<<sTestInt<<endl;
                                cout<<dTestFloat<<endl;
                                iCount++;
                            } else {
                                break;
                            }
                        }
                    }else{
                        cout<<"Query execution error."<<endl;
                    }

                    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
                    SQLDisconnect(hdbc);
                }else{ 
                    cout<<"Connection error"<<endl;
                }
                SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
            }
        }
        SQLFreeHandle(SQL_HANDLE_ENV, henv);
    }

        system("pause");
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
int main(){
SQLHENV-henv;
SQLHDBC-hdbc;
SQLHSTMT-hstmt;
SQLRETURN-retcode;
SQLWCHAR OutConnStr[255];
SQLSMALLINT-OutConnStrLen;
//分配环境句柄
retcode=SQLAllocHandle(SQL\u HANDLE\u ENV、SQL\u NULL\u HANDLE和henv);
//设置ODBC版本环境属性
if(retcode==SQL_SUCCESS | | retcode==SQL_SUCCESS_WITH_INFO){
retcode=SQLSetEnvAttr(henv,SQL\u ATTR\u ODBC\u VERSION,(void*)SQL\u OV\u ODBC3,0);
//分配连接句柄
if(retcode==SQL_SUCCESS | | retcode==SQL_SUCCESS_WITH_INFO){
retcode=SQLAllocHandle(SQL\u HANDLE\u DBC、henv和hdbc);
//将登录超时设置为5秒
if(retcode==SQL_SUCCESS | | retcode==SQL_SUCCESS_WITH_INFO){
SQLSetConnectAttr(hdbc,SQL\u登录\u超时,(SQLPOINTER)5,0);
//连接到数据源
retcode=SQLDriverConnect(
hdbc,
0,
(SQLWCHAR*)L“DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL SERVER;”,
_countof(L“DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL SERVER;”),
OutConnStr,
255, 
&奥康斯特伦,
SQL(驱动程序完成);
//分配语句句柄
if(retcode==SQL_SUCCESS | | retcode==SQL_SUCCESS_WITH_INFO){
retcode=SQLAllocHandle(SQL\u HANDLE\u STMT、hdbc和hstmt);
//过程数据
retcode=SQLExecDirect(hstmt,(SQLWCHAR*)L“从dbo.testfire中选择测试字符串、测试整数、测试浮点”,SQL);
if(retcode==SQL\u SUCCESS){
SQLINTEGER-sTestInt、cbTestStr、cbTestInt、cbTestFloat、iCount=1;
SQLFLOAT-dTestFloat;
SQLCHAR-szTestStr[200];
while(TRUE){
retcode=SQLFetch(hstmt);
如果(retcode==SQL|错误| retcode==SQL|成功(带|u信息)
retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);
#include <iostream>
#include <windows.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
#include <string>

using namespace std;

int main(){
    SQLHENV henv;
    SQLHDBC hdbc;
    SQLHSTMT hstmt;
    SQLRETURN retcode;

    SQLWCHAR OutConnStr[255];
    SQLSMALLINT OutConnStrLen;

    // Allocate environment handle
    retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

    // Set the ODBC version environment attribute
    if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
        retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); 

        // Allocate connection handle
        if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
            retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); 

             // Set login timeout to 5 seconds
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
                SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);

                // Connect to data source
                retcode = SQLDriverConnect(
                    hdbc, 
                    0,
                    (SQLWCHAR*)L"DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL Server;", 
                    _countof(L"DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL Server;"),
                    OutConnStr,
                    255, 
                    &OutConnStrLen,
                    SQL_DRIVER_COMPLETE );

                // Allocate statement handle
                if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
                    retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 

                    // Process data
                    retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);

                    if (retcode == SQL_SUCCESS) {
                        SQLINTEGER sTestInt, cbTestStr, cbTestInt, cbTestFloat, iCount = 1;
                        SQLFLOAT dTestFloat;
                        SQLCHAR szTestStr[200];
                        while (TRUE) {
                            retcode = SQLFetch(hstmt);
                            if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {
                                cout<<"An error occurred";
                            }
                            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){

                                SQLGetData(hstmt, 1, SQL_C_CHAR, szTestStr, 200, &cbTestStr);
                                SQLGetData(hstmt, 2, SQL_C_ULONG, &sTestInt, 0, &cbTestInt);
                                SQLGetData(hstmt, 3, SQL_C_DOUBLE, &dTestFloat, 0,&cbTestFloat);

                                /* Print the row of data */
                                cout<<"Row "<<iCount<<":"<<endl;
                                cout<<szTestStr<<endl;
                                cout<<sTestInt<<endl;
                                cout<<dTestFloat<<endl;
                                iCount++;
                            } else {
                                break;
                            }
                        }
                    }else{
                        cout<<"Query execution error."<<endl;
                    }

                    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
                    SQLDisconnect(hdbc);
                }else{ 
                    cout<<"Connection error"<<endl;
                }
                SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
            }
        }
        SQLFreeHandle(SQL_HANDLE_ENV, henv);
    }

        system("pause");
    return 0;
}