⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 odbc-c5.htm

📁 odbc教程真的很不错
💻 HTM
📖 第 1 页 / 共 2 页
字号:
pop lvi.lParam
invoke SendMessage,hList, LVM_INSERTITEM,0, addr lvi
mov lvi.imask,LVIF_TEXT
inc lvi.iSubItem
mov lvi.pszText,offset TheSurname
invoke SendMessage,hList,LVM_SETITEM, 0,addr lvi
inc lvi.iSubItem
mov lvi.pszText,offset TelNo
invoke SendMessage,hList,LVM_SETITEM, 0,addr lvi
inc row
.else
.break
.endif
.endw
ret
FillData endp

RunQuery proc hDlg:DWORD
invoke ShowWindow, hList, SW_SHOW
invoke SendMessage, hList, LVM_DELETEALLITEMS,0,0
invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke SQLExecDirect, hStmt, addr SQLStatement, sizeof SQLStatement
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke FillData
.else
invoke ShowWindow, hList, SW_HIDE
invoke MessageBox,hDlg,addr ExecuteFail, addr AppName, MB_OK+MB_ICONERROR
.endif
invoke SQLCloseCursor, hStmt
invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt
.else
invoke ShowWindow, hList, SW_HIDE
invoke MessageBox,hDlg,addr AllocStmtFail, addr AppName, MB_OK+MB_ICONERROR
.endif
ret
RunQuery endp
QueryProc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD 
.if uMsg==WM_CLOSE
invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt
invoke EndDialog, hDlg,0
.elseif uMsg==WM_INITDIALOG
invoke ShowWindow, hList, SW_SHOW
invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke lstrcpy, addr Conn, addr SQLStatement
invoke lstrcat, addr Conn, addr WhereStatement
invoke SQLBindParameter,hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,25,0, addr SearchName,25,addr StrLen
invoke SQLPrepare, hStmt, addr Conn, sizeof Conn
.else
invoke ShowWindow, hList, SW_HIDE
invoke MessageBox,hDlg,addr AllocStmtFail, addr AppName, MB_OK+MB_ICONERROR
invoke EndDialog, hDlg,0
.endif 
.elseif uMsg==WM_COMMAND
mov eax, wParam
shr eax,16
.if ax==BN_CLICKED
mov eax,wParam
.if ax==IDC_OK
invoke GetDlgItemText, hDlg, IDC_NAME, addr SearchName, 25
.if ax==0
invoke MessageBox, hDlg,addr NoData, addr AppName, MB_OK+MB_ICONERROR
invoke GetDlgItem, hDlg, IDC_NAME
invoke SetFocus, eax
.else
invoke lstrlen,addr SearchName
mov StrLen,eax
invoke SendMessage, hList, LVM_DELETEALLITEMS,0,0
invoke SQLExecute, hStmt
invoke FillData
invoke SQLCloseCursor, hStmt
.endif
.else
invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt
invoke EndDialog, hDlg,0
.endif
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
QueryProc endp
end start</b></font>
</pre>
<h4><font face="Tahoma" color="#FFFFCC">分析</font></h4>
<pre><b><font face="Tahoma" color="#33CCCC">start:
invoke GetModuleHandle, NULL
mov hInstance,eax
call GetProgramPath</font></b></pre>
<p><font face="Tahoma" size="-1">当程序开始时,将获得实例句柄并获得所在路径.默认情况下数据库 test.mdb应与程序处于同一文件夹. </font><br>
</p>
<pre><font face="Tahoma"><b><font color="#33CCCC">GetProgramPath proc
invoke GetModuleFileName, NULL,addr ProgPath,sizeof ProgPath
std
mov edi,offset ProgPath
add edi,sizeof ProgPath-1
mov al,"\"
mov ecx,sizeof ProgPath
repne scasb
cld
mov byte ptr [edi+2],0
ret
GetProgramPath endp</font></b></font> </pre>
<p><font face="Tahoma" size="-1">GetProgramPath调用GetModuleFileName来获得程序的全路径名.接着在路径中查找最后一个"\"符",通过将文件名的第一个字符置为0获得(truncate)" 文件名. 因此我们在ProgPath中获得了程序的路径名.</font></p>
<p><font face="Tahoma" size="-1">然后程序将用<font color="#FFFFCC"><b>DialogBoxParam</b></font>显示主对话框.当主对话框第一次被载入时,它将获得菜单句柄和listview control句柄.接下来在listview control中插入三列(因为我们已经知道结果集将包含三列.因为是我们先建的表.)</font></p>
<p><font face="Tahoma" size="-1">现在,它就等待用户的动作了.如果用户在菜单中选择"connect",将会调用<font color="#FFFFCC"><b>ODBCConnect</b></font>函数.</font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">ODBCConnect proc hDlg:DWORD
invoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_NULL_HANDLE, addr hEnv
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">它做的第一件事是调用<font color="#FFFFCC"><b>SQLAllocHandle</b></font>来分配一个环境句柄.</font><b><font color="#33CCCC"><br>
</font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC"> invoke SQLSetEnvAttr, hEnv,SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3,0
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">获得环境句柄后,程序调用<font color="#FFFFCC"><b>SQLSetEnvAttr</b></font>来表示将要使用ODBC 3.x的语法.</font><b><font color="#33CCCC"><br>
</font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC"> invoke SQLAllocHandle, SQL_HANDLE_DBC, hEnv, addr hConn
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">如果一切顺利,程序将通过调用<font color="#FFFFCC"><b>SQLAllocHandle</b></font>获得连接句柄来实现连接.</font><b><font color="#33CCCC"><br>
</font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC"> invoke lstrcpy,addr ConnectString,addr strConnect
invoke lstrcat,addr ConnectString, addr ProgPath
invoke lstrcat, addr ConnectString,addr DBName</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">接着填写连接字符串.完整的连接字符串将被用在<b><font color="#33CCCC">ConnectionString</font></b><br>
</font></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC"> invoke SQLDriverConnect, hConn, hDlg, addr ConnectString, sizeof ConnectString, addr Conn, sizeof Conn,addr StrLen, SQL_DRIVER_COMPLETE
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke SwitchMenuState,TRUE
invoke MessageBox,hDlg, addr Conn,addr ConnectCaption,MB_OK+MB_ICONINFORMATION</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">当连接字符串完成,程序将调用<font color="#FFFFCC"><b>SQLDriverConnect</b></font>来通过MS Access ODBC 驱动程序连接test.mdb数据库.如果文件test.mdb不存在,ODBC driver将提示用户输入该文件的位置,因为我们已经设定了<font color="#CCFFCC"><b>SQL_DRIVER_COMPLETE</b></font>标志.当<font color="#CCFFCC"><b>SQLDriverConnect</b></font>成功返回时, <font color="#CCFFCC"><b>Conn</b></font> 被填入由ODBC驱动程序创建的完整连接字符串.我们通过一个message box来将其显示给用户. <font color="#CCFFCC"><b>SwitchMenuState</b></font>是一个单纯切换菜单选项可用的函数.</font></font></p>
<p><font face="Tahoma" size="-1">现在,到数据库的连接已经建立并被打开,并一直保持打开状态直到用户选择关闭. </font></p>
<p><font face="Tahoma" size="-1">当用户选择了"View All Records"命令, 
对话框过程将调用<font face="Tahoma" size="-1"><b><font color="#33CCCC">RunQuery.</font></b>函数 
<br>
</font></font></p><font face="Tahoma" size="-1">
<pre><font face="Tahoma" size="+0"><b>
<font color="#33CCCC">RunQuery proc hDlg:DWORD
invoke ShowWindow, hList, SW_SHOW
invoke SendMessage, hList, LVM_DELETEALLITEMS,0,0</font></b></font></pre>
<p><font face="Tahoma" size="-1">由于listview control在创建时是不可见的,现在我们把它显示出来.还有 要把其中的所有元素(如果有的话)删掉.</font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC" size="+0"> invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">接下来,程序将获得一个语句句柄.</font></font><br>
</p></font>
<pre><font face="Tahoma" size="+0"><b><font color="#33CCCC"> invoke SQLExecDirect, hStmt, addr SQLStatement, sizeof SQLStatement
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">通过<font color="#FFFFCC"> <b>SQLExecDirect</b></font>执行已准备好的SQL语句.我这里选择<font color="#FFFFCC"><b>SQLExecDirect</b></font> 
的原因是只须执行一次.</font><b><font color="#33CCCC"><br>
</font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC"> invoke FillData</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">执行SQL语句后,将返回一个结果集.我们使用<font color="#FFFFCC"> <b>FillData</b></font>函数来从结果集中解出数据并将其放入listview control中.</font></font></p>
<pre><font face="Tahoma"><font face="Tahoma"><b><font color="#33CCCC">FillData proc
LOCAL lvi:LV_ITEM
LOCAL row:DWORD

