• MariaDB + Visual Studio 2017 环境下的 ODBC 入门开发


    参考:

    Easysoft公司提供的ODBC教程

    微软提供的ODBC文档

    环境:

    • Windows 10 x64 1803
    • MariaDB TX 10.2.14 x64
    • MariaDB ODBC Connector 3.0.3 x64
    • Visual Studio 2017 Community 15.6.7

    安装ODBC驱动并配置数据源:

    先安装ODBC驱动。根据自身需求选择32或64位版本。我选择了64位版本。

    打开ODBC数据源管理程序,点击右侧的“添加”按钮,添加用户DSN。如图操作。

    后面按照默认配置,点击Next即可。

    编写ODBC程序:

    1         引入头文件:

    #include <iostream>
    
    #include <windows.h>
    
    #include <sqlext.h>

    2         定义一个检查错误的宏:

    #define ODBC_CHECK(x) 
    
    {
    
        if (!SQL_SUCCEEDED(x))
    
        {
    
            std::cout << "SQL error occurred at line " << __LINE__ << ".";
    
            getchar();
    
            exit(-1);
    
        }
    
    }

    3         ODBC初始化,为ODBC分配环境句柄

    (分配环境句柄:注意,这里使用了新版的ODBC API SQLAllocHandle,而不是SQLAllocEnv

        // SQL Handle of ENVironment
    
        SQLHENV env;
    
        ODBC_CHECK(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env)); // SQLAllocEnv
    
      ODBC_CHECK(SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0));

    4         建立应用程序与ODBC数据源的连接

    (分配连接句柄:注意,这里使用了新版的ODBC API SQLAllocHandle,而不是SQLAllocConnect

        // SQL Handle of DB Connection
    
        SQLHDBC dbc;
    
        SQLCHAR dbcConfOut[256];
    
        ODBC_CHECK(SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc)); // SQLAllocConnect
    
        ODBC_CHECK(SQLSetConnectAttr(dbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0));

    (连接数据源:可以使用SQLConnect,也可以使用SQLDriverConnect;可以手动指定DSN名字,也可以通过弹出窗口来指定)

        // specify manually
    
        ODBC_CHECK(SQLDriverConnect(dbc, NULL, (SQLCHAR *)"DSN=MariaDB;", SQL_NTS,
    
                                    dbcConfOut, sizeof(dbcConfOut), NULL, SQL_DRIVER_COMPLETE)); // SQLConnect
    
        // specify by popup window
    
        //ODBC_CHECK(SQLDriverConnect(dbc, GetDesktopWindow(), NULL, SQL_NTS,
    
        //                            dbcConfOut, sizeof(dbcConfOut), NULL, SQL_DRIVER_COMPLETE)); // SQLConnect

    (显示连接成功的信息)

        std::cout << "Connected!" << std::endl
    
            << "ConnStrIn = " << dbcConfOut << std::endl;
    
     
    
        SQLCHAR dbmsName[256];
    
        ODBC_CHECK(SQLGetInfo(dbc, SQL_DBMS_NAME, (SQLPOINTER)dbmsName, sizeof(dbmsName), NULL));
    
        SQLCHAR dbmsVer[256];
    
        ODBC_CHECK(SQLGetInfo(dbc, SQL_DBMS_VER, (SQLPOINTER)dbmsVer, sizeof(dbmsVer), NULL));
    
        std::cout << "DBMS Name = " << dbmsName << std::endl
    
            << "DBMS Version = " << dbmsVer << std::endl;

    (分配语句句柄:注意,这里使用了新版的ODBC API SQLAllocHandle,而不是SQLAllocStmt

        // SQL Handle of STateMenT
    
        SQLHSTMT stmt;
    
        ODBC_CHECK(SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt)); // SQLAllocStmt

    5         利用SQLExecDirect语句,实现数据库应用程序对数据库的建立、查询、修改、删除等 

    (建立一个循环,一直接收并执行用户的SQL的语句,直到用户退出)

        const int queryLen = 1024;
    
        SQLCHAR query[queryLen];
    
        std::cout << "Please input your SQL query. Type CTRL+Z to quit." << std::endl
    
            << dbmsName << " >";
    
        while (fgets((char*)query, queryLen - 1, stdin))
    
        {
    
            if (query[0] == '
    ')
    
            {
    
                std::cout << dbmsName << " >";
    
                continue;
    
            }
    
     
    
            switch (SQLExecDirect(stmt, query, SQL_NTS))
    
            {
    
                case SQL_SUCCESS_WITH_INFO:
    
                case SQL_SUCCESS:
    
                {
    
                    SQLSMALLINT col;
    
                    SQLNumResultCols(stmt, &col);
    
                    // SELECT
    
                    if (col > 0)
    
                    {   // 2 methods: SQLGetData() and SQLBindCol()
    
                        // SQLGetData() is adopted here
    
     
    
                        char buf[512];
    
                        SQLUSMALLINT colidx;
    
                        // print column names
    
                        for (colidx = 1; colidx <= col; ++colidx)
    
                        {
    
                            SQLColAttribute(stmt, colidx, SQL_DESC_NAME,
    
                                            buf, sizeof(buf), NULL, NULL);
    
                            std::cout << buf << " ";
    
                        }
    
                        std::cout << std::endl;
    
     
    
                        // iterate each row
    
                        unsigned row = 0; // row counter
    
                        while (SQL_SUCCEEDED(SQLFetch(stmt)))
    
                        {
    
                            ++row;
    
                            // iterate each column
    
                            for (colidx = 1; colidx <= col; ++colidx)
    
                            {
    
                                SQLLEN indicator;
    
                                if (SQL_SUCCEEDED(SQLGetData(stmt, colidx, SQL_C_CHAR,
    
                                                             buf, sizeof(buf), &indicator)))
    
                                {
    
                                    if (indicator == SQL_NULL_DATA) strcpy(buf, "NULL");
    
                                    std::cout << buf << " ";
    
                                }
    
                            }
    
                            std::cout << std::endl;
    
                        }
    
                        if (row == 1) { std::cout << "1 row in set." << std::endl; }
    
                        else { std::cout << row << " rows in set." << std::endl; }
    
                    }
    
                    // CREATE, UPDATE, DELETE, etc.
    
                    else
    
                    {
    
                        SQLLEN row;
    
                        ODBC_CHECK(SQLRowCount(stmt, &row));
    
                        if (row == 1) { std::cout << "1 row affected." << std::endl; }
    
                        else { std::cout << row << " rows affected." << std::endl; }
    
                    }
    
                    break;
    
                }
    
                case SQL_ERROR:
    
                {
    
                    std::cout << "Returned SQL_ERROR." << std::endl;
    
                    break;
    
                }
    
                default:
    
                {
    
                    std::cout << "Unknown SQLRETURN." << std::endl;
    
                }
    
            }
    
     
    
            ODBC_CHECK(SQLFreeStmt(stmt, SQL_CLOSE));
    
            std::cout << dbmsName << " >";
    
        }

    6         检索查询结果集 

    7         结束数据库应用程序

        // release resources
    
        ODBC_CHECK(SQLFreeHandle(SQL_HANDLE_STMT, stmt));
    
        ODBC_CHECK(SQLDisconnect(dbc));
    
        ODBC_CHECK(SQLFreeHandle(SQL_HANDLE_DBC, dbc));
    
        ODBC_CHECK(SQLFreeHandle(SQL_HANDLE_ENV, env));
    
        return 0;
  • 相关阅读:
    POJ 1751 Highways (kruskal)
    POJ 2031 Building a Space Station
    UVA 624
    POJ 1502 MPI Maelstrom (Dijkstra)
    POJ 3259 Wormholes(SPFA判负环)
    HZAU 1199 Little Red Riding Hood(水DP)
    HZAU 1205 Sequence Number(最大值前后缀 +双指针 + 二分)
    HZAU 1209 Deadline (hash 贪心 水题不水)
    STL完整版整理
    set集合完整版整理
  • 原文地址:https://www.cnblogs.com/joxon/p/mariadb-vs2017-odbc.html
Copyright © 2020-2023  润新知