数据库编程之ODBC编程

article/2025/9/19 20:26:45

ODBC优点

移植性好
能同时访问不同的数据库
共享多个数据资源

ODBC概述

ODBC产生的原因

由于不同的数据库管理系统的存在,在某个关系数据库管理系统下编写的应用程序就不能在另一个关系数据库管理系统下运行
许多应用程序需要共享多个部门的数据资源,访问不同的关系数据库管理系统

ODBC

是微软公司开放服务体系(Windows Open Services Architecture,WOSA)中有关数据库的一个组成部分
提供了一组访问数据库的应用程序编程接口(Application Programming Interface,API )

ODBC约束力

规范应用开发
规范关系数据库管理系统应用接口

ODBC工作原理概述

ODBC应用系统的体系结构

1.用户应用程序
2.ODBC驱动程序管理器
3.数据库驱动程序
4.数据源
在这里插入图片描述

用户应用程序

ODBC应用程序包括的内容
请求连接数据库
向数据源发送SQL语句
为SQL语句执行结果分配存储空间,定义所读取的数据格式
获取数据库操作结果或处理错误
进行数据处理并向用户提交处理结果
请求事务的提交和回滚操作
断开与数据源的连接

ODBC驱动程序管理器

驱动程序管理器:用来管理各种驱动程序
包含在ODBC32.DLL中
管理应用程序和驱动程序之间的通信
建立、配置或删除数据源,并查看系统当前所安装的数据库ODBC驱动程序
主要功能:
装载ODBC驱动程序
选择和连接正确的驱动程序
管理数据源
检查ODBC调用参数的合法性
记录ODBC函数的调用等

数据库驱动程序

ODBC通过驱动程序来提供应用系统与数据库平台的独立性
ODBC应用程序不能直接存取数据库
其各种操作请求由驱动程序管理器提交给某个关系数据库管理系统的ODBC驱动程序
通过调用驱动程序所支持的函数来存取数据库
数据库的操作结果也通过驱动程序返回给应用程序
如果应用程序要操纵不同的数据库,就要动态地链接到不同的驱动程序上
ODBC驱动程序类型
单束
数据源和应用程序在同一台机器上
驱动程序直接完成对数据文件的I/O操作
驱动程序相当于数据管理器
多束
支持客户机—服务器、客户机—应用服务器/数据库服务器等网络环境下的数据访问
由驱动程序完成数据库访问请求的提交和结果集接收
应用程序使用驱动程序提供的结果集管理接口操纵执行后的结果数据

ODBC数据源管理

数据源:是最终用户需要访问的数据,包含了数据库位置和数据库类型等信息,是一种数据连接的抽象
数据源对最终用户是透明的
ODBC给每个被访问的数据源指定唯一的数据源名(Data Source Name,简称DSN),并映射到所有必要的、用来存取数据的低层软件
在连接中,用数据源名来代表用户名、服务器名、所连接的数据库名等
最终用户无须知道数据库管理系统或其他数据管理软件、网络以及有关ODBC驱动程序的细节
例如,假设某个学校在SQL Server和KingbaseES上创建了两个数据库:学校人事数据库和教学科研数据库。
学校的信息系统要从这两个数据库中存取数据
为了方便地与两个数据库连接,为学校人事数据库创建一个数据源名PERSON,为教学科研数据库创建一个名为EDU的数据源
当要访问每一个数据库时,只要与PERSON和EDU连接即可,不需要记住使用的驱动程序、服务器名称、数据库名

ODBC API 基础

ODBC 应用程序编程接口的一致性

API一致性
包含核心级、扩展1级、扩展2级
语法一致性
包含最低限度SQL语法级、核心SQL语法级、扩展SQL语法级

函数概述

ODBC 3.0 标准提供了76个函数接口
分配和释放环境句柄、连接句柄、语句句柄
连接函数(SQLDriverconnect等)
与信息相关的函数(SQLGetinfo、SQLGetFuction等)
事务处理函数(如SQLEndTran)
执行相关函数(SQLExecdirect、SQLExecute等)
编目函数,ODBC 3.0提供了11个编目函数,如SQLTables、SQLColumn等。应用程序可以通过对编目函数的调用来获取数据字典的信息,如权限、表结构等
ODBC不同版本上的函数和函数使用是有差异的,读者必须注意使用的版本,目前最新的版本是ODBC 3.8

句柄及其属性

句柄是32位整数值,代表一个指针
ODBC 3.0中句柄分类
环境句柄
连接句柄
语句句柄
描述符句柄
应用程序句柄之间的关系
每个ODBC应用程序需要建立一个ODBC环境,分配一个环境句柄,存取数据的全局性背景,如环境状态、当前环境状态诊断、当前在环境上分配的连接句柄等
一个环境句柄可以建立多个连接句柄,每一个连接句柄实现与一个数据源之间的连接
在这里插入图片描述

在一个连接中可以建立多个语句句柄,它不只是一个SQL语句,还包括SQL语句产生的结果集以及相关的信息等
在ODBC 3.0中又提出了描述符句柄的概念,它是描述SQL语句的参数、结果集列的元数据集合

数据类型

ODBC数据类型
SQL数据类型:用于数据源
C数据类型 :用于应用程序的C代码
应用程序可以通过SQLGetTypeInfo来获取不同的驱动程序对于数据类型的支持情况
SQL数据类型和C数据类型之间的转换规则
在这里插入图片描述

ODBC的工作流程

在这里插入图片描述

[例8.11] 将KingbaseES数据库中Student表的数据备份到SQL Server数据库中。

该应用涉及两个不同的关系数据库管理系统中的数据源
使用ODBC来开发应用程序,只要改变应用程序中连接函数(SQLConnect)的参数,就可以连接不同关系数据库管理系统的驱动程序,连接两个数据源

在应用程序运行前,已经在KingbaseES和SQL Server中分别建立了Student关系表

应用程序要执行的操作
在KingbaseES上执行SELECT * FROM Student;
把获取的结果集,通过多次执行INSERT语句插入到SQL Server的Student表中

操作步骤

1.配置数据源
2. 初始化环境
3. 建立连接
4. 分配语句句柄
5. 执行SQL语句
6. 结果集处理
7. 中止处理

配置数据源

配置数据源有两种方法
运行数据源管理工具来进行配置
使用Driver Manager 提供的ConfigDsn函数来增加、修改或删除数据源
在[例8.12]中,采用第一种方法创建数据源。因为要同时用到KingbaseES和SQL Server,所以分别建立两个数据源,将其取名为KingbaseES ODBC和SQL Server
[例8.12] 创建数据源的详细过程

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <Sqltypes.h>
#define SNO_LEN 30
#define NAME_LEN 50
#define DEPART_LEN 100
#define SSEX_LEN 5

创建数据源—第一步:定义句柄和变量

int main()
{	/* Step 1 定义句柄和变量 *//*以king开头的表示的是连接KingbaseES的变量*//*以server开头的表示的是连接SQLServer的变量*/SQLHENV    kinghenv,serverhenv;        /*环境句柄*/SQLHDBC 	 kinghdbc,serverhdbc;         /*连接句柄*/SQLHSTMT kinghstmt,serverhstmt;  	/*语句句柄*/SQLRETURN   ret;SQLCHAR  sName[NAME_LEN],sDepart[DEPART_LEN],sSex[SSEX_LEN],sSno[SNO_LEN];SQLINTEGER   sAge;SQLINTEGER  cbAge=0,cbSno=SQL_NTS,cbSex=SQL_NTS,cbName=SQL_NTS,cbDepart=SQL_NTS;

初始化环境

没有和具体的驱动程序相关联,由Driver Manager来进行控制 ,并配置环境属性
应用程序通过调用连接函数和某个数据源进行连接后,Driver Manager才调用所连的驱动程序中的SQLAllocHandle,来真正分配环境句柄的数据结构
创建数据源—第二步:初始化环境

/* Step 2 初始化环境 */
ret=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE, 			          &kinghenv);
ret=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE, 			          &serverhenv);
ret=SQLSetEnvAttr(kinghenv,SQL_ATTR_ODBC_VERSION, 				        (void*)SQL_OV_ODBC3, 0);
ret=SQLSetEnvAttr(serverhenv,SQL_ATTR_ODBC_VERSION, 			        (void*)SQL_OV_ODBC3, 0);

建立连接

应用程序调用SQLAllocHandle分配连接句柄,通过SQLConnect、SQLDriverConnect或SQLBrowseConnect与数据源连接
SQLConnect连接函数的输入参数为:
配置好的数据源名称
用户ID
口令
[例8.12]中KingbaseES ODBC为数据源名字,SYSTEM为用户名,MANAGER为用户密码
创建数据源—第三步:建立连接

/* Step 3 建立连接 */
ret=SQLAllocHandle(SQL_HANDLE_DBC, kinghenv, &kinghdbc);
ret=SQLAllocHandle(SQL_HANDLE_DBC, serverhenv,                          		          &serverhdbc);
ret=SQLConnect(kinghdbc,“KingbaseES ODBC”, SQL_NTS,“SYSTEM”,SQL_NTS, "MANAGER",SQL_NTS);
if (!SQL_SUCCEEDED(ret))	/*连接失败时返回错误值*/return -1;	
ret=SQLConnect(serverhdbc, "SQLServer", SQL_NTS, "sa“,SQL_NTS,"sa",SQL_NTS);
if (!SQL_SUCCEEDED(ret) )	/*连接失败时返回错误值*/return -1;

分配语句句柄

处理任何SQL语句之前,应用程序还需要首先分配一个语句句柄
语句句柄含有具体的SQL语句以及输出的结果集等信息
应用程序还可以通过SQLtStmtAttr来设置语句属性(也可以使用默认值)
创建数据源—第四步

/* Step 4 初始化语句句柄 */
ret=SQLAllocHandle(SQL_HANDLE_STMT,kinghdbc,&kinghstmt);
ret=SQLSetStmtAttr(kinghstmt,SQL_ATTR_ROW_BIND_TYPE, 			 	 (SQLPOINTER)SQL_BIND_BY_COLUMN,			  	 	 SQL_IS_INTEGER);
ret=SQLAllocHandle(SQL_HANDLE_STMT,serverhdbc, 			&serverhstmt);

执行SQL语句

应用程序处理SQL语句的两种方式
预处理(SQLPrepare、SQLExecute适用于语句的多次执行)
直接执行(SQLExecdirect)
如果SQL语句含有参数,应用程序为每个参数调用SQLBindParameter,并把它们绑定至应用程序变量
应用程序可以直接通过改变应用程序缓冲区的内容从而在程序中动态改变SQL语句的具体执行
应用程序根据语句类型进行的处理
有结果集的语句(select或是编目函数),则进行结果集处理
没有结果集的函数,可以直接利用本语句句柄继续执行新的语句或是获取行计数(本次执行所影响的行数)之后继续执行
在插入数据时,采用了预编译的方式,首先通过SQLPrepare来预处理SQL语句,然后将每一列绑定到用户缓冲区
创建数据源—第五步:执行SQL语句

/* Step 5 两种方式执行语句 */
/* 预编译带有参数的语句 */
ret=SQLPrepare(serverhstmt,"INSERT INTO 				  STUDENT(SNO,SNAME,SSEX, SAGE,SDEPT) VALUES (?, ?, ?, ?, ?)", SQL_NTS);
if (ret==SQL_SUCCESS || ret==SQL_SUCCESS_WITH_INFO)
{ret=SQLBindParameter(serverhstmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,SNO_LEN,0,sSno,0, &cbSno); ret=SQLBindParameter(serverhstmt,2,SQL_PARAM_INPUT, SQL_C_CHAR,SQL_CHAR,NAME_LEN,0,sName,0,&cbName);ret=SQLBindParameter(serverhstmt,3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,2,0,sSex,0,&cbSex);ret=SQLBindParameter(serverhstmt,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&sAge,0,&cbAge);
ret=SQLBindParameter(serverhstmt,5,SQL_PARAM_INPUT,  SQL_C_CHAR,SQL_CHAR, DEPART_LEN, 0, sDepart,0,    &cbDepart);}/*执行SQL语句*/
ret=SQLExecDirect(kinghstmt,"SELECT * FROM 				         STUDENT",SQL_NTS);
if (ret==SQL_SUCCESS || ret==SQL_SUCCESS_WITH_INFO) 
{
ret=SQLBindCol(kinghstmt,1,SQL_C_CHAR,sSno,SNO_LEN,&cbSno);
ret=SQLBindCol(kinghstmt,2,SQL_C_CHAR,sName,NAME_LEN,&cbName);
ret=SQLBindCol(kinghstmt,3,SQL_C_CHAR,sSex,SSEX_LEN,&cbSex);
ret=SQLBindCol(kinghstmt,4,SQL_C_LONG,&sAge,0,&cbAge);
ret=SQLBindCol(kinghstmt,5,SQL_C_CHAR,sDepart, 				DEPART_LEN,&cbDepart);
}

结果集处理

应用程序可以通过SQLNumResultCols来获取结果集中的列数
通过SQL DescribeCol或是SQLColAttrbute函数来获取结果集每一列的名称、数据类型、精度和范围
ODBC中使用游标来处理结果集数据
ODBC中游标类型
Forward-only游标,是ODBC的默认游标类型
可滚动(Scroll)游标
静态(static)
动态(dynamic)
码集驱动(keyset-driven)
混合型(mixed)
结果集处理步骤
ODBC游标的打开方式不同于嵌入式SQL,不是显式声明而是系统自动产生一个游标,当结果集刚刚生成时,游标指向第一行数据之前
应用程序通过SQLBindCol把查询结果绑定到应用程序缓冲区中,通过SQLFetch或是SQLFetchScroll来移动游标获取结果集中的每一行数据
对于如图像这类特别的数据类型,当一个缓冲区不足以容纳所有的数据时,可以通过SQLGetdata分多次获取
最后通过SQLClosecursor来关闭游标
创建数据源—第六步:结果集处理

/* Step 6 处理结果集并执行预编译后的语句*/
while ((ret=SQLFetch(kinghstmt))!=SQL_NO_DATA_FOUND) {  
if(ret==SQL_ERROR)printf("Fetch error\n");
else  ret=SQLExecute(serverhstmt);
}

中止处理

应用程序中止步骤
释放语句句柄
释放数据库连接
与数据库服务器断开
释放ODBC环境
创建数据源—第七步:中止处理

/* Step 7 中止处理*/
SQLFreeHandle(SQL_HANDLE_STMT,kinghstmt);
SQLDisconnect(kinghdbc);
SQLFreeHandle(SQL_HANDLE_DBC,kinghdbc);
SQLFreeHandle(SQL_HANDLE_ENV,kinghenv);
SQLFreeHandle(SQL_HANDLE_STMT,serverhstmt);
SQLDisconnect(serverhdbc);
SQLFreeHandle(SQL_HANDLE_DBC,serverhdbc);
SQLFreeHandle(SQL_HANDLE_ENV,serverhenv);
return 0;
}

欢迎大家加我微信交流讨论(请备注csdn上添加)
在这里插入图片描述


http://chatgpt.dhexx.cn/article/vkKKjIQ3.shtml

相关文章

第8章 数据库编程

文章目录 ❖第一节 T-SQL编程基础标识符注释语句表达式SET、SELECT区别 流程控制语句选择结构❖IF ELSECASE语句搜索式CASE语句 循环结构等待语句返回语句 系统函数标量函数日期和时间函数字符串函数 数据类型转换函数 ❖第二节 游标&#xff08;重点&#xff09;1. 声明游标2.…

teredo实现ipv4公网环境下接入ipv6

teredo实现ipv4公网环境下接入ipv6 系统&#xff1a;macOS High Sierra 10.13.3 测试成功 软件下载 下载安装Miredo http://www.deepdarc.com/miredo-osx-prerelease2.pkg.zip 项目github地址&#xff1a;https://github.com/darconeous/miredo-osx下载安装tuntaposx http…

Tornado简介

Tornado龙卷风是一个开源的网络服务器框架&#xff0c;它是基于社交聚合网站FriendFeed的实时信息服务开发而来的 Tornado是使用Python编写的Web服务器兼Web应用框架与主流Web服务器框架不同的是&#xff0c;Tornado是异步非阻塞式服务器&#xff0c;得益于非阻塞式和对epoll模…

