VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 用ODBC API访问ODBC数据库
发表评论(0)作者:, 平台:, 阅读:13076, 日期:2000-03-12


用ODBC API访问ODBC数据库



 

开放数据库互连(ODBC)已经成为Client /Server 数据

库应用系统中访问远程数据库的一个标准。做为强大

的前端开发工具,MS Visual Basic 为开发者提供了多种访

问ODBC 数据源的途径,如JET 数据库引擎、ODBC API 函数、RDO

接口等。比较而言,直接使用ODBC API 函数的编程难度最

大,但由此获得的存取数据库的性能也是最佳。诚然,

VB 4.0 企业版提供的RDO 接口的性能已经接近ODBC API,但

是遗憾的是,这个接口只能在32 位Windows 环境中运行,

而ODBC API 函数则没有这个限制。



ODBC API 函数的声明方法



与使用其它动态库函数一样,在VB 中使用ODBC API 函

数之前,必须事先声明将要使用的函数、常量和数据

结构。ODBC API 函数驻留在ODBC 运行动态库ODBC.DLL(16 位)

或ODBC32.DLL(32 位)中,该动态库位于Windows 子目录system

中。通常做法是在VB 项目中单独使用一个模块文件,然

后将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

Declare 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 Integer

Declare 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



需要说明的是,在函数声明时,应该根据程序的运

行环境选择相应的动态库。在VB 子目

录samples\remauto\db_odbc 中有两个正文文件ODBC16.TXT

和ODBC32.TXT,分别存有所有16 位和32 位ODBC API 函数、常量

和数据结构的声明语句,编程时可以从中拷贝所需的

声明语句。



使用ODBC API 的编程方法



在VB 中调用ODBC API 函数访问ODBC 数据库,代码编制一

般是按照下列过程进行的:



一、初始化ODBC



在这个过程中,应用程序将通过调用SQLAlloEnv 函数

初始化ODBC 接口,获取ODBC 环境句柄。ODBC 环境句柄是其

它所有ODBC 资源句柄的父句柄,因此无论程序将建立多

少个ODBC 连接,这个过程只需执行一次即可。例如:



Dim rc As Integer 'ODBC 函数的返回码

Dim henv As Long 'ODBC 环境句柄

rc = SQLAllocEnv(henv) ' 获取ODBC 环境句柄

二、与ODBC 数据源建立连接

这个过程由下列两个步骤组成:

1、调用SQLAllocConnect 函数获取连接句柄。例如:

Dim hdbc As Long ' 连接句柄

rc = SQLAllocConnect(henv, hdbc) ' 获取连接句柄

2、建立连接。这个步骤可以通过多种方法实现,

最简单直观的方法是调用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)) ' 建立连接



三、存取数据



用户对ODBC 数据源的存取操作,都是通过SQL 语句实

现的。在这个过程中,应用程序将通过连接向ODBC 数据

库提交SQL 语句,以完成用户请求的操作。具体步骤如

下:

1、调用SQLAllocStmt 函数获取语句句柄。例如:

Dim hstmt As Long

rc = SQLAllocStmt(hdbc, hstmt)

2、执行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



五、结束应用程序



在应用程序完成数据库操作,退出运行之前,必须

释放程序中使用的系统资源。这些系统资源包括:语

句句柄、连接句柄和ODBC 环境句柄。完成这个过程的步

骤如下:

1、调用SQLFreeStmt 函数释放语句句柄及其相关的系

统资源。例如:

rc = SQLFreeStmt(hstmt, SQL_DROP)

2、调用SQLDisconnect 函数关闭连接。例如:

rc = SQLDisconnect(hdbc)

3、调用SQLFreeConnect 函数释放连接句柄及其相关的

系统资源。例如:

rc = SQLFreeConnect(hdbc)

4、调用SQLFreeEnv 函数释放环境句柄及其相关的系

统资源,停止ODBC 操作。例如:

rc = SQLFreeEnv(henv)

此外,在编制程序时还有一个需要重点考虑的问

题,这就是错误处理。所有ODBC API 函数,若在执行期间

发生错误,都将返回一个标准错误代码SQL_ERROR。一般

来讲,在每次调用ODBC API 函数之后,都应该检查该函数

返回值,确定该函数是否成功地执行,再决定是否继

续后续过程。而详细的错误信息,可以调用SQLError 函数

获得。SQLError 函数将返回下列信息:

标准的ODBC 错误状态码

ODBC 数据源提供的内部错误编码

错误信息串


简单应用实例

本实例将编制一个客户机端VB 应用程序,通过

Windows NT 局域网查询服务器端MS SQL Server 6.5 样板数据

库PUBS 中的AUTHORS 数据表,并在一个Grid 控件中显示查询

结果。首先,使用Windows 控制面板中的ODBC 驱动管理器新

建一个ODBC 数据源,定义数据源名称为ODBC_API_DEMO,定义

登录数据库为PUBS,其它信息应根据用户的环境正确设

置。然后,启动VB,新建一个项目Project1,在缺省窗体

Form1 中加入一个Grid 控件Grid1、两个CommandButton 控

件cmdQuery 和cmdClose,在Project1 中插入一个模块Module1,将

前面列举的声明语句加入其中。程序代码如下:

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

实例程序是使用Visual Basic 4.0 在Windows 95 环境下开发的。