第1关:ODBC程序设计
第1关:ODBC程序设计#
任务描述#
本关任务:使用 ODBC 查询表中数据。
相关知识#
为了完成本关任务,你需要掌握:
1.ODBC 的主要功能;
2.ODBC 接口主要函数;
3.ODBC 应用程序开发实例。
ODBC主要功能#
ODBC(Open Database Connectivity,开放式数据库连接)是由 Microsoft 开发和定义的一种访问数据库的应用程序接口,其定义了访问数据库API的一组规范,这些API独立于形色各异的数据库系统和编程语言。因此,ODBC 支持不同编程语言,同时也支持不同的数据库系统。借助 ODBC 接口,应用程序能够使用相同的源代码和各种各样的数据库交互。这使得应用程序开发人员不需要考虑各类数据库系统的构造细节,只要使用相应 ODBC 驱动程序,即可通过将 SQL 语句发送到目标数据库中,可以访问和操作各类数据库中的数据。
也就是说,一个基于 ODBC 的应用程序,对数据库的操作不依赖任何数据库系统,所有的数据库操作由对应数据库的ODBC驱动程序完成。不论是 SQL Server、Access、Oracle,还是 DM 数据库,均可借助 ODBC API 进行访问。ODBC 体系结构如下图所示,ODBC 驱动程序管理器用于管理各种 ODBC 驱动程序,基于 ODBC 开发的应用程序通过 ODBC 驱动程序管理器,调用针对不同数据库的驱动程序,进行数据对象的维护、数据的查询和修改等操作。
DM8 数据库提供的 DM ODBC 3.0 接口遵照 Microsoft ODBC 3.0 规范设计与开发,实现了 ODBC 应用程序与 DM 的互连。其由 C 语言编写,其底层调用 DM DCI 接口实现。因此,应用程序开发人员可基于 ODBC 接口规范,使用 DM ODBC 驱动访问和操作 DM8 数据库。
ODBC接口主要函数#
由于 DM ODBC 遵照 Microsoft ODBC 3.0 规范设计与开发,因此 DM ODBC 接口提供的函数与标准 ODBC 一致。由于 DM ODBC 接口函数较多,下图仅列出了 DM ODBC 接口的主要函数。
ODBC应用程序开发实例#
DM ODBC应用程序开发总体流程#
DM ODBC 为程序员提供了基于 ODBC 接口开发应用程序的手段,程序员使用 DM ODBC 开发应用程序时总体流程如下图所示。首先,安装 DM ODBC 驱动;其次,配置 ODBC 数据源;最后,基于 DM ODBC 编程规范,编写代码访问和操作 DM8 数据库。
1)安装 DM ODBC 驱动程序;
示例:
1.将附件 unixODBC-2.3.0.tar.gz 上传到 /usr/local 下,执行安装。
[root@localhost local]# tar -xzvf unixODBC-2.3.0.tar.gz
[root@localhost unixODBC-2.3.0]# cd unixODBC-2.3.0
[root@localhost unixODBC-2.3.0]# ./configure --enable-gui=no
[root@localhost unixODBC-2.3.0]# make
[root@localhost unixODBC-2.3.0]# make install
2.查看操作系统上查看 ODBC 版本
[dmdba@localhost]# odbc_config --version
2.3.0
3.查看 ODBC 配置文件存放的位置
[root@localhost etc]# odbc_config --odbcini
/etc/odbc.ini
[root@localhost etc]# odbc_config --odbcinstini
/etc/odbcinst.ini
4.修改odbc.ini文件
[dmdba@localhost]# vi /etc/odbc.ini
[dm]
Description = DM ODBC DSN
Driver = DM7 ODBC DRIVER
SERVER = localhost
UID = SYSDBA
PWD = SYSDBA
TCP_PORT = 5236
5.修改odbcinst.ini文件
[dmdba@localhost]# vi /etc/odbcinst.ini
[DM7 ODBC DRIVER]
Description = ODBC DRIVER FOR DM7
Driver = /opt/dmdbms/bin/libdodbc.so
6.测试连接
[root@localhost]# isql dm SYSDBA SYSDBA
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
出现上述“Connected”就代表安装成功。
2)配置 DM ODBC 数据源;
3)编写 DM ODBC 代码。
DM ODBC代码编写流程#
DM ODBC 数据源配置成功后,即可编写代码访问和操作数据库。遵循 ODBC 编程规范,基于 DM ODBC 接口编写代码访问和操作数据库大致流程如下图所示。
首先,创建连接环境和连接数据库。主要通过调用相关函数分配环境句柄、设置环境属性、分配连接句柄和建立数据库连接等过程。
其次,访问和操作数据库。主要通过建立的连接来分配语句句柄、执行SQL语句等操作,该过程是操作数据库的主体部分,与数据库的所有交互均在该过程完成。
最后,断开连接和释放连接资源。数据库操作完成后,程序需关闭数据库连接,并释放连接资源。
DM ODBC代码编写实例#
【例1】 基于 DM ODBC 编程接口,利用已配置的 DM ODBC 数据源 DM,编写程序,实现获取数据源 DM 对应数据库中 DMHR.EMPLOYEE 表的数据,包括职员 ID、姓名、手机号码等信息。
在 Visual Studio Code 集成开发环境中,创建一个项目,并为项目添加一个 .cpp 源代码文件;然后添加依赖文件“dodbc.so”和达梦数据库安装目录下的 bin 和 include 两个依赖目录;接着基于 DM ODBC 接口编写代码。
1)创建连接环境和连接数据库
应用程序与 DM 数据库进行通讯,需要和数据库建立连接。①调用函数 SQLAllocHandle 申请环境、连接句柄;②调用函数 SQLSetEnvAttr 设置环境句柄属性;③调用函数 SQLSetConnectAttr 设置连接句柄属性;⑤调用连接函数 SQLConnect、SQLDriverConnect 或 SQLBrowseConnect 连接数据源。
2)访问和操作数据库
与 ODBC 数据源建立连接后,即可通过 ODBC 函数访问和操作数据。调用 SQLAllocHandle 申请语句句柄,通过该句柄执行 SQL 语句;调用函数 SQLPrepare 对 SQL 语句和操作进行准备;调用 SQLDescribeCol、SQLDescribeParam 等函数取得相关的描述信息,依据描述信息调用 SQLBindCol、SQLBindParam 等函数绑定相关的列和参数;调用 SQLExecute 执行 SQL 语句,实现相关的 SQL 操作。应用程序也可以调用 SQLExecDirect 直接执行 SQL 语句进行相关的 SQL 操作。
3)断开数据连接和释放连接资源
数据库操作完成后,程序需关闭数据库连接,并释放连接资源。如果要终止客户程序与服务器之间的连接,客户程序应当完成以下的几个操作:
(1)调用 SQLFreeHandle 释放语句句柄,关闭所有打开的游标,释放相关的语句句柄资源(在非自动提交模式下,需事先提交当前的事务);
(2)调用函数 SQLDisconnect 关闭所有的连接;
(3)调用 SQLFreeHandle 释放连接句柄及其相关的资源;
(4)调用 SQLFreeHandle 释放环境句柄及其相关的资源。
例 1 代码如下所示,该代码可用于查询 dmhr.employee 表中所有职工姓名、id 和电话号码。
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
/* 检测返回代码是否为成功标志,当为成功标志返回 TRUE,否则返回 FALSE */
#define RC_SUCCESSFUL(rc) ((rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO)
/* 检测返回代码是否为失败标志,当为失败标志返回 TRUE,否则返回 FALSE */
#define RC_NOTSUCCESSFUL(rc) (!(RC_SUCCESSFUL(rc)))
HENV henv; /* 环境句柄 */
HDBC hdbc; /* 连接句柄 */
HSTMT hsmt; /* 语句句柄 */
SQLRETURN sret;/* 返回代码 */
char szpersonid[11]; /*人员编号*/
SQLLEN cbpersonid=0;
char szname[51]; /*人员姓名*/
SQLLEN cbname=0;
char szphone[26]; /*联系电话*/
SQLLEN cbphone=0;
void main(void)
{
/* 申请一个环境句柄 */
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
if(henv == NULL){
printf("ODBC 环境句柄分配失败");
return;
}
/* 设置环境句柄的 ODBC 版本 */
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
/* 申请一个连接句柄 */
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
if(hdbc == NULL){
printf("ODBC 连接句柄分配失败");
return;
}
sret=SQLConnect(hdbc, (SQLCHAR *)"DM", SQL_NTS, (SQLCHAR *)"DMHR", SQL_NTS, (SQLCHAR *)"dameng123", SQL_NTS);
if(sret == SQL_SUCCESS||sret==SQL_SUCCESS_WITH_INFO){
/* 申请一个语句句柄 */
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hsmt);
/* 立即执行查询人员信息表的语句 */
SQLExecDirect(hsmt, (SQLCHAR *)"SELECT employee_id, employee_name, phone_num FROM dmhr.employee;", SQL_NTS);
/* 绑定数据缓冲区 */
SQLBindCol(hsmt, 1, SQL_C_CHAR, szpersonid, sizeof(szpersonid), &cbpersonid);
SQLBindCol(hsmt, 2, SQL_C_CHAR, szname, sizeof(szname), &cbname);
SQLBindCol(hsmt, 3, SQL_C_CHAR, szphone, sizeof(sazphone), &cbphone);
/* 取得数据并且打印数据 */
printf("人员编号 人员姓名 联系电话\n");
for (;;) {
sret = SQLFetchScroll(hsmt, SQL_FETCH_NEXT, 0);
if (sret == SQL_NO_DATA_FOUND)
break;
printf("%s %s %s\n", szpersonid, szname, szphone);
}
}
else{
printf("连接失败\n");
}
/* 关闭游标,终止语句执行 */
SQLCloseCursor(hsmt);
/* 释放语句句柄 */
SQLFreeHandle(SQL_HANDLE_STMT, hsmt);
/* 断开与数据源之间的连接 */
SQLDisconnect(hdbc);
/* 释放连接句柄 */
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
/* 释放环境句柄*/
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
其中 DMHR 为用户名,dameng123 为密码。
编程要求#
使用右侧 VS CODE 编写 ODBC 程序,查询 test.tb_class 表中所有数据。
登录用户名为:SYSDBA;密码:SYSDBA。
操作步骤:
1.打开 VS CODE,在 HELLOWORLD 项目下方新建 test.cpp 文件,并在该文件中实现 ODBC 程序需求;
2.编辑 HELLOWORLD 项目下的 task.json 文件,按下图所示添加依赖文件dodbc.so。
4.选中 test.c 文件,按下“Ctrl+Shift+B”,编译 test.cpp 文件;
5.点击测评。
test.tb_class 表字段信息:
字段名 | 字段类型 |
---|---|
id | int |
name | varchar(25) |
测试说明#
平台会对你编写的代码进行测试。
开始你的任务吧,祝你成功!
代码参考:#
- 打开 VS CODE,编辑 HELLOWORLD 项目下的 task.json 文件,加上代码:
“-dodbc”,
- 在 HELLOWORLD 项目下方新建 test.cpp 文件,复制以下代码:
(点击右侧的 “工具栏”->“复制粘贴” 即可粘贴进去了)
- 选中 test.c 文件,按下“Ctrl+Shift+B”,编译 test.cpp 文件;
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
/* 检测返回代码是否为成功标志,当为成功标志返回 TRUE,否则返回 FALSE */
#define RC_SUCCESSFUL(rc) ((rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO)
/* 检测返回代码是否为失败标志,当为失败标志返回 TRUE,否则返回 FALSE */
#define RC_NOTSUCCESSFUL(rc) (!(RC_SUCCESSFUL(rc)))
HENV henv; /* 环境句柄 */
HDBC hdbc; /* 连接句柄 */
HSTMT hsmt; /* 语句句柄 */
SQLRETURN sret;/* 返回代码 */
int szpersonid; /*人员编号*/
SQLLEN cbpersonid=0;
char szname[51]; /*人员姓名*/
SQLLEN cbname=0;
int main(void)
{
/* 申请一个环境句柄 */
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
if(henv == NULL){
printf("ODBC 环境句柄分配失败");
return -1;
}
/* 设置环境句柄的 ODBC 版本 */
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
/* 申请一个连接句柄 */
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
if(hdbc == NULL){
printf("ODBC 连接句柄分配失败");
return -1;
}
sret=SQLConnect(hdbc, (SQLCHAR *)"DM", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS);
if(sret == SQL_SUCCESS||sret==SQL_SUCCESS_WITH_INFO){
/* 申请一个语句句柄 */
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hsmt);
/* 立即执行查询人员信息表的语句 */
SQLExecDirect(hsmt, (SQLCHAR *)"SELECT id, name FROM test.tb_class;", SQL_NTS);
/* 绑定数据缓冲区 */
SQLBindCol(hsmt, 1, SQL_C_CHAR, &szpersonid, sizeof(szpersonid), &cbpersonid);
SQLBindCol(hsmt, 2, SQL_C_CHAR, szname, sizeof(szname), &cbname);
/* 取得数据并且打印数据 */
for (int i = 1;;++i) {
sret = SQLFetchScroll(hsmt, SQL_FETCH_NEXT, 0);
if (sret == SQL_NO_DATA_FOUND)
break;
printf("%d %s\n", i, szname);
}
}
else{
printf("连接失败\n");
}
/* 关闭游标,终止语句执行 */
SQLCloseCursor(hsmt);
/* 释放语句句柄 */
SQLFreeHandle(SQL_HANDLE_STMT, hsmt);
/* 断开与数据源之间的连接 */
SQLDisconnect(hdbc);
/* 释放连接句柄 */
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
/* 释放环境句柄*/
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}
作者:aslwr
出处:https://www.cnblogs.com/aslwr/p/17752427.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
各位可以多多推广哦φ(>ω<*)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)