📄 odbc-c3.htm
字号:
hStmt dd ?</font></b></font></p>
<p><font color="#33CCCC" face="Tahoma"><b><font size="-1">.code<br>
.....<br>
</font></b></font><font face="Tahoma" size="-1" color="#33CCCC"><b> invoke
SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt</b></font><font face="Tahoma"><br>
<font size="-1"><b><font color="#33CCCC"> .if
ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO </font></b></font><br>
<font color="#33CCCC"><b><font size="-1"> invoke
SQLPrepare, hStmt, addr SQLStmt, sizeof SQLStmt<br>
invoke SQLExecute, hStmt</font></b></font></font></p>
<p><font face="Tahoma" size="-1">你也许会想,编译执行没什么强于直接执行的。上面的例子还不明显。
我们需要知道SQL语句的参数来仔细研究它。</font></p>
<h4><font face="Tahoma" color="#FFFFCC">语句参数(Statement Parameters)</font></h4>
<p><font face="Tahoma" size="-1">这里的参数是指由SQL语句使用的变量.比如说我们有一个叫做 "employee"的表,它有三个字段:"name", "surname"和 "TelephoneNo" 。现在我们要找一个叫做"Bob"的职员的电话号码,
就可以使用以下SQL语句:</font></p>
<blockquote>
<pre><font face="Tahoma"><b><font color="#CCFFCC">select telephoneNo from employee where name='Bob'</font></b></font></pre>
</blockquote>
<p><font face="Tahoma" size="-1">这条SQL语句象我们希望的那样工作了。但是,如果我们又想找另一个职员的电话号码怎么办?如果不使用参数,那只好再写一条SQL语句,然后再一次编译、执行它。</font></p><font face="Tahoma" size="-1"><font>
<p><font face="Tahoma" size="-1">现在我们不会允许这种低效率的行为了。我们可以使用参数来实现目标。在上面的例子中,我们必须将字符串/值替换为 '?' (被称为参数标志符(parameter marker)).SQL 语句将变成这样:</font></p>
<blockquote>
<pre><font face="Tahoma"><b><font color="#CCFFCC">select telephoneNo from employee where name=?</font></b></font></pre>
</blockquote>
<p><font face="Tahoma" size="-1">现在想一下这个问题:ODBC驱动程序如何知道用什么值来替换参数标志符'?'?答案是:
我们必须提供需要的值.这种方法被称为<font color="#CCFFCC"><b>参数绑定(parameter
binding)</b></font>.简单点说,就是将一个参数标志符与用户程序中的变量建立连接的过程.在上面的例子中,我们需要创建一个缓冲区来告诉ODBC驱动程序,当它需要一个参数的具体值时,将从我们提供的字符串缓冲区中获得。一旦一个参数与一个变量绑定,它将一直保持绑定,直到被绑定到另一变量,或直到所有参数都被函数 <font color="#FFFFCC"> <b>SQLFreeStmt</b></font>以(函数)参数<font color="#CCFFCC"><b>
SQL_RESET_PARAMS</b></font>释放,或直到该语句被释放.</font></p>
<p><font face="Tahoma" size="-1">将一个参数绑定到一个变量是通过调用函数
<font color="#FFFFCC"><b>SQLBindParameter</b></font>实现,语法如下:</font></p>
<ul>
<li>
<pre><font face="Tahoma"><b><font color="#CCFFCC">SQLBindParameter proto StatementHandle:DWORD,<br> ParameterNumber:DWORD,<br> InputOutputType:DWORD,<br> ValueType:DWORD,<br> ParameterType:DWORD,<br> ColumnSize:DWORD,<br> DecimalDigits:DWORD,<br> ParameterValuePtr:DWORD,<br> BufferLength:DWORD,<br> pStrLenOrIndPtr:DWORD</font></b></font></pre>
</li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>StatementHandle</b></font><font face="Tahoma" size="-1">
语句句柄</font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>ParameterNumber </b></font><font face="Tahoma" size="-1">参数个数,由1开始。这就是ODBC用来判断参数描述符的方法。如果有三个参数,则最左边是第一个参数,最右边是第三个参数。</font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>InputOutputType </b></font><font face="Tahoma" size="-1">表明参数是用来输入还是输出的标志.这里的输入是指ODBC驱动程序将使用参数中获得的值,输出是指ODBC驱动程序将在操作结束时将结果放入参数中.大多数情况下,我们使用参数作为输入。而输出参数经常与存储过程有关.这个参数的两个可能值为: <font color="#CCFFCC"><b>SQL_PARAM_INPUT</b></font>、
<font color="#CCFFCC"> <b>SQL_PARAM_INPUT_OUTPUT</b></font>和<font color="#CCFFCC"><b>SQL_PARAM_OUTPUT</b></font>(译者:似应为三个参数,但原文如此)</font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>ValueType</b></font><font face="Tahoma" size="-1">
指明用户程序将要绑定到参数的值或缓冲区的类型。可能的类型为一组常数,以<font color="#CCFFCC"><b>SQL_C_</b></font>开头。</font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>ParameterType</b></font><font face="Tahoma" size="-1">
参数的SQL类型。例如,如果SQL参数是文本字段,我们就在这里填入值<font color="#CCFFCC"><b>SQL_CHAR</b></font>.查看MSDN中的ODBC程序员指南来获得完整列表(ODBC Programmer's reference)。</font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>ColumnSize</b></font><font face="Tahoma" size="-1">
参数的长度。换句话说,可认为是与参数标志符相连接的列(字段)的长度.在我们的例子中, 我们的参数标志符对列"name"使用了标准值.如果该列被定义了20字节长,我们就该在<font color="#FFCCFF"><b>ColumnSize</b></font>中填入20.</font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>DecimalDigits </b></font><font face="Tahoma" size="-1">与参数描述符连接的列的小数位.</font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>ParameterValuePtr</b></font><font face="Tahoma" size="-1">
指向包含参数数据的缓冲区的指针. </font></li>
<li><font color="#FFCCFF" face="Tahoma" size="-1"><b>BufferLength</b></font><font face="Tahoma" size="-1">
由<font color="#FFCCFF"><b>ParameterValuePtr</b></font>指向的缓冲区的长度.</font></li>
<li><font size="-1" color="#FFCCFF" face="Tahoma"><b>pStrLenOrIndPtr</b></font><font face="Tahoma" size="-1">
指向一个双字的指针,包含以下之一:</font>
<ul>
<li><font face="Tahoma" size="-1" color="#FFFFCC">由ParameterValuePtr指向的缓冲区中包含的参数长度</font><font face="Tahoma" size="-1">.
除非参数的类型是字符串或二进制值,否则这个值被忽略.别把它与<font color="#FFCCFF"><b>BufferLength</b></font>混淆,看一下这个例子就会明白:假设该参数是一个字符串,该列有20字节宽.所以我们分配了一个21字节长的缓冲区,并将其地址传送到<font color="#FFCCFF"><b>ParameterValuePtr</b></font>。在调用函数<font color="#FFFFCC"><b>SQLExecute</b></font>前, 我们在缓冲区中放入了字符串"Bob".这个字符串有3字节长,因此我们需要在<font color="#FFCCFF"><b>pStrLenOrIndPtr</b></font>指向的双字中放入3这个值.</font></li>
<li><font face="Tahoma" size="-1" color="#FFFFCC">SQL_NTS</font><font face="Tahoma" size="-1">.
这个参数是一个0结尾字符串(null-terminated string). </font></li>
<li><font face="Tahoma" size="-1" color="#FFFFCC">SQL_NULL_DATA</font><font face="Tahoma" size="-1">.
参数值为NULL. </font></li>
<li><font face="Tahoma" size="-1" color="#FFFFCC">SQL_DEFAULT_PARAM</font><font face="Tahoma" size="-1">.
存储过程将使用参数的默认值,而不是从用户程序中获得的值. 它仅适用于已定义了默认参数值的存储过程.</font></li>
<li><font face="Tahoma" size="-1" color="#FFFFCC">SQL_DATA_AT_EXEC</font><font face="Tahoma" size="-1">.
参数的数据将由<font color="#FFFFCC"><b>SQLPutData</b></font>传送.
由于数据可能太大无法放入内存(比如整个文件的数据),我们可以告诉ODBC驱动程序我们将用<font color="#FFFFCC"><b>SQLPutData</b></font>替代.<br>
<br>
可能你会说<font color="#FFCCFF"><b> pStrLenOrIndPtr</b></font>的参数太多了,但通常情况下,我们只会用到第一或第三个选项。</font></li>
</ul>
</li>
</ul>
<p><font face="Tahoma" size="-1"><b><font color="#33CCCC">例子:</font></b></font></p>
<p><font color="#33CCCC" face="Tahoma"><b><font size="-1">.data<br>
SQLString db "select telephoneNo from employee where name=?",0<br>
Sample1 db "Bob",0<br>
Sample2 db "Mary",0</font></b></font></p>
<p><font color="#33CCCC" face="Tahoma"><b><font size="-1">.data?<br>
buffer db 21 dup(?)<br>
StrLen dd ?</font></b></font></p>
<p><font color="#33CCCC" face="Tahoma"><b><font size="-1">.code<br>
........<br>
invoke SQLPrepare, hStmt, addr SQLString,sizeof
SQLString <br>
invoke SQLBindParameter, hStmt, 1, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_CHAR, 20, 0, addr buffer, sizeof buffer, addr StrLen<br>
;===========================================<br>
; First run<br>
;=========================================== <br>
invoke lstrcpy, addr buffer, addr Sample1<br>
mov StrLen, sizeof Sample1<br>
invoke SQLExecute, hStmt<br>
;===========================================<br>
; Second run<br>
;=========================================== <br>
invoke lstrcpy, addr buffer, addr Sample2<br>
mov StrLen, sizeof Sample2<br>
invoke SQLExecute, hStmt<br>
</font></b></font></p>
<p><font face="Tahoma" size="-1">注意我们仅将参数与缓冲区仅绑定了一次,当我们修改了缓冲区的内容并调用了<font color="#FFFFCC"><b>SQLExecute
</b></font>很多次.不必再调用<font color="#FFFFCC"><b>SQLPrepare</b></font>.ODBC驱动程序知道去那里找它需要的参数因为已通过<font color="#FFFFCC"><b>SQLBindParameter</b></font>函数告诉了它.</font></p>
<p><font face="Tahoma" size="-1">但现在我们还不能获得查询结果.访问和适用结果集是下一章的内容。</font></p>
<p><font face="Tahoma" size="-1">假设我们已完成了很多SQL语句,并要执行一个新的语句,那么没必要重新分配一个语句句柄.只要使用<font color="#CCFFCC"><b>SQL_UNBIND</b></font>与<font color="#CCFFCC"><b>SQL_RESET_PARAMS</b></font>参数调用<font color="#CCFFCC"><b>SQLFreeStmt</b></font>函数来解除与参数的绑定就可以了.
接下来就可以接着使用原来的语句句柄来执行SQL语句了.</font>
</p>
<h4><font face="Tahoma" color="#FFFFCC">释放语句</font> </h4>
<p><font face="Tahoma" size="-1">由调用<font color="#FFFFCC"><b>SQLFreeHandle</b></font>函数实现.</font></p>
<p> </p><p> </p>
<p align="left">
<ul>
<li>
<font size="-1">译注:原标题为<b><i><font face="Tahoma" color="#ffffcc">Preparing and Using Statements</font></i></b>,因为ODBC驱动程序繁多,有解释、编译执行之分,所以<i><font face="Tahoma" color="#ffffcc"><b>Preparing</b></font></i>不仅是指准备,也有预编译的意思。</font></li><li>
<font size="-1">另:关于作者提到的MSDN,其ODBC部分可在<i><b>Visual Studio</b></i>及其部件中找到,如<br><font face="Tahoma" color="#ffffcc">C:\program Files\DevStudio\SharedIDE\Help\ODBC.hlp</font>.</font>
<p></p>
<p align="center"><b><font face="Tahoma" size="-1"><a href="odbc-c2.htm">[<<]</a>
<a href="odbc-index.html">[index]</a> <a href="odbc-c4.htm">[>>]</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.23]</font></b></p>
</ul></font></font></font></font></body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -