开发者空间安装ODBC驱动,编写应用程序操作GaussDB数据库

一、概述

1.1 背景介绍

公司业务项目中大量商业数据需要高效管理,并进行读取,修改,写入,删除等操作,离不开数据库系统对业务数据的支持。故在企业开发商业软件时,代码绕不开与数据库的关联。为了解决该问题,各数据库厂商提供了软件研发中针对不同开发语言的驱动。例如很多使用C语言研发的基础软件在使用不同的数据库时,各数据库都有对应的C语言驱动API,像Oracle的OCI,PostgreSQL的Libpq,MySQL的Connectore C等。但由于不同数据库厂商提供的专项C语言开发接口都不同,导致在商业软件开发时面对不同Database的驱动接口,需要开发对应数据库的接口代码,故增加了开发复杂性和可维护性,且对数据库的可移植性构成巨大挑战。所以数据库厂商为解决跨数据库链接问题,提供了早期的嵌入式SQL API。但这些驱动库存在不规范导致的兼容性问题。为改善访问不同数据库,缺乏基于C语言的统一编程接口,1991年MicroSoft提出开放式数据库互连(Open-DataBase-Connectivity)。在后面发展历程中,ODBC基于SAG的SQL CAE方案,具有强大的功能和灵活性,其包含标准的错误代码集,连接和登录数据库方法及数据类型表示等关键特性。故ODBC解决方案逐渐成为Windows, MacOS, Linux平台上的标准接口,并推动该方面的开放性和标准化。

通过实际操作,让大家深入了解如何利用云主机开发C程序应用,并操作和部署GaussDB数据库。在这个过程中,大家将学习到从驱动安装、环境编码、函数应用到GaussDB数据库部署以及与 ODBC API集成等一系列关键步骤,从而掌握 ODBC连接数据库的基本使用方法,体验其在应用开发中的优势。

1.2 适用对象

  • 企业
  • 个人开发者
  • 高校学生

1.3 案例时间

本案例总时长预计60分钟。

1.4 案例流程

1.5 资源总览

本案例预计花费0.82元。

资源名称规格单价(元)时长(分钟)
弹性公网IP按流量计费 20Mbit/s0.02元/h + 0.8元/GB60
云数据库 GaussDB单副本集中式版 | 4 vCPUs | 16G | HCE OS 64bit (200GB)免费试用60
华为开发者空间 - 云开发环境鲲鹏通用计算增强型 kc1 | 2vCPUs | 4G | HCE免费60

最新案例动态,请查阅《基于开发者空间编写ODBC应用程序操作GaussDB数据库》,小伙伴快来华为开发者空间 -云开发环境实操吧!

二、开发者空间配置

2.1 远程开发环境配置

根据案例《开发者空间 - 云开发环境使用指导》,请查看下面链接,配置云开发环境,并在本地连接登录到云开发环境。

开发者空间 - 云开发环境使用指导

2.2 免费领取GaussDB数据库

免费领取GaussDB在线试用版(2025年 06月 21日 - 2025年 12月 31日)。链接如下:
领取GaussDB
有1000个名额,数量有限,速度为王。

领取后,进入到华为开发者空间,按提示步骤创建GuassDB数据库实例,如下:

给GaussDB实例绑定弹性公网IP以便在云开发环境中访问,参考:绑定EIP弹性公网

注意:绑定弹性公网EIP后,要修改GaussDB安全组,放开常用的监听端口(比如8000)。实操结束后如果短时间内不再试用弹性公网IP,请解绑并释放弹性公网IP实例,避免持续扣费!

安全组设置指导如下GaussDB安全组说明文档

在GaussDb实例基本信息页面查看绑定的弹性公网IP,并记住此公网IP备用。

2.3 云开发环境测试数据库连通性

连接登录到云开发环境,ping GaussDB绑定的弹性公网IP:

如果禁止ping,可以使用下面的命令查看端口是否通,没有返回表示通的

echo > /dev/tcp/GaussDB绑定的弹性公网IP/8000

此处echo > /dev/tcp/139.159.195.74/8000并不影响生态版GaussDB的使用。

三、安装ODBC驱动

3.1 安装unixODBC

ODBC作为面向C语言连接与操作数据库的统一程序接口规范标准,应用程序通过ODBC提供的应用程序接口与数据库进行交互,增强了应用程序的可移植性、扩展性和可维护性。而unixODBC即为Linux平台ODBC驱动管理器。

连接登录云开发环境,查看是否已安装过ODBC驱动管理器。

sudo yum list unixODBC

当前Available Packages显示unixODBC.aarch64,说明ODBC驱动管理器并没有安装,如果已安装,则显示在Installed Packages栏下面。

安装命令如下:

sudo yum install -y unixODBC

如上图所示,即表示ODBC驱动管理器安装成功。

输入如下命令,安装unixODBC头文件及开发环境。

sudo yum install -y unixODBC-devel

3.2 下载GaussDB-ODBC驱动

本案例中,使用GaussDB的ODBC驱动程序源码,完成代码编译构建和部署的功能。
下载GaussDB驱动包。

wget https://dbs-download.obs.cn-north-1.myhuaweicloud.com/GaussDB/1750076538851/GaussDB_driver.zip
解压ODBC驱动。 ```bash unzip GaussDB_driver.zip cd GaussDB_driver/Centralized/Hce2.0_arm_64/ tar -zxvf GaussDB-Kernel_505.2.1_Hce_64bit_Odbc.tar.gz ```

解压gsql工具。

cd GaussDB_driver/Centralized/Hce2.0_arm_64/
tar -zxvf GaussDB-Kernel_505.2.1_Hce_64bit_Gsql.tar.gz

3.3 适配ODBC驱动管理器unixODBC

根据3.1章节所示,云开发环境已经安装了驱动管理器unixODBC。其主要分为三大块:odbcinst、odbc_config和isql。

3.3.1 odbcinst

输入:

odbcinst --version
```bash odbcinst –h ```

用如下命令查看当前系统驱动管理器的配置文件的位置。

odbcinst -j

注意:

配置管理器的数据源和驱动文件位置,在当前环境中设置环境变量(或者在当前用户目录下的.bash_profile文件里添加如下环境变量并使其生效)。

ODBCSYSINI + ODBCINSTIN = odbcinst.ini文件路径 + odbcinst.ini文件名

ODBCSYSINI + ODBCINI = odbc.ini文件路径 + odbc.ini文件名
设置环境变量:

sudo vim ~/.bashrc

在bashrc文件中追加以下内容:

export ODBCSYSINI=/etc
export ODBCINSTINI=odbcinst.ini

if [ -d "$HOME/GaussDB_driver/Centralized/Hce2.0_arm_64/" ]; then
    cd "$HOME/GaussDB_driver/Centralized/Hce2.0_arm_64/" && source gsql_env.sh
    cd - > /dev/null
fi

刷新配置文件:

source ~/.bashrc

通常不添加export ODBCINI=odbc.ini,因为设置了ODBCINI会影响当前用户的odbc.ini同系统odbc.ini处于相同的文件。正常环境应该要把系统的odbc.ini与用户的odbc.ini区分。

修改ODBC驱动文件

sudo vim /etc/odbcinst.ini

在“/etc/odbcinst.ini”文件中追加以下内容。

[GaussDB]
Description     = ODBC for GaussDB
Driver          = /home/developer/GaussDB_driver/Centralized/Hce2.0_arm_64/odbc/lib/gsqlodbcw.so
Setup           = /home/developer/GaussDB_driver/Centralized/Hce2.0_arm_64/odbc/lib/gsqlodbcw.so
Driver64        = /home/developer/GaussDB_driver/Centralized/Hce2.0_arm_64/odbc/lib/gsqlodbcw.so
Setup64         = /home/developer/GaussDB_driver/Centralized/Hce2.0_arm_64/odbc/lib/gsqlodbcw.so

配置数据源文件:

 sudo vim /etc/odbc.ini

在“/etc/odbc.ini”文件中追加以下内容,以个人实际的数据库信息为准。。

[gauss_dsn]
Driver=GaussDB
Servername=GaussDB绑定弹性公网IP
Port=8000
Database=postgres
Username=root
Password=数据库用户密码

3.3.2 odbc_config

输入如下命令,可看到odbc_config所有参数。

odbc_config -h
odbc_config --prefix

参数prefix输出odbc的安装目录。

odbc_config --exec-prefix

参数exec-prefix输出odbc的安装目录。

odbc_config --include-prefix

参数include-prefix输出ODBC头文件目录。

odbc_config --lib-prefix

参数lib-prefix输出ODBC依赖库文件目录。

odbc_config --bin-prefix

参数bin-prefix输出ODBC可执行bin文件目录。

odbc_config --version

参数version输出当前unixODBC驱动管理器版本号。

odbc_config --libs

参数libs输出ODBC程序动态库(*.so文件)编译参数。

odbc_config --static-libs

参数static-libs输出ODBC程序静态库(*.a文件)目录。

odbc_config --libtool-libs

参数libtool-libs输出ODBC程序映射库文件(*.la静态与动态库映射文件)目录。

odbc_config --cflags

参数cflags输出C编译器gcc的编译参数。

odbc_config --odbcversion
odbc_config --longodbcversion

参数输出对应的版本号。

odbc_config --odbcini

参数odbcini输出odbc.ini配置文件所在位置。

odbc_config --odbcinstini

参数odbcinstini输出odbcinst.ini配置文件所在位置。

odbc_config --header

参数header输出ODBC编译头文件内容。

odbc_config --ulen

参数ulen输出ODBC中SQLULEN的长度数据。

3.3.3 isql

isql --version
isql -h

输入如下命令,使用isql工具通过ODBC直接登录GaussDB数据库。

isql -v gauss_dsn

注意:

此处的gauss_dsn是对应odbc.ini里的**[gauss_dsn],而odbc.ini配置文件里的Driver参数对应odbcinst.ini里的[GaussDB]**标签。

通过简单的SQL操作,如下:

create table test (id int, name varchar);
select * from test;
insert into test values(1, 'test');
insert into test values(100, 'GaussDB');
select * from test;

然后用GaussDB客户端工具gsql登录检查isql中的数据写入是否在Gauss数据库中已经存储。

gsql -h 弹性公网IP -U root -W 用户密码 -p 8000 -d postgres
\d
select * from test;

3.4 业务应用C程序研发中ODBC代码用例

下面是C语言程序开发中,调用ODBC API与GaussDB数据库互连操作,包含建表(create table),插入(insert),修改(update),删除(delete)等基础操作。例如代码文件odbc-test.c。

#include <stdlib.h>
#include <stdio.h>
#include <sqlext.h>
#ifdef WIN32
#include <windows.h>
#endif

SQLHENV       V_OD_Env;
SQLHSTMT      V_OD_hstmt;
SQLHDBC       V_OD_hdbc;
char          typename[100];
SQLINTEGER    value = 100;
SQLINTEGER    V_OD_erg, V_OD_buffer, V_OD_err, V_OD_id;

int main(int argc,char *argv[])
{
    // 1. 申请环境句柄
    V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &V_OD_Env);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
        printf("Error AllocHandle\n");
        exit(0);
    }

    // 2. 设置环境属性(版本信息)
    SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);

    // 3. 申请连接句柄
    V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
        SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
        exit(0);
    }

    // 4. 设置连接属性
    SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0);

    // 5. 连接数据源,这里的“userName”与“password”分别表示连接数据库的用户名和用户密码,请根据实际情况修改。
    // 如果odbc.ini文件中已经配置了用户名密码,那么这里可以留空("");但是不建议这么做,因为一旦odbc.ini权限管理不善,将导致数据库用户密码泄露。
    V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "DSN", SQL_NTS, (SQLCHAR*) "", SQL_NTS,  (SQLCHAR*) "", SQL_NTS);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
        printf("Error SQLConnect %d\n", V_OD_erg);
        SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
        exit(0);
    }
    printf("Connected !\n");

    // 6. 设置语句属性
    SQLSetStmtAttr(V_OD_hstmt, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER *)3, 0);

    // 7. 申请语句句柄
    SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);

    // 8. 直接执行SQL语句
    SQLExecDirect(V_OD_hstmt, "drop table IF EXISTS customer_t1", SQL_NTS);
    SQLExecDirect(V_OD_hstmt, "CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));", SQL_NTS);
    SQLExecDirect(V_OD_hstmt, "insert into customer_t1 values(25,'LiLei')", SQL_NTS);

    // 9. 准备执行
    SQLPrepare(V_OD_hstmt, "insert into customer_t1 values(?)", SQL_NTS);

    // 10. 绑定参数
SQLBindParameter(V_OD_hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &value, 0, NULL);

    // 11. 执行准备好的语句
    SQLExecute(V_OD_hstmt);
    SQLExecDirect(V_OD_hstmt, "select id from testtable", SQL_NTS);

    // 12. 获取结果集某一列的属性
    SQLColAttribute(V_OD_hstmt, 1, SQL_DESC_TYPE, typename, 100, NULL, NULL);
    printf("SQLColAtrribute %s\n", typename);

    // 13. 绑定结果集
    SQLBindCol(V_OD_hstmt, 1, SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer, 150, (SQLLEN *)&V_OD_err);

    // 14. 通过SQLFetch取结果集中数据
    V_OD_erg=SQLFetch(V_OD_hstmt);

    // 15. 通过SQLGetData获取并返回数据
    while(V_OD_erg != SQL_NO_DATA)
    {
        SQLGetData(V_OD_hstmt, 1, SQL_C_SLONG, (SQLPOINTER)&V_OD_id, 0, NULL);
        printf("SQLGetData ----ID = %d\n", V_OD_id);
        V_OD_erg=SQLFetch(V_OD_hstmt);
    };
    printf("Done !\n");

    // 16. 断开数据源连接并释放句柄资源
    SQLFreeHandle(SQL_HANDLE_STMT, V_OD_hstmt);
    SQLDisconnect(V_OD_hdbc);
    SQLFreeHandle(SQL_HANDLE_DBC, V_OD_hdbc);i
    SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
    return 0;
}

该程序用例,需要修改程序中的DSN,对应odbc.ini里的[gauss_dsn]。

V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "DSN", SQL_NTS, (SQLCHAR*) "", SQL_NTS,  (SQLCHAR*) "", SQL_NTS);

caa1bf46c0e1d1befb6e397cb3672925.png

3.5 编译和测试方法

例如上面程序文件名为odbc-test.c。

在云主机上编译该文件生成可执行文件,命令如下:

sudo gcc -o odbc-test odbc-test.c -L /home/developer/GaussDB_driver/Centralized/Hce2.0_arm_64/odbc/lib -lodbc

则会生成odbc-test可执行文件。

参数说明:

参数说明
-L指向程序odbc-test.c要依赖的动态库路径
-lodbc表示gcc要依赖的动态库是odbc驱动库

创建库路径配置文件。

echo '/home/developer/GaussDB_driver/Centralized/Hce2.0_arm_64/lib' | sudo tee /etc/ld.so.conf.d/gaussdb-lib.conf
echo '/home/developer/GaussDB_driver/Centralized/Hce2.0_arm_64/odbc/lib' | sudo tee -a /etc/ld.so.conf.d/gaussdb-lib.conf

更新系统库缓存。

sudo ldconfig

执行程序,如下:

sudo ./odbc-test

用GaussDB客户端工具gsql登录数据库:

gsql -h 弹性公网IP -U root -W 用户密码 -p 8000 -d postgres
\d
select * from customer_t1;

经过gsql客户端登录数据库,可以看到后台数据库中已经存储了应用程序C代码中写入和修改的表数据。平时企业业务系统在开发中,如果用C程序编程去处理商业数据,则可借鉴3.4章节的C程序代码。

最经典的业务场景就是银行存钱取钱,业务系统程序先从银行数据库把对应用户的存款数额读取出来,等用户取完钱,把读取的数据(存款数额)进行update操作后为取款后剩余的钱数,再回写入银行数据库系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值