
实验目的
1.通过实验了解通用数据库应用编程接口ODBC的基本原理和实现机制,熟悉主要的ODBC接口的语法和使用方法;
2.利用C语言(或其它支持ODBC接口的高级程序设计语言)编程实现简单的数据库应用程序,掌握基于ODBC的数据库访问的基本原理和方法
3.学习java语言,并采用jdbc接口方式对数据库进行访问
实验内容与步骤
1、 以教科书第四章关于SQL语言相关内容为基础,课后查阅、自学ODBC接口有关内容,包括ODBC的体系结构、工作原理、数据访问过程、主要API接口的语法和使用方法等。
2、以实验二建立的学生数据库为基础,编写 C语言(或其它支持ODBC接口的高级程序设计语言) 数据库应用程序,按照如下步骤访问数据库
(a)Step1. ODBC初始化,为ODBC分配环境句柄
(b)Step2. 建立应用程序与ODBC数据源的连接
(c)Step3. 利用SQLExecDirect语句,实现数据库应用程序对数据库的建立、查询、修改、删除等操作
(d)Step4. 检索查询结果集
(e)Step5. 结束数据库应用程序
3、要求所编写的数据库访问应用程序中使用到以下主要的ODBC API函数:
(1)SQLALLocEnv:初始化ODBC环境,返回环境句柄
(2)SQLALLocConnect:为连接句柄分配内存并返回连接句柄
(3)SQLConnect:连接一个SQL数据资源
(4) SQLDriverConnect
连接一个SQL数据资源,允许驱动器向用户询问信息
(5) SQLALLocStmt
为语句句柄分配内存, 并返回语句句柄
(6) SQLExecDirect
把SQL语句送到数据库服务器,请求执行由SQL语句定义的数据库访问
(7) SQLFetchAdvances
将游标移动到到查询结果集的下一行(或第一行)
(8) SQLGetData
按照游标指向的位置,从查询结果集的特定的一列取回数据
(9) SQLFreeStmt
释放与语句句柄相关的资源
(10) SQLDisconnect
切断连接
(11) SQLFreeConnect
释放与连接句柄相关的资源
(12) SQLFreeEnv
释放与环境句柄相关的资源
创建ODBC数据源:
#include #include #include #include "sql.h" #include "sqltypes.h" #include "sqlext.h" RETCODE retcode;//结果返回集 SQLHDBC hdbc;//定义链接句柄 void print();//打印子程序 void SQL(unsigned char[]);//执行SQL语句子程序 int main(){ SQLHANDLE henv; //定义环境句柄 unsigned char SY[]="experiment2";//ODBC数据源名称 unsigned char db2[]="localhost";//用户名 unsigned char pass[]=" ";//密码 //分配ODBC环境 retcode=SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); if(retcode==SQL_SUCCESS||retcode==SQL_SUCCESS_WITH_INFO) //声明环境 retcode=SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3, 0); if(retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); //分配连接句柄 if(retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) retcode=SQLConnect(hdbc,SY,SQL_NTS,db2,SQL_NTS,pass,SQL_NTS);//链接 if(retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){ print(); unsigned char insert[]="insert into dbo.course values('C08','计算机网络','51','3','秋')"; SQL(insert); print(); unsigned char update[]="update dbo.course set credit=100 where course_name='计算机网络'"; SQL(update); print(); unsigned char del[]="delete from dbo.course where course_name='计算机网络'"; SQL(del); print(); } SQLFreeConnect(hdbc); ////释放链接句柄 SQLFreeEnv(henv); // 释放ODBC 环境句柄 system("pause"); return 0; } void print() { unsigned char yuju[]="select * from dbo.course"; SQLHSTMT hstmt;//定义语句句柄 char L1[20];char L2[20];char L3[20];char L4[20];char L5[20]; long lenOut1,lenOut2,lenOut3,lenOut4,lenOut5; retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); //分配语句句柄 if(retcode==SQL_SUCCESS) { retcode=SQLExecDirect(hstmt,yuju,SQL_NTS); if(retcode == SQL_SUCCESS||retcode == SQL_SUCCESS_WITH_INFO) { //将结果集中的属性列一一绑定至变量 retcode=SQLBindCol(hstmt,1,SQL_C_CHAR,L1,sizeof(L1),&lenOut1); retcode=SQLBindCol(hstmt,2,SQL_C_CHAR,L2,sizeof(L2),&lenOut2); retcode=SQLBindCol(hstmt,3,SQL_C_CHAR,L3,sizeof(L3),&lenOut3); retcode=SQLBindCol(hstmt,4,SQL_C_CHAR,L4,sizeof(L4),&lenOut4); retcode=SQLBindCol(hstmt,5,SQL_C_CHAR,L5,sizeof(L5),&lenOut5); //把所有捆绑过的数据字段的数据拷贝到相应的缓冲区 retcode=SQLFetch(hstmt); while(retcode == SQL_SUCCESS||retcode == SQL_SUCCESS_WITH_INFO) { printf("%s\%s\%s\%s\%s\\n",L1,L2,L3,L4,L5); //把所有捆绑过的数据字段的数据拷贝到相应的缓冲区 retcode=SQLFetch(hstmt); } } } SQLFreeStmt(hstmt,SQL_DROP); } void SQL(unsigned char aaa[]){ printf("\\n%s\\n",aaa); SQLHSTMT hstmt;//定义语句句柄 retcode=SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); //分配语义句柄 if(retcode==SQL_SUCCESS){ retcode=SQLExecDirect(hstmt,aaa,SQL_NTS); } SQLFreeStmt(hstmt,SQL_DROP); //释放语句句柄 } 实验结果: 1、插入一条记录: 2、更新一条记录 3、删除一条记录: 实验总结: 1、首先的问题是熟悉ODBC是什么:一个基于ODBC的应用程序对数据库的操作不依赖任何DBMS,不直接与DBMS打交道,所有的数据库操作由对应的DBMS的ODBC驱动程序完成。由此可见,ODBC的最大优点是能以统一的方式处理所有的数据库。ODBC 使用层次的方法来管理数据库,在数据库通信结构的每一层,对可能出现依赖数据库产品自身特性的地方,ODBC 都引入一个公共接口以解决潜在的不一致性,从而很好地解决了基于数据库系统应用程序的相对性。 2、在建立ODBC数据源的时候出了一些问题,测试不成功,后来把Server改成和数据库连接时的服务器相同,默认数据库是我要用的数据库时才可以测试成功。 3、在编写代码时查了各个用到的ODBC API的用法,也参考了一些网上基于ODBC访问数据库的方法和代码。
