连接数据源

来源:互联网 发布:mac默认输入法为搜狗 编辑:程序博客网 时间:2024/04/28 05:47
 本教程中,我们将学习使用odbc apis的细节.

因为我们的程式并不和odbc驱动程式直接通信,而是通过odbc管理器来定义一系列apis供您的程式调用以完成工作,所以我们需要包含odbc32.inc和odbc32.lib文档,当然更有windows.inc。

连接数据源需要以下几步:
分配一个环境句柄(environment handle). 在进行每个odbc任务(session)时仅需这样做一次.一旦获得了句柄,我们就可修改环境属性来适合我们的需要。您能够把这想象为在db工作中创建一个workspace. 确认将使用的odbc的版本. 您可在odbc 2.x版和3.x版间选择.他们在很多方面存在不同,因此本步骤是必须的以使得odbc管理器他将用何种语法和用户程式通讯,及怎样解释用户程式的命令. 分配一个连接句柄.这个步骤可看作创建一个空连接.我们还没有指定使用那一个驱动程式,连接那一个数据库.这些信息将在稍后来写入. 建立一个连接.可通过调用odbc函数来建立连接.
当连接完成时,必须通过以下步骤来关闭和销毁他:
断开和数据源的连接. 释放连接句柄. 释放环境句柄 (假如不再需要在这个环境中作更多连接) 分配一个句柄
在odbc 3.x版本以前,我们需要调用很多单独的函数来分配环境、连接和语句句柄(sqlallocenv, sqlallocconnect, sqlallocstmt).而在odbc 3.x中, 这些函数被sqlallochandle所代替,语法如下:

sqlreturn sqlallochandle( sqlsmallint handletype, sqlhandle inputhandle, sqlhandle * outputhandleptr );

看上去挺麻烦,简化一下看看:

sqlallochandle proto handletype:dword,
inputhandle:dword,
outputhandleptr:dword

sqlreturn 被定义为sqlsmallint类型.而 sqlsmallint被定义为短整型,例如一个字(16 bits). 所以该函数的返回值在ax中,而不是 eax. 这是很重要的.但是win32下函数的参数是通过32位堆栈来传送的.即使这个参数只是个字长(16位),他也应被扩展为32位.这就是为什么 handletype被说明为双字(dword)而不是字(word).看一下导入库 odbc32.lib,sqlallochandle的入口是_sqlallochandle@12. 就是说这个函数的参数的组合长度为12字节(3 dwords).然而,这不是说c函数的原型不对. sqlallochandle会只用handletype的底位字并忽略高位字.因此c函数原型是功能上(functionally)正确而我们的汇编函数原型反映了实际.

结束了sql类型的讨论,我们来看一看函数的参数和返回值。.
handletype 是个常数,定义了希望分配的句柄类型.可能值如下: sql_handle_env 环境句柄(environment handle)sql_handle_dbc连接句柄(connection handle)sql_handle_stmt语句句柄(statement handle)sql_handle_desc描述符句柄(descriptor handle)
描述符是个数据集合描述了一个sql语句的参数或一个结果集的列数, 视应用程式或驱动程式而定。
inputhandle 是指向父"文本"的句柄.就是说,假如您想分配一个连接句柄, 需要通过一个环境句柄因为连接将在那个环境的文本中建立.假如您想分配一个环境句柄,这个参数必须为sql_handle_null (注意sql_handle_null在windows.inc版本1.18及其以前版本中被不正确的定义为0l.您需要删除掉"l"否则程式不会被编译通过.这是我的错,因为我负责修订windows.inc中的 sql/odbc部分.) 因为环境没有父文本.对于语句和描述符句柄,我们需要将连接句柄作为这个参数。 outputhandleptr 假如调用成功,将指向一个双字,其中包含了被分配的句柄.
sqlallochandle 可能的返回值如下:
sql_success函数成功完成.sql_success_with_info函数成功完成,但带回非致命错误或警告. sql_error函数调用失败.sql_invalid_handle传送给函数的句柄非法.
无论函数的调用成功还是失败,我们都可通过调用sqlgetdiagrec或sqlgetdiagfield函数来获得更多的信息.他们和win32 api中的getlasterror很相似.


例子:

.data?
henv dd ?

.code
invoke sqlallochandle, sql_handle_env, sql_handle_null, addr henv
.if ax==sql_success || ax==sql_success_with_info
选择odbc的版本
分配完环境句柄后,我们需要配置一个环境属性sql_attr_odbc_version以适当的值.配置环境属性可通过调用函数 sqlsetenvattr.您也许猜到了,更有类似的函数如 sqlsetconnectattr和sqlsetstmtattr. sqlsetenvattr原型如下:

sqlsetenvattr proto environmenthandle:dword,
attribute:dword,
valueptr:dword, stringlength:dword
environmenthandle. 和字面意思相同, 他包含了要配置属性的环境句柄. attribute. 这是个常数,表示用户需要配置的属性.对我们而言,是sql_attr_odbc_version.能够从msdn中查看全部列表. valueptr. 这个参数的意义由希望配置的属性值决定.假如属性值是32位的, 这个参数将被认为是想要配置的属性值.假如属性值是个字符串或二进制缓冲区,他就被解释为指向字符串或缓冲区的指针.假如我们指定了要配置的属性为 sql_attr_odbc_version, 这个参数我们能够填入sql_ov_odbc3和sql_ov_odbc2这两个可能值,分别对应odbc 3.x和2.x. stringlength. 由valueptr指向的值的长度. 假如这个值是字符串或二进制缓冲区,这个参数一定是合法的. 假如想配置的属性是个双字,这个参数被忽略.因为 sql_attr_odbc_version属性包含一个双字的值,我们能够只给他赋为null.
这个函数的返回值和sqlallochandle相同.

例子:

.data?
henv dd ?

.code
invoke sqlallochandle, sql_handle_env, sql_handle_null, addr henv
.if ax==sql_success || ax==sql_success_with_info
invoke sqlsetenvattr, henv, sql_attr_odbc_version, sql_ov_odbc3, null
.if ax==sql_success || ax==sql_success_with_info
分配连接句柄
这一步和分配环境句柄相似,我们能够通过调用sqlallochandle函数并赋以不同的参数值来完成.

例子:

.data?
henv dd ?
hconn dd ?

.code
invoke sqlallochandle, sql_handle_env, sql_handle_null, addr henv
.if ax==sql_success || ax==sql_success_with_info
invoke sqlsetenvattr, henv, sql_attr_odbc_version, sql_ov_odbc3, null
.if ax==sql_success || ax==sql_success_with_info
invoke sqlallochandle, sql_handle_dbc, henv, addr hconn
.if ax==sql_success || ax==sql_success_with_info
建立一个连接
我们现在要通过特定的odbc驱动程式来连接数据源.通过这三个odbc函数来达成这个目标.他们为我们提供了好几层"选择".
sqlconnectcore 这是最简单的函数。他只需要数据源名(dsn,data source name)和可选的用户名和密码.他不提供任何gui选项例如向用户显示一个对话框来提供更多信息。假如您已有了需要使用的数据库的dsn就能够使用这个函数.sqldriverconnectcore这个函数提供了较sqlconnect更多的选择.我们能够连接一个没有在系统信息内定义的数据源。如没有dsn.另外,我们能够指定这个函数是否需要显示一个对话框来为用户提供更多信息.例如,假如用户遗漏了数据库的名字,他会指导odbc驱动程式显示一个对话框,让用户来选择想连接的数据库.sqlbrowseconnectlevel 1这个函数允许在运行时(runtime)枚举数据源.比sqldriverconnect更加灵活。因为能够多次顺序调用 sqlbrowseconnect,而每次提供给使用者更多的专用信息直到最后获得需要的连接句柄.
我将先检查sqlconnect函数.要使用 sqlconnect,您应先知道什么是dsn. dsn是数据源名(data source name)的缩写,是个唯一标识某数据源的字符串。一个dsn标识了一个包含了怎样连接某一特定的数据源的信息的数据结构.这个信息包括要使用何种 odbc驱动程式及要连接哪个数据库.我们能够通过控制面板中的32位odbc数据源来创建、修改及删除dsn.

sqlconnect的语法如下:

sqlconnect proto connectionhandle:dword
pdsn:dword,
dsnlength:dword,
pusername:dword,
namelength:dword,
ppassword:dword,
passwordlength:dword
connectionhandle. 要使用的连接句柄. pdsn. 指向dsn的指针. dsnlength. dsn的长度 pusername. 指向用户名的指针 namelength. 用户名的长度 ppassword. 指向该用户名所使用密码的指针 passwordlength. 密码的长度
在最小情况下, sqlconnect 需要连接句柄,dsn和dsn的长度。假如数据源无需的话,用户名和密码就不是必须的.函数的返回值和sqlallochandle的返回值相同.

假设我们的系统中有一个叫做"sales" 的dsn并且我们想连接这个数据源.我们能够这样做:

.data
dsn db "sales",0

.code
......
invoke sqlconnect, hconn, addr dsn, sizeof dsn,0,0,0,0

sqlconnect 的缺点是:在连接一个数据源之前,我们必须创建他的dsn. sqldriverconnect 提供了更大的灵活性.他的语法如下:

sqldriverconnect proto connectionhandle:dword,
hwnd:dword,
pinconnectstring:dword,
instringlength:dword,
poutconnectstring:dword,
outbuffersize:dword,
poutconnectstringlength:dword, drivercompletion:dword
connectionhandle 连接句柄 hwnd 应用程式窗口句柄.假如这个参数被置为null,驱动程式将不会为用户显示一个对话框来显示更多信息(假如有的话). pinconnectstring 指向连接字符串的指针. 这是个asciiz字符串,格式由要连接的具体odbc驱动程式描述.他描述了驱动程式名、数据源及其他附加属性.连接字符串的具体描述请参见msdn,这里不再细述. instringlength 连接字符串的长度. poutconnectstring 指向将要被填入完整连接字符串的缓冲区的指针.这个缓冲区将至少有1,024字节长.这听上去使人困惑。事实上,我们提供的连接字符串会不完整,这时,odbc驱动程式会提示用户更多信息.接下来odbc驱动程式会根据任何可能的信息创建一个完整的连接字符串并将其放入缓冲区。即使我们提供的连接字符串已能够工作了,这个缓冲区也会填入更多的属性值.这个参数的目的是我们能够保存完整连接字符串来为接下来的连接做准备。 outbuffersize 由poutconnectstring指向的缓冲区的长度. poutconnectstringlength 指向一个双字的指针,用来接收由odbc驱动程式返回的完整连接字符串的长度。 drivercompletion 一个标志用来指示odbc管理器/驱动程式是否将提示用户更多信息.但是,这个标志取决于是否在调用本函数时传送了hwnd 参数一个窗口句柄。假如没有,即使该标志被配置,odbc管理器/驱动程式也不会提示用户.可能值如下:

sql_driver_promptodbc驱动程式提示用户输入信息。驱动程式将利用这些信息来创建连接字符串.sql_driver_complete
sql_driver_complete_required 仅当用户提供的连接字符串不完全时, odbc驱动程式才会提示用户.sql_driver_nopromptodbc驱动程式将不会提示用户.
例子:

.data
strconnect db "dbq=c:\data\test.mdb;driver={microsoft access driver (*.mdb)};",0

.data?
buffer db 1024 dup(?)
outstringlength dd ?

.code
.....
invoke sqldriverconnect, hconn, hwnd, addr strconnect, sizeof strconnect, addr buffer, sizeof buffer, addr outbufferlength, sql_driver_complete
断开和数据源的连接
在连接顺利完成后,我们就能够对数据源进行查询及其他操作.这些将在下一节讨论.现在假设我们已完成了对数据源的操作,就能够通过调用 sqldisconnect来断开和他的连接. 这个函数很简单(就象那悲伤而冷酷的现实:毁灭总比创造容易的多).他只需要一个参数:连接句柄。

invoke sqldisconnect, hconn
释放连接和环境句柄
在顺利地断开连接后,我们现在能够调用sqlfreehandle函数来销毁连接句柄和环境句柄. 这是由odbc 3.x提供的新函数.他替代了sqlfreeconnect, sqlfreeenv及sqlfreestmt函数. sqlfreehandle语法如下:

sqlfreehandle proto handletype:dword, handle:dword
handletype 标识要销毁句柄的类别的常数.可能值和 sqlallochandle中相同 handle要销毁的句柄.
for example:

invoke sqlfreehandle, sql_handle_dbc, hconn
invoke sqlfreehandle, sql_handle_env, henv
原创粉丝点击