?? 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 + -