ODBC编程.docx
《ODBC编程.docx》由会员分享,可在线阅读,更多相关《ODBC编程.docx(11页珍藏版)》请在冰豆网上搜索。
![ODBC编程.docx](https://file1.bdocx.com/fileroot1/2023-3/18/3878f45e-c7ee-4a0c-9eae-e05df4114bb3/3878f45e-c7ee-4a0c-9eae-e05df4114bb31.gif)
ODBC编程
ODBC编程的有关知识
ODBC是一个函数级接口标准,它为C/C++、BASIC等高级程序设计语言开发应用程序提供了访问各种数据源的统一标准。
一、ODBC的基本概念
1、 什么是ODBC
开放式数据库互连(OpenDatabaseConnectivity,ODBC)是微软公司开放服务体系中有关数据库的一个组成部分,它建立了一组规范并提供一组访问数据库的标准API。
ODBC提供了设计、开发独立于DBMS的应用能力。
应用程序可以利用SQL来完成其大部分数据库访问任务,有助于实现应用程序和数据库的分离。
提高应用系统的数据访问透明性和可移植性。
2、 ODBC的结构
ODBC通过驱动程序提供数据独立性。
驱动程序与具体的数据库有关,但基于ODBC的应用程序对数据库的操作不依赖于任何DBMS,也不直接与DBMS交互,所有的数据库操作由对应数据库服务器的ODBC驱动程序完成。
也就是说,不论何种数据库,均可以通过ODBCAPI进行访问。
驱动程序
管理器
驱动程序
图10.1 VB应用程序和底层数据库的关系
用户应用程序
ODBC API
ODBC DriverManager
ODBC Access SQLServer其他数据库
Driver1
Driver2
Driver2
(1)应用程序(Application):
定义了系统的应用逻辑,负责和用户的交互管理,它调用ODBC函数向数据库库服务器提交数据访问请求,获取结果并返回给用户。
(2)ODBC管理器(ODBCmanager),它为应用程序加载和调用ODBC驱动程序,负责应用程序和驱动程序的交互控制。
但应用程序需要执行ODBC函数时,它会根据应用程序提供的连接数据源找到它相应的驱动程序,并将驱动程序中同名的函数和应用程序绑定。
ODBC管理器由Microsoft提供,该程序位于WINDOWS控制面板的32位ODBC内,包含在ODBC32.dll中,对用户是透明的。
主要任务是管理ODBC的驱动程序和数据源。
(3)ODBC驱动程序(ODBCDrivers),它是一些DLL,提供ODBC32和数据库之间的接口。
应用程序最终调用驱动程序提供的函数操作数据库。
在一个程序内要操作不同类型的数据库需要加载不同的ODBC驱动程序。
驱动程序完成数据库访问请求的提交和结果集接收,应用程序使用驱动程序提供的结果集管理接口操纵执行后的结果数据。
Microsoft随他们的产品提供了好几种。
并且你总可从数据库提供商那里获得新的ODBC驱动程序。
只要简单地安装新的ODBC驱动程序,你的机器就可使用新的它以前不知道的数据库。
(4)数据源(DataSourcES,数据库):
包含数据库的位置和数据库类型等信息,实际上是一种数据连接的抽象。
3、ODBC句柄
应用程序运行后,为维护执行的状态,ODBC管理器和ODBC驱动程序中必须保持足够的控制信息。
应用程序要求ODBC管理器和ODBC驱动程序为ODBC环境、每个连接以及每个SQL语句分配描述/控制信息存储空间,并返回指向各个存储区的句柄供其使用。
(1)环境句柄:
整个ODBC上下文的根句柄。
标识全程数据访问控制信息的内存结构,包括有效连接句柄以及当前活动连接句柄。
ODBC将环境句柄定义为HENV类型的变量。
应用程序使用单一的环境句柄,在连接到数据源以前必须申请该句柄。
(2)连接句柄:
管理有关数据库会话的所有信息。
连接句柄标识每个特定的连接信息的内存结构。
ODBC将环境句柄定义为HDBC类型的变量。
应用程序在连接数据源之前申请连接句柄。
每个连接句柄与环境句柄有关,环境句柄上可以有多个与其有关的连接句柄。
(3)语句句柄:
ODBC语句包括应用访问数据源的SQL语句和语句相关的管理信息,语句句柄标识每个语句管理信息的内存结构。
ODBC将语句句柄定义为HSTMT类型的变量。
应用程序在提交SQL请求之前也必须申请语句句柄。
每个语句句柄与一个连接句柄有关,每个连接句柄上可以有多个与其有关的语句句柄。
4、执行流程
(1) 分配环境句柄
基于ODBC3.X版本的应用统一使用SQLAllocHandle来分配句柄。
调用时设计不同的句柄类型就可以获得该类型的句柄。
但在API内部实现上一般重新转换为执行SQLAllocEnv,SQLAllocConnect和SQLAllocStmt,这样可以达到兼容和代码重用作用。
SQLAllocEnv:
用来分配环境句柄。
例如:
DimrcAsInteger 'ODBC函数的返回码
DimhenvAsLong 'ODBC环境句柄
rc=SQLAllocEnv(henv) '获取ODBC环境句柄
(2) 分配连接句柄
SQLAllocConnect:
用来分配连接句柄。
连接句柄提供对一些信息的访问,例如,在连接上的有效语句及标识符句柄,以及当前是否打开一些一个事务处理。
调用SQLAllocConnect函数获取连接句柄。
例如:
Dim hdbc As Long'连接句柄
rc=SQLAllocConnect(henv,hdbc)'获取连接句柄
(3) 建立数据源
使用已分配的连接句柄来建立应用程序和数据源/数据库系统的连接,进行句柄和数据源的绑定。
绑定也由目标数据源的ODBC驱动程序完成。
建立的连接方式有三种:
SQLConnect、SQLDriverConnect和SQLDriverConnect
l SQLConnect:
最简单的方式
例如:
DimDSNAsString,UIDAsString,PWDAsString
DSN="DataSourceName"'ODBC数据源名称
UID="UserID"'用户帐号
PWD="Password"'用户口令
rc=SQLConnect(hdbc,DSN,Len(DSN),UID,Len(UID),PWD,Len(PWD))'建立连接
其中:
hdbc,已经分配的连接句柄,DSN、UID和PWD分别是数据源、用户名和用户密码。
l SQLDriverConnect
交互式连接的方法。
应用程序根据驱动程序的规格说明为参数inconnectionstring
l SQLDriverConnect:
可以多次调用以创建到数据源的有效ODBC连接。
(4) 分配语句句柄
用户对DBC数据源的存取操作,都是通过SQL语句实现的。
在这个过程中,应用程序将通过连接向ODBC数据库提交SQL语句,以完成用户请求的操作。
即通过执行SQLAllocHandle或SQLAllocStmt来分配语句句柄。
调用SQLAllocStmt函数获取语句句柄。
例如:
DimhstmtAsLong
rc=SQLAllocStmt(hdbc,hstmt)
(5) 执行SQL语句
执行SQL语句。
执行SQL语句的方法比较多,最简单明了的方法是调用SQLAllocStmt函数,例如:
DimSQLstmtAsString
SQLstmt="SELECT*FROMauthors"
rc=SQLExecDirect(hstmt,SQLstmt,Len(SQLstmt))
如果SQL语句被顺利提交并正确执行,那么就会产生一个结果集。
检索结果集的方法有很多,最简单最直接的方法是调用SQLFetch和SQLGetData函数。
SQLFetch函数的功能是将结果集的当前记录指针移至下一个记录;
SQLGetData函数的功能是提取结果集中当前记录的某个字段值。
通常可以采用一个循环以提取结果集中所有记录的所有字段值,该循环重复执行SQLFetch和SQLGetData函数,直至SQLFetch函数返回SQL_NO_DATA_FOUND,这表示已经到达结果集的末尾。
DimColValAsString*225
ColVal=String(255,0)
DoUntilSQLFetch(hstmt)=SQL_NO_DATA_FOUND
rc=SQLGetData(hstmt,i,SQL_C_CHAR,ColVal,Len(ColVal),SQL_NULL_DATA)
Loop
(6)结束应用程序
在应用程序完成数据库操作,退出运行之前,必须释放程序中使用的系统资源。
这些系统资源包括:
语句句柄、连接句柄和ODBC环境句柄。
完成这个过程的如下:
调用SQLFreeStmt函数释放语句句柄及其相关的系统资源。
例如:
rc=SQLFreeStmt(hstmt,SQL_DROP)
调用SQLDisconnect函数关闭连接。
例如:
rc=SQLDisconnect(hdbc)
调用SQLFreeConnect函数释放连接句柄及其相关的系统资源。
例如:
rc=SQLFreeConnect(hdbc)
调用SQLFreeEnv函数释放环境句柄及其相关的系统资源,停止ODBC操作。
例如:
rc=SQLFreeEnv(henv)
(7)错误处理
所有DBCAPI函数,若在执行期间发生错误,都将返回一个标准错误代码SQL_ERROR。
一般来讲,在每次调用ODBCAPI函数之后,都应该检查该函数返回值,确定该函数是否成功地执行,再决定是否继续后续过程。
而详细的错误信息,可以调用SQLError函数获得。
SQLError函数将返回下列信息:
标准的ODBC错误状态码ODBC数据源提供的内部错误编码错误信息串
以下是ODBC的API(加入模块文件module1.bas)
DeclareFunctionSQLAllocEnvLib"odbc32.dll"(phenv&)AsInteger
DeclareFunctionSQLAllocConnectLib"odbc32.dll"(ByValhenv&,phdbc&)AsInteger
DeclareFunctionSQLAllocStmtLib"odbc32.dll"(ByValhdbc&,phstmt&)AsInteger
DeclareFunctionSQLConnectLib"odbc32.dll"(ByValhdbc&,ByValszDSN$,ByValcbDSN%,ByValszUID$,ByValcbUID%,ByValszAuthStr$,ByValcbAuthStr%)AsInteger
DeclareFunctionSQLColAttributesStringLib"odbc32.dll"Alias"SQLColAttributes"(ByValhstmt&,ByValicol%,ByValfDescType%,ByValrgbDescAsString,ByValcbDescMax%,pcbDesc%,pfDesc&)AsInteger
DeclareFunctionSQLDisconnectLib"odbc32.dll"(ByValhdbc&)AsInteger,eclareFunctionSQLExecDirectLib"odbc32.dll"(ByValhstmt&,ByValszSqlStr$,ByValcbSqlStr&)AsInteger
DeclareFunctionSQLFetchLib"odbc32.dll"(ByValhstmt&)AsInteger
DeclareFunctionSQLFreeConnectLib"odbc32.dll"(ByValhdbc&)AsInteger
DeclareFunctionSQLFreeEnvLib"odbc32.dll"(ByValhenv&)AsInteger
DeclareFunctionSQLFreeStmtLib"odbc32.dll"(ByValhstmt&,ByValfOption%)AsInteger
DeclareFunctionSQLGetDataLib"odbc32.dll"(ByValhstmt&,ByValicol%,ByValfCType%,ByValrgbValueAsString,ByValcbValueMax&,pcbValue&)AsIntegerDeclareFunctionSQLNumResultColsLib"odbc32.dll"(ByValhstmt&,pccol%)AsInteger
GlobalConstSQL_C_CHARAsLong=1
GlobalConstSQL_COLUMN_LABELAsLong=18
GlobalConstSQL_DROPAsLong=1
GlobalConstSQL_ERRORAsLong=-1
GlobalConstSQL_NO_DATA_FOUNDAsLong=100
GlobalConstSQL_SUCCESSAsLong=0
二、ODBC环境配置
1. 打开ODBC数据源管理器面板。
在windows2000打开控制面板,再打开管理工具,你就能看到数据源(ODBC)这一项了,对windows9x来讲,则直接在控制面板中就可以看到。
2. 双击图标打开管理器,再选择系统DSN,我们的数据源是在这里添加的
3. 添加数据源。
点击添加按钮,开始创建数据源,在接下来的对话框中选择数据源的驱动程序,
三、简单应用实例
本实例将编制一个客户机端VB应用程序,通过WindowsNT局域网查询服务器端MSSQLServer2000样板数据库PUBS中的AUTHORS数据表,并在一个Grid控件中显示查询结果。
首先,使用Windows控制面板中的ODBC驱动管理器新建一个ODBC数据源,定义数据源名称为ODBC_API_DEMO,定义登录数据库为PUBS,其它信息应根据用户的环境正确设置。
然后,启动VB,新建一个项目Project1,在缺省窗体Form1中加入一个Grid控件Grid1、两个CommandButton控件cmdQuery和cmdClose,在Project1中插入一个模块Module1,将前面列举API声明语句加入其中。
程序代码如下:
PrivateSubForm_Load()
DimrcAsInteger
rc=SQLAllocEnv(henv)
Ifrc=0Then
MsgBox"无法初始化ODBC"
End
EndIf
rc=SQLAllocConnect(henv,hdbc)
Ifrc=0Then
MsgBox"无法获得连接句柄"
rc=SQLFreeEnv(henv)
End
EndIf
DimDSNAsString,UIDAsString,PWDAsString
DSN="ODBC_API_DEMO"
UID="guest"
PWD=""
rc=SQLConnect(hdbc,DSN,Len(DSN),UID,Len(UID),PWD,Len(UID))
Ifrc=SQL_ERRORThen
MsgBox"无法建立与ODBC数据源的连接"
End
EndIf
EndSub
PrivateSubcmdQuery_Click()
DimhstmtAsLong
DimSQLstmtAsString
DimRSColsAsInteger,RSRowsAsLong
DimrcAsInteger,iAsInteger,jAsInteger
DimColValAsString*1024
DimColValLenAsLong,ColLabLenAsInteger,largAsLong
rc=SQLAllocStmt(hdbc,hstmt)
IfrcSQL_SUCCESSThen
MsgBox"无法获得SQL语句句柄"
ExitSub
EndIf
SQLstmt="SELECT*FROMauthors"
rc=SQLExecDirect(hstmt,SQLstmt,Len(SQLstmt))
IfrcSQL_SUCCESSThen
MsgBox"SQL语句执行失败"
ExitSub
EndIf
rc=SQLNumResultCols(hstmt,RSCols)
IfRSCols>1Then
Grid1.Cols=RSCols
Grid1.Rows=10
Grid1.Row=0
Else
ExitSub
EndIf
Fori=1ToRSCols
rc=SQLColAttributesString(hstmt,i,SQL_COLUMN_LABEL,ColVal,255,ColLabLen,larg)
Grid1.Col=i–1
Grid1.Text=Left(ColVal,ColLabLen)
Nexti
DoUntilSQLFetch(hstmt)=SQL_NO_DATA_FOUND
ColVal=String$(1024,0)
IfGrid1.Row+1>=Grid1.RowsThen
Grid1.Rows=Grid1.Rows+1
EndIf
Grid1.Row=Grid1.Row+1
Fori=1ToRSCols
rc=SQLGetData(hstmt,i,SQL_C_CHAR,ColVal,Len(ColVal),ColValLen)
Grid1.Col=i–1
Grid1.Text=Left$(ColVal,ColValLen)
Nexti
Loop
rc=SQLFreeStmt(hstmt,SQL_DROP)
EndSub
PrivateSubcmdClose_Click()
DimrcAsInteger
Ifhdbc0Then
rc=SQLDisconnect(hdbc)
EndIf
rc=SQLFreeConnect(hdbc)
Ifhenv0Then
rc=SQLFreeEnv(henv)
EndIf
End
EndSub