实验四 数据接口实验
实验目的
1.通过实验了解通用数据库应用编程接口 ODBC 的基本原理和实现机制,熟悉主要的 ODBC
接口的语法和使用方法;
2.利用 C 语言(或其它支持 ODBC 接口的高级程序设计语言)编程实现简单的数据库应用程
序,掌握基于 ODBC 的数据库访问的基本原理和方法。
3.尝试使用 SQL Server 上的工具以特定格式导出数据,初步了解现代程序设计辅助工具的
使用,加深对接口和数据库与外界的联系的认识。
实验内容
本实验内容主要是如何通过数据库接口访问(包括增、删、改)数据库中的数据。
要求能够通过编写程序或者使用 SQL Server 工具访问到数据。该实验的重点在于 ODBC
数据源配置和工具使用,而不在于编写有一定复杂度的程序。
实验要求
1.要求所编写的数据库访问应用程序中使用到以下主要的 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
释放与环境句柄相关的资源
实验步骤
1. 实验准备:
(a) 以教科书第四章关于 SQL 语言相关内容为基础,课后查阅、自学 ODBC 接口有关
内容,包括 ODBC 的体系结构、工作原理、数据访问过程、主要 API 接口的语法
和使用方法等。
(b) 以实验二建立的数据库为基础,编写 C 语言(或其它支持 ODBC 接口的高级程序
设计语言) 数据库应用程序,按照如下步骤访问数据库
i.
ii.
iii.
Step1. ODBC 初始化,为 ODBC 分配环境句柄
Step2. 建立应用程序与 ODBC 数据源的连接
Step3. 利用 SQLExecDirect 语句,实现数据库应用程序对数据库中表(有数
据)进行数据查询、修改、删除、插入等操作。要求先打印出所有记录,然后
删除一行,再打印一次,进行修改,再打印一次,最后插入,再打印一次。
Step4. 结束数据库应用程序
iv.
由于我的数据库设置了主外键约束,DBMS 会拒绝破坏完整性约束的操作,为了直观
的演示操作效果,我先做的插入操作,然后是修改,最后是删除。
因为这不是程序设计练习,所以只针对一张表就可以了。我们也不要求做出很好的界面,
和允许用户选择如何操作数据,只要是完成基本功能就可以了。
实验代码:
#include
#include
#include
#include
#include
#include
SQLRETURN retcode; //结果返回集
SQLHDBC conn; //数据库连接句柄
SQLHSTMT stmt; //定义语句句柄
SQLHENV env; //环境参数变量
//打印整张表
void print() {
SQLCHAR sqlquery[] = "select * from class";
char class_id[10];
char moniter[10];
char classroom[20];
char department_id[20];
SQLINTEGER lenOut1, lenOut2, lenOut3, lenOut4;
retcode = SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt); //分配语句句柄
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
//发送命令到数据库
retcode = SQLExecDirect(stmt, sqlquery, SQL_NTS);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
//将结果集中的属性列绑定至变量
retcode = SQLBindCol(stmt, 1, SQL_C_CHAR, class_id, sizeof(class_id),
&lenOut1);
retcode = SQLBindCol(stmt, 2, SQL_C_CHAR, moniter, sizeof(moniter),
&lenOut2);
retcode = SQLBindCol(stmt, 3, SQL_C_CHAR, classroom, sizeof(classroom),
&lenOut3);
retcode = SQLBindCol(stmt, 4, SQL_C_CHAR,
department_id,sizeof(department_id), &lenOut4);
retcode = SQLFetch(stmt);
while (retcode != SQL_NO_DATA_FOUND) {//取回元组
printf("%s\t%s\t%s\t%s\n", class_id, moniter, classroom,
department_id);
retcode = SQLFetch(stmt);
}
}
}
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
//SQLFreeStmt(stmt, SQL_DROP);
}
//执行SQL语句
void SQL(SQLCHAR query[]) {
printf("***********************************\n\n");
printf("%s\n", query);
retcode = SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
//处理数据
retcode = SQLExecDirect(stmt, query, SQL_NTS);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
}
}
//SQLFreeStmt(stmt, SQL_DROP);
}
int main() {
//分配环境句柄
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
//设置环境属性
retcode = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
//分配连接句柄
retcode = SQLAllocHandle(SQL_HANDLE_DBC, env, &conn);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
//设置登陆超时时间为5s
SQLSetConnectAttr(conn, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
//连接
retcode = SQLDriverConnect(conn,NULL,(SQLCHAR*)"DRIVER={SQL
Server};SERVER=SARKAR\\SQLEXPRESS;DATABASE=学生选课;UID=nicholas;PWD=nicholas;",
SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
printf("Connected!\n");
print(); //打印所有
SQLCHAR insert[] = "insert into class values('g99501', '詹伟伟', '
教三3-239', 'dep_02')";
= 'g99501'";
SQL(insert);
print();
SQLCHAR update[] = "update class set monitor = '111' where class_id
SQL(update);
print();
SQLCHAR del[] = "delete from class where class_id = 'g99501'";
SQL(del);
print();
SQLFreeConnect(conn); //释放连接句柄
}
else printf("Connection error!!!");
}
SQLFreeHandle(SQL_HANDLE_DBC, conn);
}
}
SQLFreeEnv(env); //释放SQL环境句柄
system("pause");
return 0;
}
实验结果:
连接成功,打印整个 class 表:
插入数据(insert into class values('g99501', '詹伟伟', '教三 3-239', 'dep_02')):
更新数据(update class set monitor = '111' where class_id = 'g99501'):
删除数据(delete from class where class_id = 'g99501'):
2. 在 Windows 控制面板中通过管理工具下的 ODBC 数据源工具在客户端新建连接到 SQL
Server 服务器的 ODBC 数据源,测试通过后保存,注意名字要和应用程序中引用的数据
源一样。
1)选择驱动程序:
2)
3)
4)
4)