1、数据库接口实验11. 实验一 数据库接口实验1.1实验目的1通过实验了解通用数据库应用编程接口ODBC的基本原理和实现机制,熟悉主要的ODBC接口的语法和使用方法;2利用C语言(或其它支持ODBC接口的高级程序设计语言)编程实现简单的数据库应用程序,掌握基于ODBC的数据库访问的基本原理和方法3学习java语言,并采用jdbc接口方式对数据库进行访问1.2实验内容1.以教科书第四章关于SQL语言相关内容为基础,课后查阅、自学ODBC接口有关内容,包括ODBC的体系结构、工作原理、数据访问过程、主要API接口的语法和使用方法等。2 以实验二建立的学生数据库为基础,编写 C语言(或其它支持ODBC
2、接口的高级程序设计语言) 数据库应用程序,按照如下步骤访问数据库(a)Step1. ODBC初始化,为ODBC分配环境句柄(b)Step2. 建立应用程序与ODBC数据源的连接(c)Step3. 利用SQLExecDirect语句,实现数据库应用程序对数据库的建立、查询、修改、删除等操作(d)Step4. 检索查询结果集(e)Step5. 结束数据库应用程序 1.3实验要求1要求所编写的数据库访问应用程序中使用到以下主要的ODBC API函数:(1)SQLALLocEnv:初始化ODBC环境,返回环境句柄(2)SQLALLocConnect:为连接句柄分配内存并返回连接句柄(3)SQLConn
3、ect:连接一个SQL数据资源(4) SQLDriverConnect连接一个SQL数据资源,允许驱动器向用户询问信息(5) SQLALLocStmt 为语句句柄分配内存, 并返回语句句柄(6) SQLExecDirect 把SQL语句送到数据库服务器,请求执行由SQL语句定义的数据库访问(7) SQLFetchAdvances将游标移动到到查询结果集的下一行(或第一行)(8) SQLGetData 按照游标指向的位置,从查询结果集的特定的一列取回数据(9) SQLFreeStmt 释放与语句句柄相关的资源(10) SQLDisconnect 切断连接(11) SQLFreeConnect 释
4、放与连接句柄相关的资源(12) SQLFreeEnv 释放与环境句柄相关的资源1.4实验环境 Mysql 8.0版本数据库 VS2015c+编程环境 Window8操作系统 ODBC 5.3版本数据库连接接口1.5实验步骤资源配置1.5.1环境配置ODBC下载可以在官网下载odbc驱动,注意32位与64位区别,相关bug将在下面提到。1.5.2环境配置数据源配置1. 打开控制面板,找到管理工具2.找到ODBC数据源,这里我用的是32位数据源。(因为我之前用的是ODBC8.0版本64位的,在VS测试中连接失败,就换用了32位5.3版本)3. 在用户dsn中添加相应数据源,这里点击添加按钮4. 找
5、到我们安装的ODBC相关驱动程序,我安装的是5.3版本,选择相应驱动5. 这里需要填写对应的要连接的数据库信息, Data Sourse Name任意命名都可以,TCP Server使用本地,User是数据库用户的名称(可以打开workbench找到),Password是用户对应密码,Database会自动检测出该用户建立的数据库,我们只需要进行相应选择。6. 填写好之后可以点击Test按钮测试是否可以成功连接。如果不可以,就需要检查一下说数据库信息是否填写正确。1.5.3环境配置ODBC和MYSQL选择上面可能出现的bug本次试验中这个问题困扰了我好久,起初我采用ODBC8.0和mysql8
6、.0,由于都是64位,在VS中产生了DSN匹配错误,因此只能使用32位的低版本ODBC5.3。但是在使用时发现ODBC5.3版本不能识别MYSQL8.0版本数据库,在添加数据源中检测不到数据库。折腾了3个小时终于找到了问题所在,即8.0版本可之前版本的密码检测方式不同,因此在网上找到了相应的解决方法(修改数据库加密规则)。在MYSQL命令行中执行下列语句:ALTER USER rootlocalhost IDENTIFIED BY password PASSWORD EXPIRE NEVER; #修改加密规则 ALTER USER rootlocalhost IDENTIFIED WITH m
7、ysql_native_password BY password; #更新一下用户的密码 FLUSH PRIVILEGES; #刷新权限再重置下密码:alter user rootlocalhost identified by 123qwe;最终,终于使得5.3版本可以成功连接8.0的mysql数据库了。1.5.4环境配置VS属性设置1.字符集设置,将字符集的Unicode变为多字符集2.资源库导入3.Lib文件包的导入4.Libmysql.lib写入1.6实验步骤代码分析1.6.1SC存储结构struct Stu_Course char sno6; char cno4; int grade;
8、1.6.2实验语句char table_command4100 = select * from sc where sno=30201;, /查询 INSERT INTO sc VALUE(30201,C01,80);, /插入 update sc set grade=80 where sno=30201 and cno=C03;, /修改 delete from sc where sno=30201& cno=C01;/删除1.6.3初始化ODBC,获取ODBC环境句柄HENV hEnv;SQLRETURN rEturn;/ 初始化ODBC环境,返回环境句柄rEturn = :SQLAlloc
9、Env(&hEnv);1.6.4与数据源ODBC建立连接1.分配连接句柄/ 分配连接句柄 rEturn = :SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc); if (rEturn = SQL_SUCCESS) cout 连接句柄分配成功! endl; else cout 连接句柄分配失败! endl; return -1; 2.连接数据源 /连接数据源 rEturn = :SQLConnect(hDbc, (SQLCHAR*)Dsn, SQL_NTS, (SQLCHAR*)userId, SQL_NTS, (SQLCHAR*)userPw, SQL_N
10、TS); if (rEturn = SQL_SUCCESS) cout 数据源连接成功! endl; else cout 数据源连接失败! endl; return -1; 1.6.5释放连接资源在应用程序完成数据库操作,退出运行之前,必须释放程序中使用的系统资源。这些系统资源包括:语句句柄、连接句柄和ODBC环境句柄。 完成这个过程的步骤如下: 1.调用SQLFreeStmt 函数释放语句句柄及其相关的系统资源。 SQLFreeStmt(hstmt, SQL_DROP); /释放与语句句柄相关的资源 2.调用SQLFreeConnect 函数释放连接句柄及其相关的系统资源。 SQLFreeC
11、onnect(hdbc); /释放与连接句柄相关的资源 3.调用SQLFreeEnv 函数释放环境句柄及其相关的系统资源,停止ODBC 操作。 SQLFreeEnv(env); /释放与环境句柄相关的资源1.7实验步骤结果分析1.7.1执行查询操作Mysql代码:select * from sc where sno=30201; 功能:查询SC表中学号为30201的学生的选课情况1.7.2Mysql代码:INSERT INTO sc VALUE(30201,C01,80);功能:在学号为30201的学生的选课中添加课程号为C01的课程,并令其成绩为80分。1.7.3Mysql代码:update
12、 sc set grade=80 where sno=30201 and cno=C03;功能:将学号为30201学号的学生的课程号为C03的选课成绩改为80分。1.7.4Mysql代码:delete from sc where sno=30201and cno=C01;功能:将学号为30201的学生的课程号为C01 的选课删除。 1.8实验源代码#include #include #include #include #include #include #include #include #include using namespace std;/定义ODBC连接的数据源信息#define D
13、SN rxk.test#define ID root#define PS ru072312/命令mysql代码char table_command4100 = select * from sc where sno=30201;, /查询 INSERT INTO sc VALUE(30201,C01,80);, /插入 update sc set grade=80 where sno=30201 and cno=C03;,/修改 delete from sc where sno=30201 and cno=C01;/删除/SC存储结构struct Stu_Course char sno6; ch
14、ar cno4; int grade;void query_table(SQLHDBC hDbc); /查询表void insert_table(SQLHDBC hDbc); /插入表void modify_table(SQLHDBC hDbc); /修改表项void delete_table(SQLHDBC hDbc); /删除表项int main(void) char Dsn10 = DSN, userId5 = ID, userPw13 = PS; /连接信息 HENV hEnv; SQLHDBC hDbc; SQLRETURN rEturn; / 初始化ODBC环境,返回环境句柄 rE
15、turn = :SQLAllocEnv(&hEnv); if (rEturn = SQL_SUCCESS) cout 环境句柄创建成功! endl; else cout 环境句柄创建失败! endl; return -1; / 分配连接句柄 rEturn = :SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc); if (rEturn = SQL_SUCCESS) cout 连接句柄分配成功! endl; else cout 连接句柄分配失败! endl; return -1; /连接数据源 rEturn = :SQLConnect(hDbc, (SQLCH
16、AR*)Dsn, SQL_NTS, (SQLCHAR*)userId, SQL_NTS, (SQLCHAR*)userPw, SQL_NTS); if (rEturn = SQL_SUCCESS) cout 数据源连接成功! endl; else cout 数据源连接失败! endl; return -1; int op = 0; /选择操作类型 bool flag = true; /判断是否退出 while (flag) cout *请选择服务项目* endl; cout 1.查询sc数据库 2.插入数据库 3.修改数据库 4.删除数据 5.退出 op; switch (op) case 1
17、: cout 查询sc数据库 endl; query_table(hDbc); break; case 2: cout 插入数据库 endl; insert_table(hDbc); query_table(hDbc); break; case 3: cout 修改数据库 endl; modify_table(hDbc); query_table(hDbc); case 4: cout 删除数据 endl; delete_table(hDbc);query_table(hDbc); break; case 5: cout 退出 endl; flag = false; break; defaul
18、t: cout 无效命令 endl; break; if (SQLFreeConnect(hDbc) = SQL_SUCCESS) cout 释放连接句柄资源成功! endl; if (SQLFreeEnv(hEnv) = SQL_SUCCESS) cout 释放环境句柄资源成功! sno, 6, &len1); SQLBindCol(hstmt, 2, SQL_C_CHAR, aSC-cno, 4, &len2); SQLBindCol(hstmt, 3, SQL_C_SLONG, &aSC-grade, 3, &len3); retcode = SQLExecDirect(hstmt, (
19、SQLCHAR*)table_command0, SQL_NTS);/查询操作执行 if (retcode = SQL_SUCCESS | retcode = SQL_SUCCESS_WITH_INFO) cout 学号 课程名 成绩 endl; retcode = SQLFetch(hstmt); /依次取出缓冲区的内容 while (retcode = SQL_SUCCESS | retcode = SQL_SUCCESS_WITH_INFO) cout sno cno grade endl; retcode = SQLFetch(hstmt); else cout 选择语句执行失败 en
20、dl; else cout 句柄内存分配失败 endl; /释放资源 SQLFreeStmt(hstmt, SQL_DROP); free(aSC);void insert_table(SQLHDBC hDbc) HSTMT hstmt; RETCODE retcode; retcode = SQLAllocStmt(hDbc, &hstmt);/语句句柄分配 if (retcode = SQL_SUCCESS | retcode = SQL_SUCCESS_WITH_INFO) /执行mysql插入操作 retcode = SQLExecDirect(hstmt, (SQLCHAR*)tab
21、le_command1, SQL_NTS); if (retcode = SQL_SUCCESS | retcode = SQL_SUCCESS_WITH_INFO) cout 执行插入语句成功 endl; else cout 插入语句执行失败 endl; else cout 句柄内存分配失败 endl; /释放资源 SQLFreeStmt(hstmt, SQL_DROP);void modify_table(SQLHDBC hDbc) HSTMT hstmt; RETCODE retcode; retcode = SQLAllocStmt(hDbc, &hstmt);/语句句柄分配 if (
22、retcode = SQL_SUCCESS | retcode = SQL_SUCCESS_WITH_INFO) /执行mysql修改操作 retcode = SQLExecDirect(hstmt, (SQLCHAR*)table_command2, SQL_NTS); if (retcode = SQL_SUCCESS | retcode = SQL_SUCCESS_WITH_INFO) cout 修改语句执行成功 endl; else cout 修改语句执行失败 endl; else cout 句柄内存分配失败 endl; /释放资源 SQLFreeStmt(hstmt, SQL_DRO
23、P);void delete_table(SQLHDBC hDbc) HSTMT hstmt; RETCODE retcode; retcode = SQLAllocStmt(hDbc, &hstmt);/语句句柄分配 if (retcode = SQL_SUCCESS | retcode = SQL_SUCCESS_WITH_INFO) /执行mysql删除操作 retcode = SQLExecDirect(hstmt, (SQLCHAR*)table_command3, SQL_NTS); if (retcode = SQL_SUCCESS | retcode = SQL_SUCCESS
24、_WITH_INFO) cout 删除语句执行成功 endl; else cout 删除语句执行失败 endl; else cout 句柄内存分配失败 endl; /释放资源 SQLFreeStmt(hstmt, SQL_DROP);1.9实验总结本次实验在配置环境的时候让我更进一步的了解到了数据库的一些内部情况,和内部命令的使用,例如更改加密规则、更新权限、重置密码等。同时也让我对32位和64位的区别有了一定的了解,同时也有了一定的谨慎,一旦出错很难被发现。本次实验过程:首先创建了ODBC数据源,与数据库进行连接,然后进行代码编写:1.初始化ODBC,获取ODBC环境句柄2.与ODBC数据源建立连接3.通过连接向ODBC数据库提交SQL语句,实现存取数据4.结束应用程序,释放连接需要提交的SQL语句实现存放在数组中,在第三步通过语句句柄提交执行,也可以仅分配内存空间,输入sql语句,再执行。通过这次实验,我了解了数据库应用编程接口ODBC的基本原理和实现机制,并对MySQL中的ODBC的使用和ODBC接口的语法和函数等有了进一步的了解。还通过在VS中编写C语言程序实现简单的数据库应用程序,较好地掌握基于ODBC的数据库访问的基本原理和方法,在实践中较好的掌握ODBC相关知识。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1