ODBC是一个函数级接口标准,它为C/C++、BASIC等高级程序设计语言开发应用程序提供了访问各种数据源的统一标准。
一、ODBC的基本概念
1、 什么是ODBC
开放式数据库互连(Open Database Connectivity,ODBC)是微软公司开放服务体系中有关数据库的一个组成部分,它建立了一组规范并提供一组访问数据库的标准API。ODBC提供了设计、开发独立于DBMS的应用能力。应用程序可以利用SQL来完成其大部分数据库访问任务,有助于实现应用程序和数据库的分离。提高应用系统的数据访问透明性和可移植性。
2、 ODBC的结构
ODBC通过驱动程序提供数据独立性。驱动程序与具体的数据库有关,但基于ODBC的应用程序对数据库的操作不依赖于任何DBMS,也不直接与DBMS交互,所有的数据库操作由对应数据库服务器的ODBC驱动程序完成。也就是说,不论何种数据库,均可以通过ODBC API进行访问。
用户应用程序 ODBC API 驱动程序 管理器 ODBC Driver Manager 驱动程序 Driver1 Driver2 Driver2 ODBC Access SQL Server 其他数据库 图10.1 VB应用程序和底层数据库的关系 (1)应用程序 (Application):定义了系统的应用逻辑,负责和用户的交互管理,它调用ODBC函数向数据库库服务器提交数据访问请求,获取结果并返回给用户。
(2)ODBC 管理器 (ODBC manager),它为应用程序加载和调用ODBC驱动程序,负责应用程序和驱动程序的交互控制。但应用程序需要执行ODBC函数时,它会根据应用程序提供的连接数据源找到它相应的驱动程序,并将驱动程序中同名的函数和应用程序绑定。
ODBC管理器由Microsoft提供,该程序位于WINDOWS控制面板的32位ODBC内,包含在 ODBC32.dll中,对用户是透明的。主要任务是管理ODBC的驱动程序和数据源。
(3)ODBC 驱动程序(ODBC Drivers),它是一些DLL,提供 ODBC32和数据库之间的接口。应用程序最终调用驱动程序提供的函数操作数据库。在一个程序内要操作不同类型的数据库需要加载不同的ODBC 驱动程序。
驱动程序完成数据库访问请求的提交和结果集接收,应用程序使用驱动程序提供的结果集管理接口操纵执行后的结果数据。
Microsoft随他们的产品提供了好几种。并且你总可从数据库提供商那里获得新的ODBC 驱动程序。只要简单地安装新的ODBC驱动程序,你的机器就可使用新的它以前不知道的数据库。
(4)数据源 (Data SourcES,数据库):包含数据库的位置和数据库类型等信息,实际上是一种数据连接的抽象。
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:用来分配环境句柄。例如:
Dim rc As Integer 'ODBC函数的返回码 Dim henv As Long 'ODBC环境句柄 rc = SQLAllocEnv(henv) '获取ODBC环境句柄
(2) 分配连接句柄
SQLAllocConnect:用来分配连接句柄。连接句柄提供对一些信息的访问,例如,在连接上的有效语句及标识符句柄,以及当前是否打开一些一个事务处理。调用SQLAllocConnect 函 数 获 取 连 接 句 柄。例如: Dim hdbc As Long '连接句柄
rc = SQLAllocConnect(henv, hdbc) '获取连接句柄
(3) 建立数据源
使用已分配的连接句柄来建立应用程序和数据源/数据库系统的连接,进行句柄和数据源的绑定。绑定也由目标数据源的ODBC驱动程序完成。
建立的连接方式有三种: SQLConnect、SQLDriverConnect 和SQLDriverConnect
SQLConnect:最简单的方式 例 如:
Dim DSN As String, UID As String, PWD As String DSN = \"DataSourceName\" 'ODBC数据源名称
UID = \"UserID\" '用户帐号 PWD = \"Password\" '用户口令
rc = SQLConnect(hdbc, DSN, Len(DSN), UID,Len(UID), PWD, Len(PWD)) '建立连接
其中:hdbc,已经分配的连接句柄,DSN 、UID和 PWD分别是数据源、用户名和用户密码。
SQLDriverConnect
交互式连接的方法。应用程序根据驱动程序的规格说明为参数inconnectionstring
SQLDriverConnect:可以多次调用以创建到数据源的有效ODBC连接。 (4) 分配语句句柄
用户对DBC数据源的存取操作,都是通过SQL语句实现的。在这个过程中,应用程序 将通过连接向ODBC数据库提交SQL语句,以完成用户请求的操作。即通过执行SQLAllocHandle或SQLAllocStmt来分配语句句柄。调用SQLAllocStmt 函数获取语句句柄。例如:
Dim hstmt As Long
rc = SQLAllocStmt(hdbc, hstmt) (5) 执行SQL语句
执行SQL语句。 执行SQL 语 句 的方法比较多, 最简单明了的方法是调用SQLAllocStmt 函数,例如: Dim SQLstmt As String
SQLstmt = \"SELECT * FROM authors\"
rc = SQLExecDirect(hstmt, SQLstmt, Len(SQLstmt))
如果SQL语句被顺利提交并正确执行, 那么就会产生一个结果集。检索结果集的方法有很多,最简单最直接的方法是调用SQLFetch 和SQLGetData 函 数。
SQLFetch函数的功能是将结果集的当前记录指针移至下一个记录; SQLGetData 函数的功能是提取结果集中当前记录的某个字段值。通常可以采用一个循环以提取结果集中所有记录的所有字段值,该循环重复执行SQLFetch
和
SQLGetData
函数,直至
SQLFetch
函数返回
SQL_NO_DATA_FOUND, 这表示已经到达结果集的末尾。
Dim ColVal As String * 225 ColVal = String(255, 0)
Do Until SQLFetch(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。
一般来讲,在每次调用ODBC API 函 数 之 后, 都应该检查该函数返回值, 确定该函数是否成功地执行,再决定是否继续后续过程。 而详细的错误信息,可以调用SQLError 函数获得。SQLError 函数将返回下列信息: 标准的ODBC错误状态码 ODBC 数据源提供的内部错误编码错误信息串
以下是ODBC的API( 加入模块文件module1.bas)
Declare Function SQLAllocEnv Lib \" odbc32.dll\" (phenv&) As Integer
Declare Function SQLAllocConnect Lib \"odbc32.dll\" (ByVal henv&, phdbc&) As Integer Declare Function SQLAllocStmt Lib \"odbc32.dll\" (ByVal hdbc&, phstmt&) As Integer Declare Function SQLConnect Lib \"odbc32.dll\" (ByVal hdbc&, ByVal szDSN$, ByVal
cbDSN%, ByVal szUID$, ByVal cbUID%,ByVal szAuthStr$, ByVal cbAuthStr%) As Integer Declare Function SQLColAttributesString Lib \" odbc32.dll\" Alias \"SQLColAttributes\" (ByVal hstmt&, ByVal icol%, ByVal fDescType%,ByVal rgbDesc As String, ByVal cbDescMax%, pcbDesc%, pfDesc&) As Integer
Declare Function SQLDisconnect Lib \" odbc32.dll\" (ByVal hdbc&) As Integer,eclare Function SQLExecDirect Lib \"odbc32.dll\" (ByVal hstmt&, ByVal szSqlStr$, ByVal cbSqlStr&) As Integer
Declare Function SQLFetch Lib \"odbc32.dll\" (ByVal hstmt&) As Integer Declare Function SQLFreeConnect Lib \"odbc32.dll\" (ByVal hdbc&) As Integer Declare Function SQLFreeEnv Lib \"odbc32.dll\" (ByVal henv&) As Integer
Declare Function SQLFreeStmt Lib \"odbc32.dll\" (ByVal hstmt&, ByVal fOption%) As Integer
Declare Function SQLGetData Lib \"odbc32.dll\" (ByVal hstmt&, ByVal icol%,ByVal fCType%, ByVal rgbValue As String, ByVal cbValueMax&, pcbValue&) As IntegerDeclare Function SQLNumResultCols Lib \"odbc32.dll\" (ByVal hstmt&, pccol%) As Integer
Global Const SQL_C_CHAR As Long = 1 Global Const SQL_COLUMN_LABEL As Long = 18 Global Const SQL_DROP As Long = 1 Global Const SQL_ERROR As Long = -1
Global Const SQL_NO_DATA_FOUND As Long = 100 Global Const SQL_SUCCESS As Long = 0
二、ODBC环境配置
1. 打开ODBC数据源管理器面板。 在windows 2000打开控制面板,再打开管理工具,你就能看到数据源(ODBC)这一项了,对windows9x来讲,则直接在控制面板中就可以看到。
2. 双击图标打开管理器,再选择 系统DSN ,我们的数据源是在这里添加的 3. 添加数据源。点击添加按钮,开始创建数据源,在接下来的对话框中选择数据源的驱动程序,
三、简单应用实例
本实例将编制一个客户机端VB 应用程序, 通过Windows NT 局域网查询服务器端MS SQL Server 2000 样板数据库PUBS中的AUTHORS 数 据 表, 并在一个Grid 控件中显示查询结果。
首先,使用Windows 控制面板中的ODBC 驱动管理器新建一个ODBC数据源,定义数据源名称为ODBC_API_DEMO,定义登录数据库为PUBS, 其它 信息应根据用户的环境正确设置。 然后,启动VB,新建一个项目Project1,在 缺省窗体Form1 中加入一个Grid 控件Grid1、 两个CommandButton 控件cmdQuery 和cmdClose, 在Project1 中 插 入一个模块Module1, 将前面列举API声明语句加入其中。 程序代码如下:
Private Sub Form_Load() Dim rc As Integer
rc = SQLAllocEnv(henv) If rc =0 Then
MsgBox \"无法初始化ODBC\" End End If
rc = SQLAllocConnect(henv, hdbc) If rc =0 Then
MsgBox \"无法获得连接句柄\" rc = SQLFreeEnv(henv) End End If
Dim DSN As String, UID As String, PWD As String DSN = \"ODBC_API_DEMO\" UID = \"guest\" PWD = \"\"
rc = SQLConnect(hdbc, DSN, Len(DSN), UID, Len(UID), PWD, Len(UID)) If rc = SQL_ERROR Then
MsgBox \"无法建立与ODBC数据源的连接\" End End If End Sub
Private Sub cmdQuery_Click() Dim hstmt As Long Dim SQLstmt As String
Dim RSCols As Integer, RSRows As Long
Dim rc As Integer, i As Integer, j As Integer Dim ColVal As String * 1024
Dim ColValLen As Long, ColLabLen As Integer, larg As Long
rc = SQLAllocStmt(hdbc, hstmt) If rc SQL_SUCCESS Then
MsgBox \"无法获得SQL语句句柄\" Exit Sub End If
SQLstmt = \"SELECT * FROM authors\"
rc = SQLExecDirect(hstmt, SQLstmt, Len(SQLstmt)) If rc SQL_SUCCESS Then
MsgBox \"SQL语句执行失败\" Exit Sub End If
rc = SQLNumResultCols(hstmt, RSCols) If RSCols > 1 Then Grid1.Cols = RSCols Grid1.Rows = 10 Grid1.Row = 0 Else
Exit Sub End If
For i = 1 To RSCols
rc = SQLColAttributesString(hstmt, i, SQL_COLUMN_LABEL, ColVal, 255, ColLabLen, larg) Grid1.Col = i – 1
Grid1.Text = Left(ColVal, ColLabLen) Next i
Do Until SQLFetch(hstmt) = SQL_NO_DATA_FOUND ColVal = String$(1024, 0)
If Grid1.Row + 1 >= Grid1.Rows Then Grid1.Rows = Grid1.Rows + 1
End If
Grid1.Row = Grid1.Row + 1 For i = 1 To RSCols
rc = SQLGetData(hstmt, i, SQL_C_CHAR,ColVal, Len(ColVal), ColValLen) Grid1.Col = i – 1
Grid1.Text = Left$(ColVal, ColValLen) Next i Loop
rc = SQLFreeStmt(hstmt, SQL_DROP) End Sub
Private Sub cmdClose_Click() Dim rc As Integer If hdbc 0 Then
rc = SQLDisconnect(hdbc) End If
rc = SQLFreeConnect(hdbc) If henv 0 Then
rc = SQLFreeEnv(henv) End If End End Sub
因篇幅问题不能全部显示,请点此查看更多更全内容