访问数据库456.docx
《访问数据库456.docx》由会员分享,可在线阅读,更多相关《访问数据库456.docx(42页珍藏版)》请在冰豆网上搜索。
访问数据库456
实验五通过ODBC访问数据库
一、实验类别:
验证型实验
二、实验目的
掌握ODBC数据源的配置方法;熟练使用ODBC进行数据库应用程序的设计;熟悉通过ODBC接口访问数据库并对数据库进行操作。
三、实验内容
1.创建Access数据库和SQLserver数据库。
2.配置AccessODBC数据源和SQLserverODBC数据源。
3.通过ODBC接口将Access的student表中数据备份到SQLServer2000数据库。
四、实验平台
本实验要求在装有MicroSoftAccess和SQLserver2000数据库管理系统及VC++6.0开发工具的计算机上完成。
五、实验步骤及方法
1.建立Access数据文件student.mdb,并存放在E盘的根目录下;打开该文件(如图1所示),单击使用设计器设计表,在弹出的表单中设计student表的字段(如图2所示),注:
sno长度为30,sname长度为50,ssex长度为5;sDept长度为100;保存该表,并输入表名student;右键单击student;向该表中添加5条数据;
图8-1Access数据库
图8-2student表基本信息
2.在SQLserver2000中建立StudentDataBase数据库和student表,见图3;
3.为Access数据库添加ODBC数据源。
打开我的电脑->控制面板->管理工具->ODBC数据源->系统DSN,如图4所示;然后单击添加按钮,在弹出对话框中寻找DriverdoMicrosoftAccess(*mdb),选择这个条目,单击完成;在弹出对话框中,数据源名:
accessodbc;单击选择按钮;在弹出对话框中寻找刚刚创建的student.mdb,单击确定按钮;回到odbc数据源安装的对话框下选择确定;即返回如图4所示的对话框;注意:
如果计算机没有配置SQLserverODBC数据源,还要添加其ODBC数据源。
图8-3student表基本信息
图8-4ODBC数据源管理器对话框
4.配置SQLserverODBC数据源;首先要保证SQLServer服务开启;然后在图4所示的对话框中单击添加按钮,弹出对话框中找到SQLserver,单击完成;进入“创建到SQLserver新数据源”对话框:
输入信息如下:
名称:
LocalServer;服务器:
(local),单击下一步;选择“使用用户登录ID和密码的SQLserver验证”同时将“连接SQLserver以获取其他默认配置选项的默认配置”选中,输入本机SQL的用户名(sa)和密码(123),单击下一步;选中“更改默认数据库为”,并选择studentDataBase;并选中“使用ANSI引用的标识符”和“使用ANSI的空值、填充及警告,单击下一步;单击完成;单击测试数据源,如果成功,弹出图5所示对话框,说明SQLServer数据源配置成功。
图8-5SQLserver数据源测试
5.打开VC++6.0建立C++源文件输入以下代码:
//导入头文件
#include
#include
#include
#include
#include
#include
#include
//自定义宏
#defineSNO_LEN30
#defineNAME_LEN50
#defineDEPART_LEN100
#defineSEX_LEN5
intmain()
{
//step1:
定义句柄和变量
//以access开头的表示连接Access数据库的变量
//以server开头的表示连接SQLserver数据库的变量
SQLHENVaccesshenv,serverhenv;//定义环境句柄;
SQLHDBCaccesshdbc,serverhdbc;//定义连接句柄;
SQLHSTMTaccesshstmt,serverhstmt;//定义语句句柄;
SQLRETURNret;//定义结果返回集;
SQLCHARsName[NAME_LEN],sDepart[DEPART_LEN],sSex[SEX_LEN],sSno[SNO_LEN];//定义表中字段
SQLINTEGERsAge;
SQLINTEGERcbAge=0,cbSno=SQL_NTS,cbSex=SQL_NTS,cbName=SQL_NTS,cbDepart=SQL_NTS;
//step2:
初始化环境
//分配环境句柄
ret=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&accesshenv);
ret=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&serverhenv);
//设置管理环境的属性
ret=SQLSetEnvAttr(accesshenv,SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3,0);
ret=SQLSetEnvAttr(serverhenv,SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3,0);
//step3建立连接
//分配连接句柄
ret=SQLAllocHandle(SQL_HANDLE_DBC,accesshenv,&accesshdbc);
ret=SQLAllocHandle(SQL_HANDLE_DBC,serverhenv,&serverhdbc);
ret=SQLConnect(accesshdbc,(SQLCHAR*)"accessodbc",SQL_NTS,(SQLCHAR*)"",SQL_NTS,(SQLCHAR*)"",SQL_NTS);//access数据库没有用户名和密码,第二个参数必须是刚才创建access数据库的odbc数据源名
if(!
SQL_SUCCEEDED(ret)){
cout<<"未成功连接"<return-1;
}
else{
cout<<"成功连接"<}
ret=SQLConnect(serverhdbc,(SQLCHAR*)"LocalServer",SQL_NTS,(SQLCHAR*)"sa",SQL_NTS,(SQLCHAR*)"123",SQL_NTS);//sa为用户名,123为密码;需要改为自己的数据;第二个参数必须为SQLServer的odbc的数据源名
if(!
SQL_SUCCEEDED(ret)){
cout<<"未成功连接"<return-1;
}
else{
cout<<"成功连接"<}
//step4初始化语句句柄
ret=SQLAllocHandle(SQL_HANDLE_STMT,accesshdbc,&accesshstmt);
ret=SQLSetStmtAttr(accesshstmt,SQL_ATTR_ROW_BIND_TYPE,(SQLPOINTER)SQL_BIND_BY_COLUMN,SQL_IS_INTEGER);
ret=SQLAllocHandle(SQL_HANDLE_STMT,serverhdbc,&serverhstmt);
//step5两种方式执行语句
ret=SQLPrepare(serverhstmt,(SQLCHAR*)"insertintoSTUDENTVALUES(?
?
?
?
?
)",SQL_NTS);
if(ret==SQL_SUCCESS||ret==SQL_SUCCESS_WITH_INFO){
cout<<"成功"<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(accesshstmt,(SQLCHAR*)"select*fromstudent",SQL_NTS);
if(ret==SQL_SUCCESS||ret==SQL_SUCCESS_WITH_INFO){
cout<<"成功"<ret=SQLBindCol(accesshstmt,1,SQL_C_CHAR,sSno,SNO_LEN,&cbSno);
ret=SQLBindCol(accesshstmt,2,SQL_C_CHAR,sName,NAME_LEN,&cbName);
ret=SQLBindCol(accesshstmt,3,SQL_C_CHAR,sSex,SEX_LEN,&cbSex);
ret=SQLBindCol(accesshstmt,4,SQL_C_LONG,&sAge,0,&cbAge);
ret=SQLBindCol(accesshstmt,5,SQL_C_CHAR,sDepart,DEPART_LEN,&cbDepart);
}
//step6处理结果集并执行预编译后所得的语句
while((ret=SQLFetch(accesshstmt))!
=SQL_NO_DATA_FOUND){
if(ret==SQL_ERROR){
cout<<"出错了!
"<}
else{
ret=SQLExecute(serverhstmt);
if(ret==SQL_SUCCESS||ret==SQL_SUCCESS_WITH_INFO){
cout<<"成功插入数据"<}
else{
cout<<"无法插入数据"<}
}
}
SQLFreeHandle(SQL_HANDLE_STMT,accesshstmt);
SQLDisconnect(accesshdbc);
SQLFreeHandle(SQL_HANDLE_DBC,accesshdbc);
SQLFreeHandle(SQL_HANDLE_ENV,accesshenv);
SQLDisconnect(serverhdbc);
SQLFreeHandle(SQL_HANDLE_DBC,serverhdbc);
SQLFreeHandle(SQL_HANDLE_ENV,serverhenv);
return0;
}
6.调试程序,直至成功运行;如果成功运行,打开SQLserver查询分析器,切换至该数据库,查询Student表,会显示所有在Access中添加的数据。
(注意:
由于SQLserver数据库中设置了主码约束,当连续两次运行这个程序时,会报错,因此如果运行成功,需要清空Student表中的数据,这样再次运行时才能成功)
7.主要函数详解
(1)SQLRETURNSQLAllocHandle(SQLSMALLINThtype,SQLINTEGERihandle,SQLINTEGER*handle):
分配任何类型的句柄;此函数组合了函数SQLAllocEnv()、SQLAllocConnect()和SQLAllocStmt()。
返回码为:
SQL_SUCCESS,SQL_ERROR,SQL_INVALID_HANDLE,如果自变量handle是空指针,则返回SQL_ERROR。
此函数参数含义详见下表:
数据类型
形参名称
描述
SQLSMALLINT
htype
要分配的句柄的类型。
必须是SQL_HANDLE_ENV、SQL_HANDLE_DBC、SQL_HANDLE_DESC或SQL_HANDLE_STMT。
SQLINTEGER
ihandle
描述在其中分配新句柄的上下文的句柄;然而,如果htype是SQL_HANDLE_ENV,则这是SQL_NULL_HANDLE
SQLINTEGER
*handle
指向句柄的指针
(2)SQLRETURNSQLSetEnvAttr():
主要是设置环境句柄的某些属性,也就是设置连接数据库的方式,第一个参数是环境句柄,本程序采取ODBC访问数据库,因此第二个参数和第三个参数如代码所示;返回值同SQLAllocHandle函数;
(3)SQLRETURNSQLConnect():
是连接ODBC数据源的最基本的方法,在所有的一致性级别上都支持。
SQLConnect函数有以下函数:
连接句柄、数据源名称、数据源名称长度、用户名,用户名名称长度、用户口令和用户口令长度。
返回值同SQLAllocHandle函数。
(4)SQLRETURNSQLSetStmtAttr():
设置结果集大小,参数含义如下表:
语句属性
参数取值例
作用
SQL_ATTR_CURSOR_TYPE
SQL_CURSOR_FORWORD_ONLY
设置游标类型/
游标指针只能向前滚动
SQL_ATTR_ROW_BIND_TYPE
SQL_BIND_BY_COLUMN
设置结果集合列的绑定方向,采用列向绑定方式
SQL_ATTR_ROW_ARRAY_SIZE
设置行集尺寸,即SQLFetch或SQLFetchScroll函数一次返回的函数
SQL_ATTR_ROW_STATUS_PTR
指出一个状态数组,用于记录SQLFetch或SQLFetchScroll函数执行后与行集中每个数据行对应的状态信息
SQL_ATTR_ROW_FETCHED_PTR
用一个变量记录SQLFetch或SQLFetchScroll函数所读取的行数
(5)SQLRETURNSQLBindCol():
为ODBC驱动程序提供变量缓冲区,并设置变量数据存储类型。
形参名称及含义如下:
SQLHSTMTStatementHandle语句句柄
SQLSMALLINTColunmNumber,被绑定列在结果集中序号
SQLSMALLINTTargetType被绑定列C数据类型
SQLPOINTERTargetValuePtr输入输出参数
SQLINTEGERBufferLength说明缓冲区字节长度
SQLINTEGER*StrLen_or_IndPtr列长度指示缓冲区
返回值同上述函数;
(6)SQLRETURNSQLFetch(SQLSTMTStatementHandle):
提取结果集的下一行集数据,返回所有已绑定的列数据该函数将游标指针移到StatementHandle结果集合中下一行集的首行上,然后读取该行集中已关联列数据.
(7)SQLRETURNSQLBindParameter()参数含义:
StatementHandle语句句柄
ParameterNumber参数个数,由1开始。
这就是ODBC用来判断参数描述符的方法。
如果有三个参数,则最左边是第一个参数,最右边是第三个参数。
InputOutputType表明参数是用来输入还是输出的标志.这里的输入是指ODBC驱动程序将使用参数中获得的值,输出是指ODBC驱动程序将在操作结束时将结果放入参数中.大多数情况下,我们使用参数作为输入。
而输出参数经常与存储过程有关。
这个参数的两个可能值为:
SQL_PARAM_INPUT、SQL_PARAM_INPUT_OUTPUT和SQL_PARAM_OUTPUT.
ValueType指明用户程序将要绑定到参数的值或缓冲区的类型。
可能的类型为一组常数,以SQL_C_开头。
ParameterType参数的SQL类型。
例如,如果SQL参数是文本字段,在这里填入值SQL_CHAR.查看MSDN中的ODBC程序员指南来获得完整列表(ODBCProgrammer'sreference)。
ColumnSize参数的长度。
可认为是与参数标志符相连接的列(字段)的长度。
在例子中,参数标志符对列"name"使用了标准值。
如果该列被定义了20字节长,则在ColumnSize中填入20。
DecimalDigits与参数描述符连接的列的小数位。
ParameterValuePtr指向包含参数数据的缓冲区的指针。
BufferLength由ParameterValuePtr指向的缓冲区的长度。
pStrLenOrIndPtr指向一个双字的指针,包含以下之一:
由ParameterValuePtr指向的缓冲区中包含的参数长度。
除非参数的类型是字符串或二进制值,否则这个值被忽略。
不要把它与BufferLength混淆。
假设该参数是一个字符串,该列有20字节宽。
则分配了一个21字节长的缓冲区,并将其地址传送到ParameterValuePtr。
在调用函数SQLExecute前,在缓冲区中放入了字符串"Bob"。
这个字符串有3字节长,因此我们需要在pStrLenOrIndPtr指向的双字中放入3这个值。
SQL_NTS这个参数是一个0结尾字符串(null-terminatedstring)。
SQL_NULL_DATA参数值为NULL。
SQL_DEFAULT_PARAM存储过程将使用参数的默认值,而不是从用户程序中获得的值。
它仅适用于已定义了默认参数值的存储过程。
SQL_DATA_AT_EXEC参数的数据将由SQLPutData传送。
由于数据可能太大无法放入内存(比如整个文件的数据),在此可以告诉ODBC驱动程序将用SQLPutData替代。
实验六通过ADO访问数据库
一、实验类型
验证性实验
二、实验目的
掌握ADO访问数据库的技术
三、实验平台
本实验需要在装有VC++6.0和SQLServer2000的计算机上完成。
四、实验内容
使用ADO技术完成对学生表数据的增加、删除、修改与查询。
五、预备知识
ADO(ActiveXDataObjects)是一个用于存取数据源的COM组件。
它提供了编程语言和统一数据访问方式OLEDB的一个中间层。
下面简要介绍ADO常用属性及方法。
1、Connection对象
(1)属性
Attributes:
可读写Long类型,通过两个常数之和指定是否使用保留事务(retainningtransactions)。
常数adXactCommitRetaining表示调用CommitTrans方法时启动一个新事务;常数adXactAbortRetaning表示调用RollbackTrans方法时启动一个新事务。
默认值为0,表示不使用保留事务。
CommandTimeout:
可读写Long类型,指定中止某个相关Command对象的Execute调用之前必须等待的时间。
默认值为30秒。
ConnectionString:
可读写String类型,提供数据提供者或服务提供者打开到数据源的连接所需要的特定信息。
ConnectionTimeout:
可读写Long类型,指定中止一个失败的Connection.Open方法调用之前必须等待的时间,默认值为15秒。
CursorLocation:
可读写Long类型,确定是使用客户端(adUseClient)游标引擎,还是使用服务器端(adUseServer)游标引擎。
默认值是adUseServer。
(2)方法
BeginTrans:
初始化一个事务;其后必须有CommitTrans和/或RollbackTrans相呼应。
Close:
关闭连接
CommitTrans:
提交一个事务,以完成对数据源的永久改变(要求使用之前必须调用了BeginTrans方法)。
Execute:
SELECTSQL语句返回一个Recordset对象,也用来执行那些不返回Recordset语句,如INSERT、UPDATE、DELETE查询或DDL语句。
Open:
用连接字符串来打开一个连接。
2、Command对象
Command对象的主要目的是执行参数化的存储过程。
其形式要么是临时准备(prepared),要么是持久的预编译(precompiled)过的SQL语句。
(1)属性
ActiveConnection:
指针类型,指向Command所关联的Connection对象。
对于现存的已打开连接,可使用SetcmmName.ActiveConnection=cnnName。
另外,也可以不用相关Connection对象名称而使用有效的连接字符串去创建一个新的连接。
默认值为Null。
CommandText:
可读写String类型。
为ActiveConnection指定一条SQL语句、表名、存储过程名或提供者能接受的任意字符串。
CommandType属性的值决定了CommandText属性值的格式。
默认值为空字符串:
""
CommandTimeout:
可读写Long类型,指定中止一个Command.Execute调用之前必须等待的时间。
这时的值优先于Connection.ComandTimeout中的设定值。
默认值为30秒。
CommandType:
读写Long类型,指定数据提供者该如何解释CommandText属性值。
默认值为adCmdUnkown。
(2)方法
Createparameter在执行该方法之前,必须首先声明一个ADODB.Parameter对象。
调用语法为:
cmmName.CreateParameter[strName[,lngType[,lngDirection[,lngSize[,varValue]]]]]
Execute调用语法同Connection.Execute大致相同。
3、Recordset对象
(1)属性
ActiveCommand:
可读写的String类型,Recordset所关联的先前打开的Command对象名称。
ActiveConnection:
指针类型,指向Recordset所关联的先前打开的Connection对象,或指向一条完整有效的ConnectionString串值。
BOF*:
只读Boolean类型,若为True,表明记录指针已位于Recordset