【小白教程】win10系统如何开启ipv6

Teredo 是一种网络协议&#xff0c;用于在客户端和服务器之间建立安全通信&#xff0c;并且在使用网络地址转换 (NAT) 的路由器后增强设备之间的连接。 #####以下代码均在cmd窗口运行###### 一、设置Teredo 服务器 1、设置Teredo 服务器 netsh interface teredo set state …

Teredo Tunnel Adapter: Error Code 10

Teredo Tunneling 该设备无法启动 错误代码 ErrCode:10 解决方法 前文&#xff1a; Win7 系统&#xff0c;打算开启IPV6&#xff0c;本地连接的网络 ip6 驱动是异常的&#xff0c;先重新安装了网卡驱动。 过程&#xff1a; 几次尝试之后&#xff0c;还是无法启动&#xff0c;…

地平线不能多人联机解决方法

玩地平线4时可能会出现无法连接多人网络问题&#xff0c;在Xbox网络中出现Teredo不合格的问题。 解决方案&#xff1a; 按WinR输入gpedit.msc打开组策略编辑器&#xff0c;依次选择管理模块、网络、TCPIP设置、IPv6转换技术。双击设置6to4状态&#xff0c;点已启用&#xff0c…

微软的teredo服务器,win10系统通过teredo连接ipv6的操作方法

win10系统通过teredo连接ipv6的操作方法? 很多win10用户在使用电脑的时候&#xff0c;会发现win10系统通过teredo连接ipv6的的现象&#xff0c;根据小编的调查并不是所有的朋友都知道win10系统通过teredo连接ipv6的的问题怎么解决&#xff0c;不会的朋友也不用担心&#xff0c…

TCP/IP卷一:55---UDP之(UDP与IPv6、Teredo)

前一篇文章&#xff08;https://blog.csdn.net/qq_41453285/article/details/103984794&#xff09;对UDP和UDP数据报、UDP校验和做了简单的介绍&#xff0c;本片文章介绍一些UDP与IPv6有关的知识 一、IPv6下的UDP 考虑到简单性&#xff0c;在对IPv6而非IPv4进行操作时&#…

miredo - Teredo IPv6 tunneling for Unix

世界 IPv6 日&#xff1a;2011年6月8日 Test your IPv6&#xff1a;http://test-ipv6.com 安装miredo sudo apt-get install miredo 编辑miredo配置文件&#xff0c;加入teredo 的公共服务器地址&#xff0c;如ServerAddress teredo-debian.remlab.net sudo gedit /etc…

teredo 未能解析服务器名,Win10系统Xboxlive显示Teredo无法进行限定怎么解决

有的朋友会在windows10电脑上用Xbox live游玩游戏&#xff0c;但是碰到Xbox live设置显示Teredo无法进行限定&#xff0c;这时候我们该怎么办呢&#xff0c;下面由小编给大家介绍如何解决win10系统Xbox live显示Teredo无法进行限定。 具体步骤如下&#xff1a; 1.按下键盘上的&…

报PING:传输失败。常见故障.connect:network is unreachable“的解决方案-IPv6无法ssh连接的解决方案。

vultr当前2.5美金的vps只有IPv6&#xff0c;很多使用者无法正常使用ssh连接等&#xff0c;报PING&#xff1a;传输失败。常见故障。connect&#xff1a;network is unreachable 很多使用者不知所措&#xff0c;笔者也是一脸懵逼&#xff0c;经过一番研究之后&#xff0c;发现了…

微软的teredo服务器,win10系统通过teredo连接ipv6的具体教程

有关win10系统通过teredo连接ipv6的操作方法想必大家有所耳闻。但是能够对win10系统通过teredo连接ipv6进行实际操作的人却不多。其实解决win10系统通过teredo连接ipv6的问题也不是难事&#xff0c;小编这里提示两点&#xff1a;1、在“开始”里输入“cmd”&#xff0c;右击&am…

Win11地平线4 Xbox live无法登录?或者地平线4无法使用在线模式?尝试一波!!!

全是抄袭&#xff0c;只做整理&#xff0c;希望帮到大家&#xff0c;啥也不懂&#xff01;但是&#xff01;我就是这样弄好的 侵权 联系 我 就下架&#xff0c;但是只是想让大家可以解决问题 以下是我参照的文章&#xff1a; XBOX NAT类型:Teredo不合格解决方案 - 知乎 (zhi…

Win7使用teredo连接IPv6的方法

(1) 在 ” 开始 ”->” 运行 ” 中输入 cmd 打开 Windows 命令行。在命令行中输入 ipconfig /all &#xff0c;会出现若干网络配置信息&#xff0c;找到 Tunnel adpter &#xff08;隧道适配器&#xff09; Teredo Tunneling Pseudo-Interface &#xff0c; 查看它是否有正确…

关于Win10用户地平线线上连接xbox live失败问题

问题描述 游玩地平线系列游戏时&#xff0c;无法进入线上游戏游玩更多游戏内容&#xff0c;且无法与朋友联机&#xff0c;问题未知&#xff0c;并且更改加速器节点也没有用。本解决方案针对Win10的小伙伴&#xff0c;Win11的小伙伴可以参考一下。 解决方案 主要是解决xbox网络…

关于解决NAT 类型显示“Teredo 无法获得资格”的一个案例

在试过了网上很多的方法之后&#xff0c;发现依旧解决不了&#xff0c;最后发现了xbox官方的一个解决方法并且成功。&#xff08;这个是在完成了网上众多方法的前提下才解决的&#xff09; 链接:Xbox Support。 其中我估计解决方案2到5就是网上众多的解决方法&#xff0c;由于本…

teredo报文格式

teredo报文是一项 IPv6 / IPv4 过渡技术&#xff0c;为能够通过 IPv4 NAT&#xff0c; IPv6 数据包作为基于 IPv4 的用户数据包协议(UDP) 消息发送出去。 格式如下&#xff1a; 注意&#xff0c;外层为V4报文&#xff0c;内层为V6报文&#xff0c;V4报文后的UDP报文的目的端口…

Teredo 概述

Teredo 概述 发布日期&#xff1a; 2004年05月14日 摘要 了解 Teredo &#xff08;又成为面向 IPv6 的 IPv4 NAT [网络地址转换]穿越&#xff0c;是一项 IPv6 / IPv4 过渡技术&#xff0c;在 IPv6 / IPv4 主机位于一个或多个 IPv4 NAT 之后时&#xff0c;用来为单播 IPv6 连接提…

Java学习-java中的与或非

文章目录 前言一、 与&#xff08;&&#xff09;和短路与&#xff08;&&&#xff09;&#xff08;1&#xff09;概念与区别&#xff08;2&#xff09;代码示例 二、或&#xff08;|&#xff09;与短路或&#xff08;||&#xff09;&#xff08;1&#xff09;概念与…

python中的与或非详解

python中的逻辑判断与或非和其他语言的逻辑判断结果有一点不同&#xff0c;这一不小心就让中了招&#xff0c;有时候迷惑为什么结果与预测的结果大相径庭&#xff0c;既然是吃饭的手段&#xff0c;还是要认真的专研一下&#xff0c;以免出去让人看了笑话。 先来一组对比&#…