📄 odbc-c2.htm
字号:
<html>
<head>
<title>ODBC Programming Tutorial:连接数据源</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#000000" text="#FFFFFF" link="#FFFFCC" vlink="#ffffCC" alink="#CCFFCC">
<h1 align="center"><font face="Tahoma" color="#FFFFCC">连接数据源</font></h1>
<p align="left"><font face="Tahoma" size="-1">本教程中,我们将学习使用ODBC APIs的细节.</font></p>
<p align="left"><font face="Tahoma" size="-1">因为我们的程序并不与ODBC驱动程序直接通信,而是通过ODBC管理器来定义一系列APIs供你的程序调用以完成工作,所以我们需要包含odbc32.inc和odbc32.lib文件,当然还有windows.inc。</font></p>
<p align="left"><font face="Tahoma" size="-1">连接数据源需要以下几步:</font></p>
<ol>
<li><font face="Tahoma" size="-1"><b><font color="#FFFFCC">分配一个环境句柄(environment
handle)</font></b>. 在进行每个ODBC任务(session)时仅需这样做一次.一旦获得了句柄,我们就可修改环境属性来适合我们的需要。你可以把这想象为在DB工作中创建一个workspace.</font></li>
<li><font color="#FFFFCC" face="Tahoma" size="-1"><b>确认将使用的ODBC的版本</b></font><font face="Tahoma" size="-1">. 你可在ODBC 2.x版和3.x版间选择.他们在很多方面存在不同,因此本步骤是必须的以使得ODBC管理器它将用何种语法与用户程序通讯,及如何解释用户程序的命令.</font></li>
<li><font face="Tahoma" size="-1"><b><font color="#FFFFCC">分配一个连接句柄</font></b>.这个步骤可看作创建一个空连接.我们还没有指定使用那一个驱动程序,连接那一个数据库.这些信息将在稍后来写入.</font></li>
<li><font face="Tahoma" size="-1"><b><font color="#FFFFCC">建立一个连接.</font></b>可通过调用ODBC函数来建立连接.</font></li>
</ol>
<p><font face="Tahoma" size="-1">当连接完成时,必须通过以下步骤来关闭和销毁它:</font></p>
<ol>
<li><font color="#FFFFCC" face="Tahoma" size="-1"><b>断开与数据源的连接</b></font><font face="Tahoma" size="-1">.</font></li>
<li><font face="Tahoma" size="-1"><b><font color="#FFFFCC">释放连接句柄</font></b>.</font></li>
<li><font color="#FFFFCC" face="Tahoma" size="-1"><b>释放环境句柄</b></font><font face="Tahoma" size="-1"> (如果不再需要在这个环境中作更多连接)</font></li>
</ol>
<h4><font face="Tahoma" color="#CCFFCC">分配一个句柄</font></h4>
<p><font face="Tahoma" size="-1">在ODBC 3.x版本以前,我们需要调用很多独立的函数来分配环境、连接和语句句柄(<font color="#FFFFCC"><b>SQLAllocEnv</b></font>, <font color="#FFFFCC"> <b>SQLAllocConnect</b></font>,
<font color="#FFFFCC"><b>SQLAllocStmt</b></font>).而在ODBC 3.x中, 这些函数被<font color="#FFFFCC"><b>SQLAllocHandle</b></font>所代替,语法如下:</font></p>
<blockquote>
<pre><font face="Tahoma"><b><font color="#CCFFCC">SQLRETURN SQLAllocHandle( SQLSMALLINT HandleType,
SQLHANDLE InputHandle,
SQLHANDLE * OutputHandlePtr
); </font></b></font></pre>
</blockquote>
<p><font face="Tahoma" size="-1">看上去挺麻烦,简化一下看看:</font> </p>
<blockquote>
<pre><font face="Tahoma" color="#CCFFCC"><b>SQLAllocHandle proto HandleType:DWORD, <br> InputHandle:DWORD, <br> OutputHandlePtr:DWORD</b></font></pre>
</blockquote>
<p><font color="#FFFFCC" face="Tahoma" size="-1"><b>SQLRETURN</b></font><font face="Tahoma" size="-1">
被定义为<font color="#FFFFCC"><b>SQLSMALLINT</b></font>类型.而<font color="#FFFFCC"><b>
SQLSMALLINT</b></font>被定义为短整型,例如一个字(16 bits).
所以该函数的返回值在<font color="#FFFFCC"><b>ax</b></font>中,而不是<font color="#FFFFCC"><b> eax</b></font>. 这是很重要的.但是Win32下函数的参数是通过32位堆栈来传送的.即使这个参数只是一个字长(16位),它也应被扩展为32位.这就是为什么<font color="#CCFFCC"><b>HandleType</b></font>被说明为双字(dword)而不是字(word).看一下导入库<font color="#CCFFCC"> <b>odbc32.lib</b></font>,<font color="#FFFFCC"><b>SQLAllocHandle</b></font>的入口是<font color="#CCFFCC"><b>_SQLAllocHandle@12</b></font>. 就是说这个函数的参数的组合长度为12字节(3
dwords).然而,这不是说C函数的原型不对.
<font color="#FFFFCC"> <b>SQLAllocHandle</b></font>会只用<font color="#CCFFCC"><b>HandleType</b></font>的底位字并忽略高位字.因此C函数原型是<font color="#CCCCFF"><i><b>功能上(functionally)</b></i></font>正确而我们的汇编函数原型反映了实际.</font></p>
<p><font face="Tahoma" size="-1">结束了SQL类型的讨论,我们来看一看函数的参数和返回值。.</font></p>
<ul>
<li><font face="Tahoma" size="-1"><b><font color="#CCFFCC">HandleType</font></b>
是一个常数,定义了希望分配的句柄类型.可能值如下:</font></li>
</ul>
<table border="1" cellspacing="1" cellpadding="3" align="center">
<tr>
<td bgcolor="#0000CC"><font face="Tahoma" size="-1"><b>SQL_HANDLE_ENV </b></font></td>
<td bgcolor="#006666"><font face="Tahoma" size="-1">环境句柄(Environment handle)</font></td>
</tr>
<tr>
<td bgcolor="#0000CC"><font face="Tahoma" size="-1"><b>SQL_HANDLE_DBC</b></font></td>
<td bgcolor="#006666"><font face="Tahoma" size="-1">连接句柄(Connection handle)</font></td>
</tr>
<tr>
<td bgcolor="#0000CC"><font face="Tahoma" size="-1"><b>SQL_HANDLE_STMT</b></font></td>
<td bgcolor="#006666"><font face="Tahoma" size="-1">语句句柄(Statement handle)</font></td>
</tr>
<tr>
<td bgcolor="#0000CC"><font face="Tahoma" size="-1"><b>SQL_HANDLE_DESC</b></font></td>
<td bgcolor="#006666"><font face="Tahoma" size="-1">描述符句柄(Descriptor handle)</font></td>
</tr>
</table>
<blockquote>
<p><font face="Tahoma" size="-1">描述符是一个数据集合描述了一个SQL语句的参数或一个结果集的列数,
视应用程序或驱动程序而定。</font></p>
</blockquote>
<ul>
<li><font color="#CCFFCC" face="Tahoma" size="-1"><b>InputHandle</b></font><font face="Tahoma" size="-1">
是指向父"文本"的句柄.就是说,如果你想分配一个连接句柄, 需要通过一个环境句柄因为连接将在那个环境的文本中建立.如果你想分配一个环境句柄,这个参数必须为<font color="#CCFFCC"><b>SQL_HANDLE_NULL</b></font>
(注意<font color="#CCFFCC"><b>SQL_HANDLE_NULL</b></font>在windows.inc版本1.18及其以前版本中被不正确的定义为0L.你需要删除掉"L"否则程序不会被编译通过.这是我的错,因为我负责修订windows.inc中的 SQL/ODBC部分.)
因为环境没有父文本.对于语句和描述符句柄,我们需要将连接句柄作为这个参数。</font></li>
<li><font color="#CCFFCC"><b><font face="Tahoma" size="-1">OutputHandlePtr</font></b></font><font face="Tahoma" size="-1">
如果调用成功,将指向一个双字,其中包含了被分配的句柄.</font></li>
</ul>
<p><font face="Tahoma" size="-1"><font color="#FFFFCC"><b>SQLAllocHandle</b></font>
可能的返回值如下:</font></p>
<table border="1" cellspacing="1" cellpadding="3" align="center">
<tr>
<td bgcolor="#003399"><b><font face="Tahoma" size="-1">SQL_SUCCESS</font></b></td>
<td bgcolor="#006666"><font face="Tahoma" size="-1">函数成功完成.</font></td>
</tr>
<tr>
<td bgcolor="#003399"><b><font face="Tahoma" size="-1">SQL_SUCCESS_WITH_INFO</font></b></td>
<td bgcolor="#006666"><font face="Tahoma" size="-1">函数成功完成,但带回非致命错误或警告. </font></td>
</tr>
<tr>
<td bgcolor="#003399"><b><font face="Tahoma" size="-1">SQL_ERROR</font></b></td>
<td bgcolor="#006666"><font face="Tahoma" size="-1">函数调用失败.</font></td>
</tr>
<tr>
<td bgcolor="#003399"><b><font face="Tahoma" size="-1">SQL_INVALID_HANDLE</font></b></td>
<td bgcolor="#006666"><font face="Tahoma" size="-1">传送给函数的句柄非法.</font></td>
</tr>
</table>
<p><font face="Tahoma" size="-1">无论函数的调用成功还是失败,我们都可通过调用<font color="#FFFFCC"><b>SQLGetDiagRec</b></font>或<font color="#FFFFCC"><b>SQLGetDiagField</b></font>函数来获得更多的信息.它们与Win32 API中的<font color="#FFFFCC"><b>GetLastError</b></font>很相似.</font></p>
<p><font face="Tahoma" size="-1"><br>
<font face="MS Sans Serif"><b><font face="Tahoma" color="#33CCCC">例子:</font></b></font></font></p>
<p><font face="Tahoma" color="#33CCCC"><b><font size="-1">.data?<br>
hEnv dd ?</font></b></font></p>
<p><font face="Tahoma" color="#33CCCC"><b><font size="-1">.code<br>
invoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_HANDLE_NULL,
addr hEnv<br>
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></p>
<h4><font face="Tahoma" color="#FFFFCC">选择ODBC的版本</font></h4>
<p><font face="Tahoma" size="-1">分配完环境句柄后,我们需要设置一个环境属性<font color="#CCFFCC"><b>SQL_ATTR_ODBC_VERSION</b></font>以适当的值.设置环境属性可通过调用函数<font color="#FFFFCC"><b>SQLSetEnvAttr</b></font>.你也许猜到了,还有类似的函数如<font color="#FFFFCC"><b>
SQLSetConnectAttr</b></font>和<font color="#FFFFCC"><b>SQLSetStmtAttr</b></font>.<font color="#FFFFCC"><b>
SQLSetEnvAttr</b></font>原型如下:</font></p>
<blockquote>
<pre><font face="Tahoma"><b><font color="#CCFFCC">SQLSetEnvAttr proto EnvironmentHandle:DWORD,<br> Attribute:DWORD,<br> ValuePtr:DWORD,
StringLength:DWORD</font></b></font></pre>
</blockquote>
<ul>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>EnvironmentHandle</b></font><font face="Tahoma" size="-1">.
与字面意思一样, 它包含了要设置属性的环境句柄.</font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>Attribute</b></font><font face="Tahoma" size="-1">.
这是一个常数,表示用户需要设置的属性.对我们而言,是<font color="#CCFFCC"><b>SQL_ATTR_ODBC_VERSION</b></font>.可以从MSDN中查看全部列表. </font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>ValuePtr</b></font><font face="Tahoma" size="-1">.
这个参数的意义由希望设置的属性值决定.如果属性值是32位的, 这个参数将被认为是想要设置的属性值.如果属性值是一个字符串或二进制缓冲区,它就被解释为指向字符串或缓冲区的指针.如果我们指定了要设置的属性为<font color="#CCFFCC"><b>SQL_ATTR_ODBC_VERSION</b></font>, 这个参数我们可以填入<font color="#CCFFCC"><b>SQL_OV_ODBC3</b></font>和<font color="#CCFFCC"><b>SQL_OV_ODBC2</b></font>这两个可能值,分别对应ODBC 3.x和2.x.</font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>StringLength</b></font><font face="Tahoma" size="-1">.
由<font color="#FFCCFF"><b>ValuePtr</b></font>指向的值的长度.
如果这个值是字符串或二进制缓冲区,这个参数一定是合法的.
如果想设置的属性是一个双字,这个参数被忽略.因为
<font color="#CCFFCC"><b>SQL_ATTR_ODBC_VERSION</b></font>属性包含一个双字的值,我们可以只给它赋为NULL.</font></li>
</ul>
<p><font face="Tahoma" size="-1">这个函数的返回值与<font color="#FFFFCC"><b>SQLAllocHandle</b></font>相同.</font></p>
<p><font face="Tahoma" size="-1"><font face="MS Sans Serif"><b><font face="Tahoma" color="#33CCCC">例子:</font></b></font></font></p>
<p><font face="Tahoma" color="#33CCCC"><b><font size="-1">.data?<br>
hEnv dd ?</font></b></font></p>
<p><font face="Tahoma" color="#33CCCC"><b><font size="-1">.code<br>
invoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_HANDLE_NULL,
addr hEnv<br>
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO<br>
invoke SQLSetEnvAttr,
hEnv, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3, NULL<br>
.if ax==SQL_SUCCESS ||
ax==SQL_SUCCESS_WITH_INFO</font></b></font></p>
<h4><font face="Tahoma" color="#FFFFCC">分配连接句柄</font></h4>
<p><font face="Tahoma" size="-1">这一步与分配环境句柄相似,我们可以通过调用<font color="#FFFFCC"><b>SQLAllocHandle</b></font>函数并赋以不同的参数值来完成.</font></p>
<p><font face="Tahoma" size="-1"><b><font color="#33CCCC">例子:</font></b></font></p>
<p><font color="#33CCCC"><b><font face="Tahoma" size="-1">.data?<br>
hEnv dd ?<br>
hConn dd ?</font></b></font></p>
<p><font color="#33CCCC"><b><font face="Tahoma" size="-1">.code<br>
invoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_HANDLE_NULL,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -