基于ODBC的应用开发

本文介绍C/C++语言如何通过MySQL的ODBC驱动进行应用程序开发。

前提条件

操作步骤

  1. 下载并安装MySQL ODBC驱动。下载地址:ODBC

  2. 执行以下命令,安装数据库连接组件unixODBC。以Linux操作系统为例。

    yum install unixODBC-devel
  3. 修改ODBC配置文件odbcinst.ini中的MySQL依赖。

    [MySQL]
    Description	= ODBC for MySQL
    Driver		= /usr/lib/libmyodbc8a.so
    Setup		= /usr/lib/libmyodbc8w.so
    Driver64	= /usr/lib64/libmyodbc8a.so
    Setup64		= /usr/lib64/libmyodbc8w.so
    FileUsage	= 1

    配置项说明如下:

    配置项

    说明

    Description

    MySQL依赖描述,可自定义。

    Driver

    ODBC驱动程序。请填写ODBC驱动程序实际存放路径。

    Setup

    ODBC驱动安装程序。请填写ODBC驱动安装程序实际存放路径。

    Driver64

    ODBC 64位驱动程序。请填写ODBC 64位驱动程序实际存放路径。

    Setup64

    ODBC 64位驱动安装程序。请填写ODBC 64位驱动安装程序实际存放路径。

    FileUsage

    默认值为1。不修改。

  4. 配置连接参数。

    ret = SQLDriverConnect(dbc, NULL, (SQLCHAR*)"DRIVER={MySQL};SERVER=ld-uf6k8yqb741t3****-proxy-sql-lindorm-public.lindorm.rds.aliyuncs.com;PORT=33060;DATABASE=default;USER=user;PASSWORD=test", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);

    参数说明

    参数

    说明

    DRIVER

    MySQL驱动名。根据odbcinst.ini文件中的MySQL依赖名称进行修改。

    SERVER

    Lindorm宽表引擎的MySQL兼容地址。如何获取,请参见查看连接地址

    重要
    • 如果应用部署在ECS实例,建议您通过专有网络访问Lindorm实例,可获得更高的安全性和更低的网络延迟。

    • 如果应用部署在本地,在通过公网连接Lindorm实例前,需在控制台开通公网地址。开通方式:在控制台选择数据库连接 > 宽表引擎,在宽表引擎页签单击开通公网地址

    • 通过专有网络访问Lindorm实例,SERVER请填写MySQL兼容地址对应的专有网络地址。通过公网访问Lindorm实例,SERVER请填写MySQL兼容地址对应的公网地址。

    PORT

    Lindorm宽表引擎MySQL协议的端口,固定为33060。

    DATABASE

    需要连接的数据库名称。默认连接default数据库。

    USER

    如果您忘记用户密码,可以通过Lindorm宽表引擎的集群管理系统修改密码。具体操作,请参见修改用户密码

    PASSWORD

  5. 创建连接,通过SQL语法使用Lindorm宽表引擎。以查询所有数据库为例。

    if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
            printf("连接成功\n");
    
            // 执行查询
            SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
            SQLExecDirect(stmt, (SQLCHAR*)"show databases", SQL_NTS);
    
            // 获取查询结果
            SQLCHAR result[50];
            while (SQLFetch(stmt) == SQL_SUCCESS) {
                SQLGetData(stmt, 1, SQL_C_CHAR, result, sizeof(result), NULL);
                printf("database: %s\n", result);
            } 
            // 释放资源
            SQLFreeHandle(SQL_HANDLE_STMT, stmt);
            SQLDisconnect(dbc);
        }
        else {
            SQLCHAR sqlState[6];
            SQLCHAR msg[SQL_MAX_MESSAGE_LENGTH];
            SQLINTEGER nativeError;
            SQLSMALLINT actualMsgLen;
    
            SQLGetDiagRec(SQL_HANDLE_DBC, dbc, 1, sqlState, &nativeError, msg, sizeof(msg), &actualMsgLen);
            printf("连接失败: %s\n", msg);
        }
    
        // 释放资源
        SQLFreeHandle(SQL_HANDLE_DBC, dbc);
        SQLFreeHandle(SQL_HANDLE_ENV, env);
    
        return 0;

完整示例

完整示例代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>

int main() {
    // 定义连接信息
    SQLHENV env;
    SQLHDBC dbc;
    SQLHSTMT stmt;
    SQLRETURN ret;

    // 初始化环境
    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
    SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);

    // 建立连接
    SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
    SQLSetConnectAttr(dbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, SQL_IS_INTEGER);
    //lindorm_mysql_url为lindorm宽表引擎MySQL协议的连接地址,database为需要连接的数据库,lindorm_user为用户名,lindorm_password为用户密码 
    ret = SQLDriverConnect(dbc, NULL, (SQLCHAR*)"DRIVER={MySQL};SERVER=ld-uf6k8yqb741t3****-proxy-sql-lindorm-public.lindorm.rds.aliyuncs.com;PORT=33060;DATABASE=default;USER=user;PASSWORD=test", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);

    if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
        printf("连接成功\n");

        // 执行查询
        SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
        SQLExecDirect(stmt, (SQLCHAR*)"show databases", SQL_NTS);

        // 获取查询结果
        SQLCHAR result[50];
        while (SQLFetch(stmt) == SQL_SUCCESS) {
            SQLGetData(stmt, 1, SQL_C_CHAR, result, sizeof(result), NULL);
            printf("database: %s\n", result);
        } 
        // 释放资源
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
        SQLDisconnect(dbc);
    }
    else {
        SQLCHAR sqlState[6];
        SQLCHAR msg[SQL_MAX_MESSAGE_LENGTH];
        SQLINTEGER nativeError;
        SQLSMALLINT actualMsgLen;

        SQLGetDiagRec(SQL_HANDLE_DBC, dbc, 1, sqlState, &nativeError, msg, sizeof(msg), &actualMsgLen);
        printf("连接失败: %s\n", msg);
    }

    // 释放资源
    SQLFreeHandle(SQL_HANDLE_DBC, dbc);
    SQLFreeHandle(SQL_HANDLE_ENV, env);

    return 0;
}

如果当前实例仅有default一个数据库,执行成功后将返回如下结果:

连接成功
database: default
database: information_schema