使用ODBC进行数据库的操作

时间:2024-03-31 20:34:41

1.配置ODBC

打开C:\Windows\SysWOW64\odbcad32.exe,如下图所示,选择“用户DSN”选项。

使用ODBC进行数据库的操作

点击添加,如下图所示。选择"MySQL ODBC 5.3 Unicode Driver"。

使用ODBC进行数据库的操作

点击完成,如下图所示。

使用ODBC进行数据库的操作

"Data Source Name"数据源名称,自己自定义一个名称,不和已有的重复即可,这里填test,注意:这个在写程序的时候需要用到。

“Description”描述,可不填。

“TCP/IP Server”和Port:这两项是ip和端口,远程的数据库需要填正确的数据端口即可,如果是本地数据库,请按照安装时候的信息填写。

“Named Pipe”:这项不知道是什么。

“User”和Password用户名和密码,远程的直接填自己的用户名和密码。

“Database”,填你想连接到数据库中的那个Schema

完成后可以点击Test试一下,如果正常,测试会返回成功提示。

2.C++封装的代码

Mysql.h

#pragma once
#include <windows.h>
#include <iostream>
#include <sql.h>
#include <sqlext.h>
using namespace std;

class Mysql
{
public:
    /*使用ODBC配置好的Data Source Name,User,Password初始化*/
    Mysql(const char *m_database, const char *m_user, const char *m_password);
    /*执行SQL语句*/
    bool Execute(const char *statement);
    /*输出列*/
    void BindCol(long m_col, void *m_outbuf, long m_bufsize, long *length);
    /*移动光标到下一行*/
    bool Fetch();
    ~Mysql();
private:
    SQLHENV        serverhenv;//环境句柄
    SQLHDBC        serverhdbc;//连接句柄
    SQLHSTMT        serverhstmt;//执行句柄
    bool            connect;//连接数据库标记
};

Mysql.cpp

#include "Mysql.h"

Mysql::Mysql(const char *m_database, const char *m_user, const char *m_password)
{
    SQLRETURN ret = 0;
    connect = false;
    //分配环境句柄
    ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &serverhenv);
    if (ret != 0)
    {
        throw "func SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &serverhenv) error";
    }
    //设置环境属性
    ret = SQLSetEnvAttr(serverhenv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
    if (!SQL_SUCCEEDED(ret))
    {
        throw "func SQLSetEnvAttr(serverhenv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0) error";
    }
    //分配连接句柄
    ret = SQLAllocHandle(SQL_HANDLE_DBC, serverhenv, &serverhdbc);
    if (!SQL_SUCCEEDED(ret))
    {
        throw "func SQLAllocHandle(SQL_HANDLE_DBC, serverhenv, &serverhdbc) error";
    }
    //数据库连接
    ret = SQLConnect(serverhdbc, (SQLCHAR*)m_database, SQL_NTS, (SQLCHAR*)m_user, SQL_NTS, (SQLCHAR*)m_password, SQL_NTS);
    if (!SQL_SUCCEEDED(ret))
    {
        throw "func SQLConnect(serverhdbc, (SQLCHAR*)m_database, SQL_NTS, (SQLCHAR*)m_user, SQL_NTS, (SQLCHAR*)m_password, SQL_NTS) error";
    }
    //分配执行语句句柄
    ret = SQLAllocHandle(SQL_HANDLE_STMT, serverhdbc, &serverhstmt);
    if (!SQL_SUCCEEDED(ret))
    {
        throw "func SQLAllocHandle(SQL_HANDLE_STMT, serverhdbc, &serverhstmt) error";
    }
    connect = true;
}
//执行数据库语句
bool Mysql::Execute(const char *statement)
{
    if (connect == false || statement == NULL)
    {
        return false;
    }
    SQLRETURN ret = 0;
    ret = SQLExecDirect(serverhstmt, (SQLCHAR*)statement, SQL_NTS);
    if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
    {
        return true;
    }
    return false;
}
void Mysql::BindCol(long m_col, void *m_outbuf, long m_bufsize, long *length)
{
    if (connect == false || m_outbuf == NULL || length == NULL)
    {
        return;
    }
    SQLBindCol(serverhstmt, m_col, SQL_C_CHAR, (void*)m_outbuf, m_bufsize, length);
}
bool Mysql::Fetch()
{
    if (connect == false)
    {
        return false;
    }
    if (SQL_NO_DATA != SQLFetch(serverhstmt))
    {
        return true;
    }
    return false;
}

Mysql::~Mysql()
{
    SQLRETURN ret = 0;
    //释放语句句柄
    ret = SQLFreeHandle(SQL_HANDLE_STMT, serverhstmt);
    if (SQL_SUCCESS != ret && SQL_SUCCESS_WITH_INFO != ret)
        cout << "free hstmt error!" << endl;
    //断开数据库连接
    ret = SQLDisconnect(serverhdbc);
    if (SQL_SUCCESS != ret&&SQL_SUCCESS_WITH_INFO != ret)
        cout << "disconnected error!" << endl;
    //释放连接句柄
    ret = SQLFreeHandle(SQL_HANDLE_DBC, serverhdbc);
    if (SQL_SUCCESS != ret&&SQL_SUCCESS_WITH_INFO != ret)
        cout << "free hdbc error!" << endl;
    //释放环境句柄句柄
    ret = SQLFreeHandle(SQL_HANDLE_ENV, serverhenv);
    if (SQL_SUCCESS != ret&&SQL_SUCCESS_WITH_INFO != ret)
        cout << "free henv error!" << endl;
}