ODBC

一、ODBC简介

开放数据库互连(ODBC)是微软提出的数据库访问接口标准。开放数据库互连定义了访问数据库的API一个规范,这些API独立于不同厂商的DBMS,也独立于具体的编程语言。通过使用ODBC,应用程序能够使用相同的源代码和各种各样的数据库进行交互。这使得开发者不需要以特殊的数据库管理系统DBMS为目标,或者了解不同支撑背景的数据库的详细细节,就能够开发和发布客户/服务器应用程序。下面是ODBC应用系统的体系结构。

二、ODBC句柄

应用程序运行后,为维护执行的状态,ODBC 管理器和ODBC 驱动程序中必须保持足够的控制信息。应用程序要求ODBC 管理器和ODBC 驱动程序为ODBC环境、每个连接以及每个SQL语句分配描述/控制信息存储空间,并返回指向各个存储区的句柄供其使用。

(1)环境句柄:整个ODBC上下文的根句柄。标识全程数据访问控制信息的内存结构,包括有效连接句柄以及当前活动连接句柄。ODBC将环境句柄定义为HENV类型的变量。应用程序使用单一的环境句柄,在连接到数据源以前必须申请该句柄。

(2)连接句柄:管理有关数据库会话的所有信息。连接句柄标识每个特定的连接信息的内存结构。ODBC将环境句柄定义为HDBC类型的变量。应用程序在连接数据源之前申请连接句柄。每个连接句柄与环境句柄有关,环境句柄上可以有多个与其有关的连接句柄。

(3)语句句柄:ODBC语句包括应用访问数据源的SQL语句和语句相关的管理信息,语句句柄标识每个语句管理信息的内存结构。ODBC将语句句柄定义为HSTMT类型的变量。应用程序在提交SQL请求之前也必须申请语句句柄。每个语句句柄与一个连接句柄有关,每个连接句柄上可以有多个与其有关的语句句柄。

三、ODBC程序执行流程

Ø 分配环境句柄

基于ODBC3.X版本的应用统一使用SQLAllocHandle来分配句柄。调用时设计不同的句柄类型就可以获得该类型的句柄。但在API内部实现上一般重新转换为执行SQLAllocEnv,SQLAllocConnect和SQLAllocStmt,这样可以达到兼容和代码重用作用。SQLAllocEnv:用来分配环境句柄。

例如:ret = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &oraclehenv);

Ø 分配连接句柄

SQLAllocConnect:用来分配连接句柄。连接句柄提供对一些信息的访问,例如,在连接上的有效语句及标识符句柄,以及当前是否打开一些一个事务处理。调用SQLAllocConnect 函 数 获 取 连 接 句 柄。例如:

ret = SQLAllocHandle(SQL_HANDLE_DBC, oraclehenv, &oraclehdbc);

Ø  建立数据源

使用已分配的连接句柄来建立应用程序和数据源/数据库系统的连接,进行句柄和数据源的绑定。绑定也由目标数据源的ODBC驱动程序完成。

例 如:ret = SQLConnect(oraclehdbc,

"conn",SQL_NTS, //ODBC的DNS名称

"scott",SQL_NTS, //用户账号

"123",SQL_NTS);     //密码

Ø 分配语句句柄

用户对DBC数据源的存取操作,都是通过SQL语句实现的。在这个过程中,应用程序 将通过连接向ODBC数据库提交SQL语句,以完成用户请求的操作。即通过执行SQLAllocHandle或SQLAllocStmt来分配语句句柄。调用SQLAllocStmt 函数获取语句句柄。例如:

SQLstmt= "SELECT * FROM authors"

rc= SQLAllocStmt(hdbc, hstmt)

Ø  执行SQL语句

执行SQL语句。 执行SQL 语 句 的方法比较多, 最简单明了的方法是调用SQLAllocStmt函数,例如:

SQLstmt= "SELECT * FROM authors"

rc= SQLExecDirect(hstmt, SQLstmt, Len(SQLstmt))

如果SQL语句被顺利提交并正确执行,那么就会产生一个结果集。检索结果集的方法有很多,最简单最直接的方法是调用SQLFetch 和SQLGetData 函 数。

SQLFetch函数的功能是将结果集的当前记录指针移至下一个记录;

SQLGetData函数的功能是提取结果集中当前记录的某个字段值。通常可以采用一个循环以提取结果集中所有记录的所有字段值,该循环重复执行SQLFetch和SQLGetData函数,直至SQLFetch函数返回SQL_NO_DATA_FOUND, 这表示已经到达结果集的末尾。

DimColVal As String * 225

ColVal= String(255, 0)

Ø 结束应用程序

在应用程序完成数据库操作, 退出运行之前,必须释放程序中使用的系统资源。这些系统资源包括:语句句柄、连接句柄和ODBC环境句柄。完成这个过程的如下:

调用SQLFreeStmt 函数释放语句句柄及其相关的系统资源。例如:

rc= SQLFreeStmt(hstmt, SQL_DROP)

调用SQLDisconnect 函数关闭连接。 例 如:

rc= SQLDisconnect(hdbc)

调用SQLFreeConnect函数释放连接句柄及其相关的系统资源。例如:

rc= SQLFreeConnect(hdbc)

调用SQLFreeEnv函数释放环境句柄及其相关的系统资源,停止ODBC 操作。 例如:

rc= SQLFreeEnv(henv)

(7)错 误 处 理

所有DBCAPI函 数, 若在执行期间发生错误, 都将返回一个标准错误代码SQL_ERROR。

一般来讲,在每次调用ODBC API 函 数 之 后, 都应该检查该函数返回值,确定该函数是否成功地执行,再决定是否继续后续过程。 而详细的错误信息,可以调用SQLError 函数获得。SQLError 函数将返回下列信息: 标准的ODBC错误状态码 ODBC 数据源提供的内部错误编码错误信息串

四、开发环境的配置

1.创建Oracle ODBC数据源

对于WIN 7系统来说,打开控制面板,找到ODBC,具体位置如下图所示,如果没有找到,可以在右上角搜索栏里面输入ODBC,就可以找到了。

对于WIN XP系统来说,打开控制面板,找到管理工具,找到数据源(ODBC),显示ODBC数据源管理器对话框。对话框如下图所示。

2.设置和配置一个系统DSN,单击“系统DSN标签”,选择“添加”。

3.找到需要配置的数据源,单击完成,弹出如下对话框,

4.输入数据源的名称,一个简单的描述,用户名和网络连接名。点击确认。

五、学生表创建

1.首先创建stu表

create table stu(

sno char(11) ,

sname varchar2(10),

sex char(2),

sage number,

sdepart varchar2(30)

);

六、数据类型

七、参考资料

数据库系统概论 第四版 王珊 萨师煊 高等教育出版社

电子资料链接:http://pan.baidu.com/s/1su9c5

ODBC程序

开发工具vs2017

<database.h>

#pragma once#ifndef _DATABASE_H
#define _DATABASE_H
#include <sql.h>
#include<sqlext.h>
#include<sqltypes.h>
typedef struct {SQLHENV oraclehenv;                     //环境句柄SQLHDBC oraclehdbc;                       //连接句柄SQLHSTMT oraclehsmt;                  //语句句柄SQLRETURN ret;                            //结果集
}DATABASE;DATABASE getConnection();                 //获取连接
void init(DATABASE *d);                     //初始化
void freeConnection(DATABASE d);            //释放连接资源#endif // !_DATABASE_H

<student.h>

#pragma once
#include "DATABASE.h"#ifndef _STUDENT_H
#define _STUDENT_H
#include <sql.h>
#include<sqlext.h>
#include<sqltypes.h>#define sno_length 11
#define sname_length 10
#define sdepart_length 30
#define ssex_length 5typedef struct {SQLCHAR sno[sno_length], sname[sname_length], sdepart[sdepart_length], ssex[ssex_length];SQLSMALLINT sage;SQLINTEGER cbsno, cbsname, cbdepart, cbsage, cbsex;
}STUDENT;SQLCHAR *get(SQLCHAR *p, char *s);     //将char数组转换SQLCHAR类型
void processSQL(SQLCHAR *sql, SQLHSTMT oraclehsmt);
void display(DATABASE d);
void getStu(char *sno, SQLHSTMT oraclehsmt);
int insert(STUDENT, DATABASE);
void deleteStu(char *sno, DATABASE d);
SQLRETURN  updateStu(STUDENT s, DATABASE d);
STUDENT inputStu();
void error(SQLRETURN err, int n);#endif // !_DATABASE_H

<getConnection.cpp>

#include"DATABASE.h"
#include <sql.h>
#include<sqlext.h>
#include<sqltypes.h>
#include<stdlib.h>
#include <stdio.h>
#include<windows.h>
#include<string.h>
DATABASE getConnection() {DATABASE d;/****分配环境句柄********/d.ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &d.oraclehenv);d.ret = SQLSetEnvAttr(d.oraclehenv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);/********建立连接*********/d.ret = SQLAllocHandle(SQL_HANDLE_DBC, d.oraclehenv, &d.oraclehdbc);d.ret = SQLConnect(d.oraclehdbc, (SQLCHAR *)"con", SQL_NTS, (SQLCHAR *)"HR", SQL_NTS, (SQLCHAR *)"oracle", SQL_NTS);if (SQL_SUCCEEDED(d.ret)){puts("Connect Sucess!");init(&d);}else{//连接失败时返回错误值puts("Conect Fail!");}return d;
}void init(DATABASE *d)
{/***初始化句柄*/SQLEndTran(SQL_HANDLE_DBC, d->oraclehdbc, SQL_COMMIT);                       //提交事务d->ret = SQLAllocHandle(SQL_HANDLE_STMT, d->oraclehdbc, &d->oraclehsmt);            //初始化语句句柄d->ret = SQLSetStmtAttr(d->oraclehsmt, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)SQL_BIND_BY_COLUMN, SQL_IS_INTEGER);//设置语句选项
}void freeConnection(DATABASE d)
{SQLEndTran(SQL_HANDLE_DBC, d.oraclehdbc, SQL_COMMIT);              //提交事务SQLFreeHandle(SQL_HANDLE_STMT, d.oraclehsmt);SQLDisconnect(d.oraclehdbc);SQLFreeHandle(SQL_HANDLE_DBC, d.oraclehdbc);SQLFreeHandle(SQL_HANDLE_ENV, d.oraclehenv);printf("释放连接\n\n");
}

<operateStudent.cpp>

#include "DATABASE.h"
#include "STUDENT.h"
#include <sql.h>
#include<sqlext.h>
#include<sqltypes.h>
#include<stdlib.h>
#include <stdio.h>void processSQL(SQLCHAR *sql, SQLHSTMT oraclehsmt)
{STUDENT s;int count = 1;s.cbsno = SQL_NTS;s.cbsname = SQL_NTS;s.cbdepart = SQL_NTS;s.cbsage = 0;s.cbsex = SQL_NTS;SQLRETURN ret = SQLExecDirect(oraclehsmt, sql, SQL_NTS);if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO){ret = SQLBindCol(oraclehsmt, 1, SQL_C_CHAR, s.sno, sno_length, &s.cbsno);ret = SQLBindCol(oraclehsmt, 2, SQL_C_CHAR, s.sname, sname_length, &s.cbsname);ret = SQLBindCol(oraclehsmt, 3, SQL_C_CHAR, s.ssex, ssex_length, &s.cbsex);ret = SQLBindCol(oraclehsmt, 4, SQL_C_LONG, &s.sage, 0, &s.cbsage);ret = SQLBindCol(oraclehsmt, 5, SQL_C_CHAR, s.sdepart, sdepart_length, &s.cbdepart);}/***处理结果**/while ((ret = SQLFetch(oraclehsmt)) != SQL_NO_DATA_FOUND ){if (ret == SQL_ERROR){printf("erro!\n");}else{printf("\t%-3d    %s   %s   %s  %4d  %s\n", ++count, s.sno, s.sname, s.ssex, s.sage, s.sdepart);}}
}void display(DATABASE d)
{SQLCHAR *sql = (SQLCHAR *)"select * from stu";processSQL(sql, d.oraclehsmt);
}
/*****插入********/
int insert(STUDENT s, DATABASE d)
{char str[100] = "insert into stu values(";char *age = (char *)malloc(sizeof(s.sage) + 1);_itoa_s((int)s.sage, age, 10, 10);strcat_s(str, sizeof(str), "'");strcat_s(str, sizeof(str), (char *)s.sno);strcat_s(str, sizeof(str), "',");strcat_s(str, sizeof(str), "'");strcat_s(str, sizeof(str), (char *)s.sname);strcat_s(str, sizeof(str), "',");strcat_s(str, sizeof(str), "'");strcat_s(str, sizeof(str), (char*)s.ssex);strcat_s(str, sizeof(str), "',");strcat_s(str, sizeof(str), "'");strcat_s(str, sizeof(str), age);strcat_s(str, sizeof(str), "',");strcat_s(str, sizeof(str), "'");strcat_s(str, sizeof(str), (char *)s.sdepart);strcat_s(str, sizeof(str), "')");d.ret = SQLExecDirect(d.oraclehsmt, (SQLCHAR *)str, SQL_NTS);error(d.ret, 77);return 0;}SQLCHAR *get(SQLCHAR *p, char *s)
{if ((s == NULL) || (p == NULL)){return NULL;}SQLCHAR *r = p;while ((*r++ = *s++) != '\0');return p;
}void getStu(char *sno, SQLHSTMT oraclehsmt)
{SQLCHAR *sql;char str[100] = "select * from stu where sno = \'";strcat_s(str, sizeof(str), sno);strcat_s(str, sizeof(str), "'");sql = (SQLCHAR *)str;printf("getStu()函数\n");getchar();processSQL(sql, oraclehsmt);
}void deleteStu(char *sno, DATABASE d)
{SQLCHAR *sql = NULL;char str[100] = "delete from stu where sno = \'";strcat_s(str, sizeof(str), sno);strcat_s(str, sizeof(str), "'");sql = (SQLCHAR *)str;d.ret = SQLExecDirect(d.oraclehsmt, sql, SQL_NTS);error(d.ret, 114);
}SQLRETURN updateStu(STUDENT s, DATABASE d)
{SQLRETURN ret;SQLCHAR *sql = NULL;char str[100] = "update stu set ";char *age = (char *)malloc(sizeof(s.sage) + 1);_itoa_s((int)s.sage, age, 10, 10);strcat_s(str, sizeof(str), "sname = \'");strcat_s(str, sizeof(str), (char *)s.sname);strcat_s(str, sizeof(str), "', ");strcat_s(str, sizeof(str), "sex = \'");strcat_s(str, sizeof(str), (char *)s.ssex);strcat_s(str, sizeof(str), "', ");strcat_s(str, sizeof(str), "sage = \'");strcat_s(str, sizeof(str), age);strcat_s(str, sizeof(str), "', ");strcat_s(str, sizeof(str), "sdepart = \'");strcat_s(str, sizeof(str), (char *)s.sdepart);strcat_s(str, sizeof(str), "' ");strcat_s(str, sizeof(str), "where sno =  \'");strcat_s(str, sizeof(str), (char *)s.sno);strcat_s(str, sizeof(str), "'");for (int i = 0; i < sizeof(str); i++){printf("%c", str[i]);}printf("\n");sql = (SQLCHAR *)str;ret = SQLExecDirect(d.oraclehsmt, sql, SQL_NTS);error(ret, 150);return ret;
}STUDENT inputStu()
{STUDENT s;char sno[sno_length], sname[sname_length], ssex[ssex_length], sdepart[sdepart_length], ssage[5];int sage;fflush(stdin);printf("请输入一个学号:");gets_s(sno, sizeof(sno));printf("\n请输入一个姓名:");gets_s(sname, sizeof(sname));printf("\n请输入一个性别:");gets_s(ssex, sizeof(ssex));printf("\n请输入一个年龄:");sage = atoi(gets_s(ssage));printf("\n请输入一个部门:");gets_s(sdepart, sizeof(sdepart));get(s.sno, sno);get(s.sname, sname);get(s.ssex, ssex);s.sage = sage;get(s.sdepart, sdepart);return s;
}void error(SQLRETURN err, int n) {printf("%d ", n);switch (err) {case    SQL_SUCCESS:puts("****SQL_SUCCESS*****"); break;case  SQL_SUCCESS_WITH_INFO:puts("SQL_SUCCESS_WITH_INFO"); break;case   SQL_ERROR:puts("SQL_ERROR"); break;case   SQL_INVALID_HANDLE:puts("SQL_INVALID_HANDLE"); break;case SQL_NO_DATA_FOUND:puts("SQL_NO_DATA_FOUND"); break;case   SQL_NEED_DATA:puts("SQL_NEED_DATA"); break;default:puts("err");}
}

<Test.cpp>

#include "STUDENT.h"
#include "DATABASE.h"
#include <sql.h>
#include<sqlext.h>
#include<sqltypes.h>
#include<stdlib.h>
#include <stdio.h>
#include<windows.h>
#include<string.h>char menu()
{char choice;printf("\t a.查询4所有人的信息\n");printf("\t s.查询个人信息指定学号\n");printf("\t i.插入\n");printf("\t d.删除\n");printf("\t u.修改\n");printf("\t q.退出\n");printf("\n **********************\n \t请输入你的选项:");choice = getchar();return choice;}void deal(char choice, DATABASE d)
{getchar();switch (choice){init(&d);case 'a':display(d);break;case 's': {char sno[10];fflush(stdin);printf("\n请输入学号:");gets_s(sno);printf("sno = %s\n", sno);getStu(sno, d.oraclehsmt); break;}case 'i': {STUDENT s = inputStu();insert(s, d);break;}case 'd': {char sno[10];printf("请输入学号:");gets_s(sno);deleteStu(sno, d); break;}case 'u': {STUDENT s = inputStu();updateStu(s, d);break;}case 'q': freeConnection(d); exit(0);default:printf("输入错误,请从新输入\n"); break;}printf("\n\t***************处理结束******************\n");
}int main()
{   DATABASE database = getConnection();do{char c;c = menu();deal(c,database);getchar();system("cls");} while (true); return 0;
}

<sql>

drop table stu;
create table stu(sno char(10),sname varchar2(10),sex char(5),sage number,sdepart varchar2(30),primary key(sno)
);insert into stu values('201500730','张三','男',20,'计算机系' );
insert into stu values('201500731','李四','男',20,'计算机系' );
insert into stu values('201500732','王五','男',20,'计算机系' );
insert into stu values('201500733','赵六','男',20,'计算机系' );
commit;select * from stu;

【ODBC】ODBC连接数据库详细说明相关推荐

  1. C++通过ODBC方式连接数据库SQLServer及增删查改操作【图书借阅系统为例】

    C++通过ODBC方式连接数据库SQLServer及增删查改操作[图书借阅系统为例] 文章目录 前言 一.ODBC如何配置 二.SQL Server如何设置账号密码 三.C++连接数据库以及增删查改操 ...

  2. ODBC连接数据库详细说明

    文章目录 一.ODBC简介 二.ODBC句柄 三.ODBC程序执行流程 Ø 分配环境句柄 Ø 分配连接句柄 Ø 建立数据源 Ø 分配语句句柄 Ø 执行SQL语句 Ø 结束应用程序 四.开发环境的配置 ...

  3. ODBC方式连接数据库

    以下介绍的是用ODBC方式连接SQL数据库 一.创建ODBC数据源 找到"数据源(ODBC)",并打开它-----选择"系统DSN"-----添加-----选择 ...

  4. MFC下ODBC方式连接数据库

    本篇文章主要记录VS2010环境下,MFC ODBC方式连接SQL Server数据库,通过ODBC数据源连接配置. 1.数据库 首先确保在SQL Server中已经创建好了数据库,如我使用的是cha ...

  5. centos7 关于php使用pdo扩展连接数据库详细步骤

    1 yum install httpd.x86_64 (安装http.x86) 2 yum install php(安装php) 3 systemctl start httpd.service(重启h ...

  6. JDBC连接数据库详细步骤

    一.先创建一个项目 二.打开数据库并启动连接 (我是在IDEA中写的,提前导包) 三.不会导包就在Maven中导,在pom.xml中的dependencise放,版本号看自己要高版本还是低版本.放进去 ...

  7. pl/sql developer 怎么连接mysql_PL/SQL Developer连接数据库详细教程

    PL/SQL Developer是一个集成开发环境,它专门针对Oracle数据库的存储程序单元的开发所用.现在越来越多的商业逻辑和应用程式逻辑都在使用Oracle服务器,所以PL/SQL编程在整个开发 ...

  8. IntelliJ IDEA 连接数据库 详细过程

    IntelliJ IDEA集成了众多插件,方便开发者使用,使用其自带的Database模块就可以很方便的配置.连接到数据库,本次操作以MySQL为例,其中testjdbc数据库已经提前建好,里面有两张 ...

  9. JDBC连接数据库详细讲解及代码演示

    目录 JDBC介绍 JDBC访问数据库编码步骤 1. 准备好相应的jar包 2. 创建lib目录 3. 导入下载好的jar包 4. 简单的CURD 5. PreparedStatment完成CURD ...

  10. idea 连接数据库详细教程(新手篇)2021版idea

    第一步找到Database,一般在右边 第二步点击+号即可打开这个, 第三步可以根据不同的数据库选择本期只有SQL Server (如有需要可留言) 3.1 题外如果没有驱动可下载 第四步选中SQL ...

最新文章

  1. #define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined解释
  2. J2EE中在web.xml异常页面跳转
  3. Java sdk 调用淘宝开发平台
  4. 此图片来自微信公众平台未经允许不可引用
  5. 淘宝双12趣味大数据:150万件打底裤被男人买走了;套套销量暴涨50%...
  6. springboot细节挖掘(配置Swagger2)
  7. Python3基础12(collections、struct、itertools、chardet等的使用)
  8. PTA:7-1 还原二叉树 (25 分)
  9. Python中如何清空Queue?
  10. linux下文本处理
  11. 2021考研——复习规划(数学篇)
  12. linux版svn 软件,可以媲美TortoiseSVN的Linux版SVN客户端软件RabbitVCS
  13. pg数据库的一些问题
  14. Snagit 2021 for mac(屏幕截图工具)
  15. 李白的苏台览古译文赏析
  16. ssl证书 嵌入式设备_ngx_http_ssl_module
  17. java swing是什么_JAVA初学者:swing是什么?
  18. 《指数基金投资指南》读书笔记_2022002
  19. javaFX实现登录界面并跳转
  20. html5+css3学习笔记(一)

热门文章

  1. vscode下载之前版本插件
  2. 定时任务时间表达式规则
  3. idea 格式化模板修改
  4. linux a7 a8,iOS12 A7/A8 固定Generator值 图文教程
  5. python预测比赛_分析5万多场英雄联盟比赛,教你如何轻松用python预测胜负
  6. M语言中的操作符说明:大括号{}-列List,方括号[]-记录Record
  7. 【Linux】Linux Ext2文件系统
  8. php ksc歌词,KSC字幕制作方法 KSC歌词编辑教程
  9. NC Viewer 2.41 1CD(NC程式检验程序)
  10. Linux源码编译即黑客帝国屏保cmatrix安装