invoke SQLBindCol, hStmt,1,SQL_C_CHAR, addr TheName, sizeof TheName,addr NameLength
invoke SQLBindCol, hStmt,2,SQL_C_CHAR, addr TheSurname, sizeof TheSurname,addr SurnameLength
invoke SQLBindCol, hStmt,3,SQL_C_CHAR, addr TelNo, sizeof TelNo,addr TelNoLength</font></b></font></font></pre>
<p><font face="Tahoma"><font face="Tahoma" size="-1">现在,结果集被返回.我们要绑定结果集的所有三列到我们提供的缓冲区中.这是调用<font color="#FFFFCC"><b>SQLBindCol</b></font>来实现的.注意我们要对每一列分别调用.并且我们并不需要绑定所有的列:只要绑定要获得数据的列就行了. </font><font face="Tahoma"><b><br>
</b></font></font></p>
<pre><font face="Tahoma"><font face="Tahoma"><b><font color="#33CCCC"> mov row,0
.while TRUE
mov byte ptr ds:[TheName],0
mov byte ptr ds:[TheSurname],0
mov byte ptr ds:[TelNo],0</font></b></font></font></pre>
<p><font face="Tahoma"><font face="Tahoma" size="-1">当列中没有数据时,我们初始化缓冲区为NULLs.更好的方法是用<font color="#FFFFCC"><b>SQLBindCol</b></font>指定的变量中数据的长度.在我们的例子中,我们可以检查<font color="#CCFFCC"><b>NameLength</b></font>, 
<font color="#CCFFCC"> <b>SurnameLength</b></font>和<font color="#CCFFCC"><b>TelNoLength</b></font>中的值的确切长度.</font><font face="Tahoma"><b> 
</b></font></font></p>
<pre><font face="Tahoma"><font face="Tahoma"><b><font color="#33CCCC"> invoke SQLFetch, hStmt
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
mov lvi.imask,LVIF_TEXT+LVIF_PARAM
push row
pop lvi.iItem 
mov lvi.iSubItem,0
mov lvi.pszText, offset TheName
push row
pop lvi.lParam
invoke SendMessage,hList, LVM_INSERTITEM,0, addr lvi</font></b></font><font size="-1" color="#33CCCC"> </font><font color="#33CCCC"><b> </b></font></font></pre>
<p><font face="Tahoma"><font size="-1">其它都很简单了.调用<font color="#FFFFCC"><b>SQLFetch 
</b></font>来获得结果集的一行,并将其存入listview control的缓冲区中.当没有更多的行供检索时(已到达文件尾), <font color="#FFFFCC"><b>SQLFetch</b></font>返回<font color="#CCFFCC"><b>SQL_NO_DATA</b></font>并且程序跳出循环.</font></font><font face="Tahoma"><b><font color="#33CCCC"> 
</font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC"> invoke SQLCloseCursor, hStmt
invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">当完成对结果集的操作时,调用<font color="#FFFFCC"><b>SQLCloseCursor</b></font>关闭结果集并调用<font color="#FFFFCC"><b>SQLFreeHandle</b></font>释放语句句柄.</font><font face="Tahoma" size="-1"><font color="#33CCCC"><br>
</font></font><font color="#33CCCC" face="Tahoma" size="-1"><br>
</font><font face="Tahoma" size="-1">当用户选择"Query"命令,程序显示另一个对话框供用户输入要查询的名字.</font></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC"> .elseif uMsg==WM_INITDIALOG
invoke ShowWindow, hList, SW_SHOW
invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt
.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
invoke lstrcpy, addr Conn, addr SQLStatement
invoke lstrcat, addr Conn, addr WhereStatement
invoke SQLBindParameter,hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,25,0, addr SearchName,25,addr StrLen
invoke SQLPrepare, hStmt, addr Conn, sizeof Conn</font></b></font></pre>
<p><font face="Tahoma" size="-1">对话框做的第一件事是显示listview control.接下来分配一个语句句柄以创建SQL语句.这个SQL语句有一个"where"子句及一个参数标志符"?". 
完整的SQL语句是:</font></p>
<blockquote> 
<p><font face="Tahoma" color="#ffffcc" size="-1"><b>select * from main where name=?</b></font></p>
</blockquote>
<p><font size="-1" face="Tahoma">接着程序调用<font color="#FFFFCC"><b>SQLBindParameter</b></font> 
来建立参数标志符与缓冲区<font color="#CCFFCC"><b>SearchName</b></font>的连接,这样当SQL语句被执行时,ODBC驱动程序就可从<font color="#CCFFCC"><b>SearchName</b></font>中获得需要的字符串.接下来,程序调用<font color="#FFFFCC"><b>SQLPrepare</b></font>来编译SQL语句. 
这样我们只要准备/编译SQL语句一次就可多次使用.因为SQL语句已被编译过,接下来的执行过程会快一些.</font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC"> .if ax==IDC_OK
invoke GetDlgItemText, hDlg, IDC_NAME, addr SearchName, 25
.if ax==0
invoke MessageBox, hDlg,addr NoData, addr AppName, MB_OK+MB_ICONERROR
invoke GetDlgItem, hDlg, IDC_NAME
invoke SetFocus, eax
.else</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">当用户在编辑框(edit control)中填入了一些名字并按下回车键, 程序将获得编辑框中的文本并检查是否是空字符串.如果是,则显示一个message box并将键盘焦点设在编辑框上,提示用户输入名字.<br>
</font><b> </b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC"> invoke lstrlen,addr SearchName
mov StrLen,eax
invoke SendMessage, hList, LVM_DELETEALLITEMS,0,0
invoke SQLExecute, hStmt
invoke FillData
invoke SQLCloseCursor, hStmt</font></b></font></pre>
<p><font face="Tahoma" size="-1">如果编辑框中已有字符串,程序会获得它的长度并将其放入<font color="#CCFFCC"><b>StrLen</b></font>中供ODBC驱动程序使用(记住我们已将StrLen的地址传送给了<font color="#FFFFCC"><b>SQLBindParameter</b></font>). 
接下来程序使用获得的语句句柄调用<font color="#FFFFCC"><b>SQLExecute</b></font>执行已准备好的SQL语句.当<font color="#FFFFCC"><b> 
SQLExecute</b></font>返回时,程序调用FillData在listview control显示结果.因为我们不会再用到结果集,调用<font color="#FFFFCC"><b>SQLCloseCursor</b></font>来关闭它.</font></p>
<p align="center"><b><font face="Tahoma" size="-1"><a href="odbc-c4.htm">[<<]</a> 
  <a href="odbc-index.html">[index]</a> <a href="odbc-index.html">[>>]</a></font></b></p>
<hr>
<p align="center"><font face="Tahoma" size="-1"><b>[<a href="http://win32asm.cjb.net">Iczelion's 
Win32 Assembly Homepage</a>]</b></font></p>
<p align="center"><b><font face="Tahoma" size="-1">[The Chinese Portion Is Translated By <a href="mailto:hw1979@263.net">Orochi</a> ,2000.8.24]</font></b></p>
<p> </p>
<p> </p>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -