﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-叶明的javablog-随笔分类-sql2000学习</title><link>http://www.blogjava.net/guming123416/category/6970.html</link><description>java学习天堂,个人关于JAVA的论坛bbs.javaworker.cn,欢迎大家访问</description><language>zh-cn</language><lastBuildDate>Tue, 28 Aug 2007 19:47:09 GMT</lastBuildDate><pubDate>Tue, 28 Aug 2007 19:47:09 GMT</pubDate><ttl>60</ttl><item><title>手把手教你制作Google Sitemap(详细制作教程和协议讲解)</title><link>http://www.blogjava.net/guming123416/archive/2007/08/28/140579.html</link><dc:creator>lovajava_ye</dc:creator><author>lovajava_ye</author><pubDate>Tue, 28 Aug 2007 08:36:00 GMT</pubDate><guid>http://www.blogjava.net/guming123416/archive/2007/08/28/140579.html</guid><wfw:comment>http://www.blogjava.net/guming123416/comments/140579.html</wfw:comment><comments>http://www.blogjava.net/guming123416/archive/2007/08/28/140579.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/guming123416/comments/commentRss/140579.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/guming123416/services/trackbacks/140579.html</trackback:ping><description><![CDATA[<p style="TEXT-INDENT: 2em">Google SiteMap Protocol是Google自己推出的一种站点地图协议，此协议文件基于早期的robots.txt文件协议，并有所升级。在Google官方指南中指出加入了Google SiteMap文件的网站将更有利于Google网页爬行机器人的爬行索引，这样将提高索引网站内容的效率和准确度。文件协议应用了简单的XML格式，一共用到6个标签，其中关键标签包括链接地址、更新时间、更新频率和索引优先权。</p>
Google SiteMap文件生成后格式如下： <xmp><urlset xmlns="http://www.google.com/schemas/sitemap
/0.84">
<url>
<loc>http://duduwolf.winzheng.com</loc>
<lastmod>2005-06-03T04:20-08:00</lastmod>
<changefreq>always</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://duduwolf.winzheng.com/post/140.html</loc>
<lastmod>2005-06-02T20:20:36Z</lastmod>
<changefreq>daily</changefreq>
<priority>0.8</priority>
</url>
</urlset>
</xmp>XML标签
<ul>
    <li>changefreq:页面内容更新频率。
    <li>lastmod:页面最后修改时间
    <li>loc:页面永久链接地址
    <li>priority:相对于其他页面的优先权
    <li>url:相对于前4个标签的父标签
    <li>urlset:相对于前5个标签的父标签 </li>
</ul>
我将一句一句分解讲解这个xml文件的每一个标签：
<ol>
    <li>&lt;urlset xmlns="http://www.google.com/schemas/sitemap/0.84"&gt;<br>这一行定义了此xml文件的命名空间，相当于网页文件中的&lt;html&gt;标签一样的作用。
    <li><xmp><url></xmp>这是具体某一个链接的定义入口，你所希望展示在SiteMap文件中的每一个链接都要用&lt;url&gt;和&lt;/url&gt;包含在里面，这是必须的。
    <li><xmp><loc>http://duduwolf.winzheng.com</loc></xmp>用&lt;loc&gt;描述出具体的链接地址，这里需要注意的是链接地址中的一些特殊字符必须转换为XML(HTML)定义的转义字符，如下表：
    <table cellSpacing=0 cellPadding=2 border=1>
        <tbody>
            <tr>
                <th colSpan=2 rowSpan=2>字符</th>
                <th colSpan=2>转义后的字符</th>
            </tr>
            <tr>
                <th>HTML字符</th>
                <th>字符编码</th>
            </tr>
            <tr>
                <td noWrap width=125>and(和)</td>
                <td width=125>&amp;</td>
                <td width=75>&amp;amp;</td>
                <td width=75>&#38;</td>
            </tr>
            <tr>
                <td noWrap width=125>单引号</td>
                <td width=125>&amp;apos;</td>
                <td width=75>&amp;apos;</td>
                <td width=75>&#39;</td>
            </tr>
            <tr>
                <td noWrap width=125>双引号</td>
                <td width=125>"</td>
                <td width=75>&amp;quot;</td>
                <td width=75>&#34;</td>
            </tr>
            <tr>
                <td noWrap width=125>大于号</td>
                <td width=125>&gt;</td>
                <td width=75>&amp;gt;</td>
                <td width=75>&#62;</td>
            </tr>
            <tr>
                <td noWrap width=125>小于号</td>
                <td width=125>&lt;</td>
                <td width=75>&amp;lt;</td>
                <td width=75>&#60;</td>
            </tr>
        </tbody>
    </table>
    <li><xmp><lastmod>2005-06-03T04:20:32-08:00</lastmod></xmp>&lt;lastmod&gt;是用来指定该链接的最后更新时间，这个很重要。Google的机器人会在索引此链接前先和上次索引记录的最后更新时间进行比较，如果时间一样就会跳过不再索引。所以如果你的链接内容基于上次Google索引时的内容有所改变，应该更新该时间，让Google下次索引时会重新对该链接内容进行分析和提取关键字。这里必须用<a title="ISO 8601时间格式详细说明" href="http://www.w3.org/TR/NOTE-datetime"><u><font color=#0000ff>ISO 8601</font></u></a>中指定的时间格式进行描述，格式化的时间格式如下：
    <ul style="LIST-STYLE-TYPE: disc">
        <li>年：YYYY(2005)
        <li>年和月：YYYY-MM(2005-06)
        <li>年月日：YYYY-MM-DD(2005-06-04)
        <li>年月日小时分钟：YYYY-MM-DDThh:mmTZD(2005-06-04T10:37+08:00)
        <li>年月日小时分钟秒：YYYY-MM-DDThh:mmTZD(2005-06-04T10:37:30+08:00) </li>
    </ul>
    这里需注意的是TZD，TZD指定就是本地时间区域标记，像中国就是+08:00了
    <li><xmp><changefreq>always</changefreq></xmp>用这个标签告诉Google此链接可能会出现的更新频率，比如首页肯定就要用always(经常)，而对于很久前的链接或者不再更新内容的链接就可以用yearly(每年)。这里可以用来描述的单词共这几个："always", "hourly", "daily", "weekly", "monthly", "yearly"，具体含义我就不用解释了吧，光看单词的意思就明白了。
    <li><xmp>
    <priority>1.0</priority>
    </xmp>&lt;priority&gt;是用来指定此链接相对于其他链接的优先权比值，此值定于0.0 - 1.0之间
    <li>还有&lt;/url&gt;和&lt;/urlset&gt;，这两个就是来关闭xml标签的，这和HTML中的&lt;/body&gt;和&lt;/html&gt;是一个道理
    <li><strong>另外需要注意的是</strong>，这个xml文件必须是utf-8的编码格式，不管你是手动生成还是通过代码生成，建议最好检查一下xml文件是否是utf-8编码，最简单的方法就是用记事本打开xml然后另存为时选择编码(或转换器)为UTF-8。 </li>
</ol>
<img src ="http://www.blogjava.net/guming123416/aggbug/140579.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/guming123416/" target="_blank">lovajava_ye</a> 2007-08-28 16:36 <a href="http://www.blogjava.net/guming123416/archive/2007/08/28/140579.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP与存储过程</title><link>http://www.blogjava.net/guming123416/archive/2006/02/22/31916.html</link><dc:creator>lovajava_ye</dc:creator><author>lovajava_ye</author><pubDate>Wed, 22 Feb 2006 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/guming123416/archive/2006/02/22/31916.html</guid><wfw:comment>http://www.blogjava.net/guming123416/comments/31916.html</wfw:comment><comments>http://www.blogjava.net/guming123416/archive/2006/02/22/31916.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/guming123416/comments/commentRss/31916.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/guming123416/services/trackbacks/31916.html</trackback:ping><description><![CDATA[ASP与存储过程(Stored Procedures)的文章不少，但是我怀疑作者们是否真正实践过。我在初学时查阅过大量相关资料，发现其中提供的很多方法实际操作起来并不是那么回事。对于简单的应用，这些资料也许是有帮助的，但仅限于此，因为它们根本就是千篇一律，互相抄袭，稍微复杂点的应用，就全都语焉不详了。<BR>&nbsp;&nbsp;&nbsp; 现在，我基本上通过调用存储过程访问SQL Server，以下的文字虽不敢保证绝对正确，但都是实践的总结，希望对大家能有帮助。 
<P>&nbsp;&nbsp;&nbsp; 存储过程就是作为可执行对象存放在数据库中的一个或多个SQL命令。<BR>&nbsp;&nbsp;&nbsp; 定义总是很抽象。存储过程其实就是能完成一定操作的一组SQL语句，只不过这组语句是放在数据库中的(这里我们只谈SQL Server)。如果我们通过创建存储过程以及在ASP中调用存储过程，就可以避免将SQL语句同ASP代码混杂在一起。这样做的好处至少有三个：<BR>&nbsp;&nbsp;&nbsp; 第一、大大提高效率。存储过程本身的执行速度非常快，而且，调用存储过程可以大大减少同数据库的交互次数。<BR>&nbsp;&nbsp;&nbsp; 第二、提高安全性。假如将SQL语句混合在ASP代码中，一旦代码失密，同时也就意味着库结构失密。<BR>&nbsp;&nbsp;&nbsp; 第三、有利于SQL语句的重用。<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; 在ASP中，一般通过command对象调用存储过程，根据不同情况，本文也介绍其它调用方法。为了方便说明，根据存储过程的输入输出，作以下简单分类：<BR>&nbsp;&nbsp;&nbsp; <STRONG>1. 只返回单一记录集的存储过程</STRONG><BR>&nbsp;&nbsp;&nbsp; 假设有以下存储过程(本文的目的不在于讲述T-SQL语法，所以存储过程只给出代码，不作说明)：</P>
<P>&nbsp;&nbsp;&nbsp;<FONT color=#008000> /*SP1*/<BR></FONT>&nbsp;&nbsp;&nbsp; CREATE PROCEDURE dbo.getUserList<BR>&nbsp;&nbsp;&nbsp; as<BR>&nbsp;&nbsp;&nbsp; set nocount on<BR>&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select * from dbo.[userinfo]<BR>&nbsp;&nbsp;&nbsp; end<BR>&nbsp;&nbsp;&nbsp; go</P>
<P>&nbsp;&nbsp;&nbsp; 以上存储过程取得userinfo表中的所有记录，返回一个记录集。通过command对象调用该存储过程的ASP代码如下:<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'**通过Command对象调用存储过程**</FONT><BR>&nbsp;&nbsp;&nbsp; DIM MyComm,MyRst<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; MyComm.ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'MyConStr是数据库连接字串</FONT><BR>&nbsp;&nbsp;&nbsp; MyComm.CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "getUserList"&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'指定存储过程名</FONT><BR>&nbsp;&nbsp;&nbsp; MyComm.CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'表明这是一个存储过程</FONT><BR>&nbsp;&nbsp;&nbsp; MyComm.Prepared&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'要求将SQL命令先行编译</FONT><BR>&nbsp;&nbsp;&nbsp; Set MyRst = MyComm.Execute<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing</P>
<P>&nbsp;&nbsp;&nbsp; 存储过程取得的记录集赋给MyRst，接下来，可以对MyRst进行操作。<BR>&nbsp;&nbsp;&nbsp; 在以上代码中，CommandType属性表明请求的类型，取值及说明如下：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -1&nbsp;&nbsp; 表明CommandText参数的类型无法确定<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp; 表明CommandText是一般的命令类型<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp; 表明CommandText参数是一个存在的表名称<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp; 表明CommandText参数是一个存储过程的名称<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; 还可以通过Connection对象或Recordset对象调用存储过程，方法分别如下：</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'**通过Connection对象调用存储过程**<BR></FONT>&nbsp;&nbsp;&nbsp; DIM MyConn,MyRst<BR>&nbsp;&nbsp;&nbsp; Set MyConn = Server.CreateObject("ADODB.Connection")<BR>&nbsp;&nbsp;&nbsp; MyConn.open MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'MyConStr是数据库连接字串<BR></FONT>&nbsp;&nbsp;&nbsp; Set MyRst&nbsp; = MyConn.Execute("getUserList",0,4)&nbsp;<FONT color=#008000> '最后一个参断含义同CommandType</FONT><BR>&nbsp;&nbsp;&nbsp; Set MyConn = Nothing</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'**通过Recordset对象调用存储过程**</FONT><BR>&nbsp;&nbsp;&nbsp; DIM MyRst<BR>&nbsp;&nbsp;&nbsp; Set MyRst = Server.CreateObject("ADODB.Recordset")<BR>&nbsp;&nbsp;&nbsp; MyRst.open "getUserList",MyConStr,0,1,4<BR>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'MyConStr是数据库连接字串,最后一个参断含义与CommandType相同</FONT></P>
<P>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; <STRONG>2. 没有输入输出的存储过程<BR></STRONG>&nbsp;&nbsp;&nbsp; 请看以下存储过程：</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>/*SP2*/<BR></FONT>&nbsp;&nbsp;&nbsp; CREATE PROCEDURE dbo.delUserAll<BR>&nbsp;&nbsp;&nbsp; as<BR>&nbsp;&nbsp;&nbsp; set nocount on<BR>&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete from dbo.[userinfo]<BR>&nbsp;&nbsp;&nbsp; end<BR>&nbsp;&nbsp;&nbsp; go</P>
<P>&nbsp;&nbsp;&nbsp; 该存储过程删去userinfo表中的所有记录，没有任何输入及输出，调用方法与上面讲过的基本相同，只是不用取得记录集：</P>
<P>&nbsp;&nbsp;&nbsp;<FONT color=#008000> '**通过Command对象调用存储过程**</FONT><BR>&nbsp;&nbsp;&nbsp; DIM MyComm<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; MyComm.ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'MyConStr是数据库连接字串</FONT><BR>&nbsp;&nbsp;&nbsp; MyComm.CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "delUserAll"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'指定存储过程名<BR></FONT>&nbsp;&nbsp;&nbsp; MyComm.CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> '表明这是一个存储过程<BR></FONT>&nbsp;&nbsp;&nbsp; MyComm.Prepared&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'要求将SQL命令先行编译</FONT><BR>&nbsp;&nbsp;&nbsp; MyComm.Execute&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'此处不必再取得记录集<BR></FONT>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing&nbsp; </P>
<P>&nbsp;&nbsp;&nbsp; 当然也可通过Connection对象或Recordset对象调用此类存储过程，不过建立Recordset对象是为了取得记录集，在没有返回记录集的情况下，还是利用Command对象吧。</P>
<P><BR>&nbsp;&nbsp;&nbsp; <STRONG>3. 有返回值的存储过程</STRONG><BR>&nbsp;&nbsp;&nbsp; 在进行类似SP2的操作时，应充分利用SQL Server强大的事务处理功能，以维护数据的一致性。并且，我们可能需要存储过程返回执行情况，为此，将SP2修改如下：</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>/*SP3*/<BR></FONT>&nbsp;&nbsp;&nbsp; CREATE PROCEDURE dbo.delUserAll<BR>&nbsp;&nbsp;&nbsp; as<BR>&nbsp;&nbsp;&nbsp; set nocount on<BR>&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BEGIN TRANSACTION<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete from dbo.[userinfo]<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF @@error=0 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; COMMIT TRANSACTION<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ELSE<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROLLBACK TRANSACTION<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return<BR>&nbsp;&nbsp;&nbsp; end<BR>&nbsp;&nbsp;&nbsp; go</P>
<P>&nbsp;&nbsp;&nbsp; 以上存储过程，在delete顺利执行时，返回1，否则返回0，并进行回滚操作。为了在ASP中取得返回值，需要利用Parameters集合来声明参数：</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'**调用带有返回值的存储过程并取得返回值**</FONT><BR>&nbsp;&nbsp;&nbsp; DIM MyComm,MyPara<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; MyComm.ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> 'MyConStr是数据库连接字串<BR></FONT>&nbsp;&nbsp;&nbsp; MyComm.CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "delUserAll"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'指定存储过程名<BR></FONT>&nbsp;&nbsp;&nbsp; MyComm.CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'表明这是一个存储过程</FONT><BR>&nbsp;&nbsp;&nbsp; MyComm.Prepared&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'要求将SQL命令先行编译<BR></FONT>&nbsp;&nbsp;&nbsp;<FONT color=#008000> '声明返回值<BR></FONT>&nbsp;&nbsp;&nbsp; Set Mypara = MyComm.CreateParameter("RETURN",2,4)<BR>&nbsp;&nbsp;&nbsp; MyComm.Parameters.Append MyPara<BR>&nbsp;&nbsp;&nbsp; MyComm.Execute<BR>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'取得返回值<BR></FONT>&nbsp;&nbsp;&nbsp; DIM retValue<BR>&nbsp;&nbsp;&nbsp; retValue = MyComm(0)&nbsp;&nbsp;&nbsp; <FONT color=#008000>'或retValue = MyComm.Parameters(0)</FONT><BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; 在MyComm.CreateParameter("RETURN",2,4)中，各参数的含义如下：<BR>&nbsp;&nbsp;&nbsp; 第一个参数("RETURE")为参数名。参数名可以任意设定，但一般应与存储过程中声明的参数名相同。此处是返回值，我习惯上设为"RETURE"；<BR>&nbsp;&nbsp;&nbsp; 第二个参数(2)，表明该参数的数据类型，具体的类型代码请参阅ADO参考，以下给出常用的类型代码：<BR>&nbsp;&nbsp;&nbsp; adBigInt: 20 ;<BR>&nbsp;&nbsp;&nbsp; adBinary : 128 ; <BR>&nbsp;&nbsp;&nbsp; adBoolean: 11 ;<BR>&nbsp;&nbsp;&nbsp; adChar: 129 ;<BR>&nbsp;&nbsp;&nbsp; adDBTimeStamp: 135 ;<BR>&nbsp;&nbsp;&nbsp; adEmpty: 0 ;<BR>&nbsp;&nbsp;&nbsp; adInteger: 3 ;<BR>&nbsp;&nbsp;&nbsp; adSmallInt: 2 ; <BR>&nbsp;&nbsp;&nbsp; adTinyInt: 16 ;<BR>&nbsp;&nbsp;&nbsp; adVarChar: 200 ;<BR>&nbsp;&nbsp;&nbsp; <FONT color=#0000ff>对于返回值，只能取整形，且-1到-99为保留值；</FONT><BR>&nbsp;&nbsp;&nbsp; 第三个参数(4)，表明参数的性质，此处4表明这是一个返回值。此参数取值的说明如下：<BR>&nbsp;&nbsp;&nbsp; 0 : 类型无法确定； 1: 输入参数；2: 输入参数；3：输入或输出参数；4: 返回值<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; 以上给出的ASP代码，应该说是完整的代码，也即最复杂的代码，其实</P>
<P>&nbsp;&nbsp;&nbsp; Set Mypara = MyComm.CreateParameter("RETURN",2,4)<BR>&nbsp;&nbsp;&nbsp; MyComm.Parameters.Append MyPara<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; 可以简化为</P>
<P>&nbsp;&nbsp;&nbsp; MyComm.Parameters.Append MyComm.CreateParameter("RETURN",2,4)</P>
<P>&nbsp;&nbsp;&nbsp; 甚至还可以继续简化，稍后会做说明。<BR>&nbsp;&nbsp;&nbsp; 对于带参数的存储过程，只能使用Command对象调用(也有资料说可通过Connection对象或Recordset对象调用，但我没有试成过)。</P>
<P><BR>&nbsp;&nbsp;&nbsp; <STRONG>4. 有输入参数和输出参数的存储过程</STRONG><BR>&nbsp;&nbsp;&nbsp; 返回值其实是一种特殊的输出参数。在大多数情况下，我们用到的是同时有输入及输出参数的存储过程，比如我们想取得用户信息表中，某ID用户的用户名，这时候，有一个输入参数----用户ID，和一个输出参数----用户名。实现这一功能的存储过程如下：</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>/*SP4*/<BR></FONT>&nbsp;&nbsp;&nbsp; CREATE PROCEDURE dbo.getUserName<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @UserID int,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @UserName varchar(40) output<BR>&nbsp;&nbsp;&nbsp; as<BR>&nbsp;&nbsp;&nbsp; set nocount on<BR>&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if @UserID is null return<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select @UserName=username <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from dbo.[userinfo] <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where userid=@UserID<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return<BR>&nbsp;&nbsp;&nbsp; end<BR>&nbsp;&nbsp;&nbsp; go</P>
<P>&nbsp;&nbsp;&nbsp; 调用该存储过程的ASP代码如下：</P>
<P>&nbsp;&nbsp;&nbsp;<FONT color=#008000> '**调用带有输入输出参数的存储过程**<BR></FONT>&nbsp;&nbsp;&nbsp; DIM MyComm,UserID,UserName<BR>&nbsp;&nbsp;&nbsp; UserID = 1<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; MyComm.ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'MyConStr是数据库连接字串<BR></FONT>&nbsp;&nbsp;&nbsp; MyComm.CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "getUserName"&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'指定存储过程名<BR></FONT>&nbsp;&nbsp;&nbsp; MyComm.CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'表明这是一个存储过程</FONT><BR>&nbsp;&nbsp;&nbsp; MyComm.Prepared&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> '要求将SQL命令先行编译<BR></FONT>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'声明参数<BR></FONT>&nbsp;&nbsp;&nbsp; MyComm.Parameters.append MyComm.CreateParameter("@UserID",3,1,4,UserID)<BR>&nbsp;&nbsp;&nbsp; MyComm.Parameters.append MyComm.CreateParameter("@UserName",200,2,40)<BR>&nbsp;&nbsp;&nbsp; MyComm.Execute<BR>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'取得出参</FONT><BR>&nbsp;&nbsp;&nbsp; UserName = MyComm(1)<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing</P>
<P>&nbsp;&nbsp;&nbsp; 在以上代码中，可以看到，与声明返回值不同，声明输入参数时需要5个参数，声明输出参数时需要4个参数。声明输入参数时5个参数分别为：<FONT color=#0000ff>参数名、参数数据类型、参数类型、数据长度、参数值</FONT>。声明输出参数时，没有最后一个参数：参数值。<BR>&nbsp;&nbsp;&nbsp; 需要特别注意的是：<FONT color=#0000ff>在声明参数时，顺序一定要与存储过程中定义的顺序相同，而且各参数的数据类型、长度也要与存储过程中定义的相同</FONT>。<BR>&nbsp;&nbsp;&nbsp; 如果存储过程有多个参数，ASP代码会显得繁琐，可以使用with命令简化代码：</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'**调用带有输入输出参数的存储过程(简化代码)**</FONT><BR>&nbsp;&nbsp;&nbsp; DIM MyComm,UserID,UserName<BR>&nbsp;&nbsp;&nbsp; UserID = 1<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; with MyComm<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> 'MyConStr是数据库连接字串</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "getUserName"&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'指定存储过程名<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'表明这是一个存储过程</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Prepared&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'要求将SQL命令先行编译</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .CreateParameter("@UserID",3,1,4,UserID)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .CreateParameter("@UserName",200,2,40)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Execute<BR>&nbsp;&nbsp;&nbsp; end with<BR>&nbsp;&nbsp;&nbsp; UserName = MyComm(1)<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; 假如我们要取得ID为1到10，10位用户的用户名，是不是要创建10次Command对象呢？不是的。如果需要多次调用同一存储过程，只需改变输入参数，就会得到不同的输出：</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'**多次调用同一存储过程**</FONT><BR>&nbsp;&nbsp;&nbsp; DIM MyComm,UserID,UserName<BR>&nbsp;&nbsp;&nbsp; UserName = ""<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; for UserID = 1 to 10<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; with MyComm<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'MyConStr是数据库连接字串<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "getUserName"&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> '指定存储过程名<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'表明这是一个存储过程</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Prepared&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'要求将SQL命令先行编译</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if UserID = 1 then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .CreateParameter("@UserID",3,1,4,UserID)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .CreateParameter("@UserName",200,2,40)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Execute<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'重新给入参赋值(此时参数值不发生变化的入参以及出参不必重新声明)<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters("@UserID") = UserID<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Execute<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end if<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end with<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserName = UserName + MyComm(1) + ","&nbsp;&nbsp;&nbsp;<FONT color=#008000> '也许你喜欢用数组存储<BR></FONT>&nbsp;&nbsp;&nbsp; next<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing</P>
<P>&nbsp;&nbsp;&nbsp; 通过以上代码可以看出：<FONT color=#0000ff>重复调用同一存储过程时，只需为值发生改变的输入参数重新赋值即可</FONT>，这一方法在有多个输入输出参数，且每次调用时只有一个输入参数的值发生变化时，可以大大减少代码量。</P>
<P><BR>&nbsp;&nbsp;&nbsp; <STRONG>5. 同时具有返回值、输入参数、输出参数的存储过程<BR></STRONG>&nbsp;&nbsp;&nbsp; 前面说过，在调用存储过程时，声明参数的顺序要与存储过程中定义的顺序相同。还有一点要特别注意：<FONT color=#0000ff>如果存储过程同时具有返回值以及输入、输出参数，返回值要最先声明</FONT>。<BR>&nbsp;&nbsp;&nbsp; 为了演示这种情况下的调用方法，我们改善一下上面的例子。还是取得ID为1的用户的用户名，但是有可能该用户不存在(该用户已删除，而userid是自增长的字段)。存储过程根据用户存在与否，返回不同的值。此时，存储过程和ASP代码如下：</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>/*SP5*/<BR></FONT>&nbsp;&nbsp;&nbsp; CREATE PROCEDURE dbo.getUserName<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--为了加深对"顺序"的印象，将以下两参数的定义顺序颠倒一下<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @UserName varchar(40) output,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @UserID int<BR>&nbsp;&nbsp;&nbsp; as<BR>&nbsp;&nbsp;&nbsp; set nocount on<BR>&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if @UserID is null return<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select @UserName=username <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from dbo.[userinfo] <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where userid=@UserID<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if @@rowcount&gt;0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return<BR>&nbsp;&nbsp;&nbsp; end<BR>&nbsp;&nbsp;&nbsp; go</P>
<P>&nbsp;&nbsp;&nbsp;<FONT color=#008000> '**调用同时具有返回值、输入参数、输出参数的存储过程**</FONT><BR>&nbsp;&nbsp;&nbsp; DIM MyComm,UserID,UserName<BR>&nbsp;&nbsp;&nbsp; UserID = 1<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; with MyComm<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'MyConStr是数据库连接字串<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "getUserName"&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> '指定存储过程名</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'表明这是一个存储过程</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Prepared&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'要求将SQL命令先行编译<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'返回值要最先被声明<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.Append .CreateParameter("RETURN",2,4)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'以下两参数的声明顺序也做相应颠倒<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .CreateParameter("@UserName",200,2,40)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .CreateParameter("@UserID",3,1,4,UserID)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Execute<BR>&nbsp;&nbsp;&nbsp; end with<BR>&nbsp;&nbsp;&nbsp; if MyComm(0) = 1 then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserName = MyComm(1)<BR>&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserName = "该用户不存在"<BR>&nbsp;&nbsp;&nbsp; end if<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing</P>
<P><BR>&nbsp;&nbsp;&nbsp; <STRONG>6. 同时返回参数和记录集的存储过程</STRONG><BR>&nbsp;&nbsp;&nbsp; 有时候，我们需要存储过程同时返回参数和记录集，比如在利用存储过程分页时，要同时返回记录集以及数据总量等参数。以下给出一个进行分页处理的存储过程：</P>
<P>&nbsp;&nbsp;&nbsp;<FONT color=#008000> /*SP6*/<BR></FONT>&nbsp;&nbsp;&nbsp; CREATE PROCEDURE dbo.getUserList<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @iPageCount int OUTPUT,&nbsp;&nbsp; <FONT color=#008000>--总页数<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @iPage int,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--当前页号</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @iPageSize int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--每页记录数<BR></FONT>&nbsp;&nbsp;&nbsp; as<BR>&nbsp;&nbsp;&nbsp; set nocount on<BR>&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--创建临时表</FONT> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; create table #t (ID int IDENTITY,&nbsp;&nbsp;<FONT color=#008000> --自增字段<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; userid int,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; username varchar(40))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--向临时表中写入数据<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insert into #t <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select userid,username from dbo.[UserInfo]<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; order by userid<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--取得记录总数</FONT> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; declare @iRecordCount int<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set @iRecordCount = @@rowcount</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--确定总页数</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF @iRecordCount%@iPageSize=0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET @iPageCount=CEILING(@iRecordCount/@iPageSize)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ELSE<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET @iPageCount=CEILING(@iRecordCount/@iPageSize)+1<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--若请求的页号大于总页数，则显示最后一页</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF @iPage &gt; @iPageCount<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT @iPage = @iPageCount</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--确定当前页的始末记录<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DECLARE @iStart int&nbsp;&nbsp;&nbsp; --start record<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DECLARE @iEnd int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --end record<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT @iStart = (@iPage - 1) * @iPageSize<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT @iEnd = @iStart + @iPageSize + 1</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> --取当前页记录</FONT>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select * from #t where ID&gt;@iStart and ID&lt;@iEnd</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--删除临时表</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DROP TABLE #t</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--返回记录总数</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return @iRecordCount<BR>&nbsp;&nbsp;&nbsp; end<BR>&nbsp;&nbsp;&nbsp; go</P>
<P>&nbsp;&nbsp;&nbsp; 在上面的存储过程中，输入当前页号及每页记录数，返回当前页的记录集，总页数及记录总数。为了更具典型性，将记录总数以返回值的形式返回。以下是调用该存储过程的ASP代码(具体的分页操作略去):</P>
<P>&nbsp;&nbsp;&nbsp;<FONT color=#008000> '**调用分页存储过程**</FONT><BR>&nbsp;&nbsp;&nbsp; DIM pagenow,pagesize,pagecount,recordcount<BR>&nbsp;&nbsp;&nbsp; DIM MyComm,MyRst<BR>&nbsp;&nbsp;&nbsp; pagenow = Request("pn")<BR>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'自定义函数用于验证自然数</FONT><BR>&nbsp;&nbsp;&nbsp; if CheckNar(pagenow) = false then pagenow = 1<BR>&nbsp;&nbsp;&nbsp; pagesize = 20<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; with MyComm<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> 'MyConStr是数据库连接字串</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "getUserList"&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> '指定存储过程名</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'表明这是一个存储过程</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Prepared&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> '要求将SQL命令先行编译</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'返回值(记录总量)</FONT> <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.Append .CreateParameter("RETURN",2,4)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> '出参(总页数)<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.Append .CreateParameter("@iPageCount",3,2)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'入参(当前页号)<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .CreateParameter("@iPage",3,1,4,pagenow)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'入参(每页记录数)<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .CreateParameter("@iPageSize",3,1,4,pagesize)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set MyRst = .Execute<BR>&nbsp;&nbsp;&nbsp; end with<BR>&nbsp;&nbsp;&nbsp; if MyRst.state = 0 then&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'未取到数据，MyRst关闭<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; recordcount = -1<BR>&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyRst.close&nbsp;&nbsp;&nbsp; <FONT color=#008000>'注意：若要取得参数值，需先关闭记录集对象</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; recordcount = MyComm(0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pagecount&nbsp;&nbsp; = MyComm(1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if cint(pagenow)&gt;=cint(pagecount) then pagenow=pagecount<BR>&nbsp;&nbsp;&nbsp; end if<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'以下显示记录<BR></FONT>&nbsp;&nbsp;&nbsp; if recordcount = 0 then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Response.Write "无记录"<BR>&nbsp;&nbsp;&nbsp; elseif recordcount &gt; 0 then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyRst.open<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do until MyRst.EOF<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; loop<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'以下显示分页信息</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......<BR>&nbsp;&nbsp;&nbsp; else&nbsp; <FONT color=#008000>'recordcount=-1</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Response.Write "参数错误"<BR>&nbsp;&nbsp;&nbsp; end if</P>
<P>&nbsp;&nbsp;&nbsp; 对于以上代码，只有一点需要说明：<FONT color=#0000ff>同时返回记录集和参数时，若要取得参数，需先将记录集关闭，使用记录集时再将其打开</FONT>。</P>
<P><BR>&nbsp;&nbsp;&nbsp; <STRONG>7. 返回多个记录集的存储过程<BR></STRONG>&nbsp;&nbsp;&nbsp; 本文最先介绍的是返回记录集的存储过程。有时候，需要一个存储过程返回多个记录集，在ASP中，如何同时取得这些记录集呢？为了说明这一问题，在userinfo表中增加两个字段：usertel及usermail，并设定只有登录用户可以查看这两项内容。</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>/*SP7*/<BR></FONT>&nbsp;&nbsp;&nbsp; CREATE PROCEDURE dbo.getUserInfo<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @userid int,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @checklogin bit<BR>&nbsp;&nbsp;&nbsp; as<BR>&nbsp;&nbsp;&nbsp; set nocount on<BR>&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if @userid is null or @checklogin is null return<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select username<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from dbo.[usrinfo]<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where userid=@userid<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>--若为登录用户，取usertel及usermail</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if @checklogin=1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select usertel,usermail<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from dbo.[userinfo]<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where userid=@userid<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return<BR>&nbsp;&nbsp;&nbsp; end<BR>&nbsp;&nbsp;&nbsp; go</P>
<P>&nbsp;&nbsp;&nbsp; 以下是ASP代码：</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'**调用返回多个记录集的存储过程**</FONT><BR>&nbsp;&nbsp;&nbsp; DIM checklg,UserID,UserName,UserTel,UserMail<BR>&nbsp;&nbsp;&nbsp; DIM MyComm,MyRst<BR>&nbsp;&nbsp;&nbsp; UserID = 1<BR>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'checklogin()为自定义函数，判断访问者是否登录<BR></FONT>&nbsp;&nbsp;&nbsp; checklg = checklogin()<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; with MyComm<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#008000> 'MyConStr是数据库连接字串</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "getUserInfo"&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'指定存储过程名<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'表明这是一个存储过程</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Prepared&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#008000>'要求将SQL命令先行编译</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .CreateParameter("@userid",3,1,4,UserID)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .CreateParameter("@checklogin",11,1,1,checklg)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set MyRst = .Execute<BR>&nbsp;&nbsp;&nbsp; end with<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing</P>
<P>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'从第一个记录集中取值</FONT><BR>&nbsp;&nbsp;&nbsp; UserName = MyRst(0)<BR>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'从第二个记录集中取值</FONT><BR>&nbsp;&nbsp;&nbsp; if not MyRst is Nothing then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set MyRst = MyRst.NextRecordset()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserTel&nbsp; = MyRst(0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserMail = MyRst(1)<BR>&nbsp;&nbsp;&nbsp; end if<BR>&nbsp;&nbsp;&nbsp; Set MyRst = Nothing</P>
<P>&nbsp;&nbsp;&nbsp; 以上代码中，<FONT color=#0000ff>利用Recordset对象的NextRecordset方法，取得了存储过程返回的多个记录集</FONT>。</P>
<P><BR>&nbsp;&nbsp;&nbsp; 至此，针对ASP调用存储过程的各种情况，本文已做了较为全面的说明。最后说一下在一个ASP程序中，调用多个存储过程的不同方法。<BR>&nbsp;&nbsp;&nbsp; 在一个ASP程序中，调用多个存储过程至少有以下三种方法是可行的：<BR>&nbsp;&nbsp;&nbsp; <STRONG>1. 创建多个Command对象</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp; DIM MyComm<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'调用存储过程一<BR></FONT>&nbsp;&nbsp;&nbsp; ......<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp;<FONT color=#008000> '调用存储过程二</FONT><BR>&nbsp;&nbsp;&nbsp; ......<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing<BR>&nbsp;&nbsp;&nbsp; ......</P>
<P>&nbsp;&nbsp;&nbsp;<STRONG> 2. 只创建一个Command对象，结束一次调用时，清除其参数</STRONG></P>
<P>&nbsp;&nbsp;&nbsp; DIM MyComm<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp;<FONT color=#008000> '调用存储过程一<BR></FONT>&nbsp;&nbsp;&nbsp; .....<BR>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'清除参数(假设有三个参数)<BR></FONT>&nbsp;&nbsp;&nbsp; MyComm.Parameters.delete 2<BR>&nbsp;&nbsp;&nbsp; MyComm.Parameters.delete 1<BR>&nbsp;&nbsp;&nbsp; MyComm.Parameters.delete 0<BR>&nbsp;&nbsp;&nbsp;<FONT color=#008000> '调用存储过程二并清除参数<BR></FONT>&nbsp;&nbsp;&nbsp; ......<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing</P>
<P>&nbsp;&nbsp;&nbsp; 此时要注意：清除参数的顺序与参数声明的顺序相反，原因嘛，我也不知道。</P>
<P>&nbsp;&nbsp;&nbsp; <STRONG>3. 利用Parameters数据集合的Refresh方法重置Parameter对象</STRONG></P>
<P>&nbsp;&nbsp;&nbsp; DIM MyComm<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Server.CreateObject("ADODB.Command")<BR>&nbsp;&nbsp;&nbsp; <FONT color=#008000>'调用存储过程一</FONT><BR>&nbsp;&nbsp;&nbsp; .....<BR>&nbsp;&nbsp;&nbsp;<FONT color=#008000> '重置Parameters数据集合中包含的所有Parameter对象<BR></FONT>&nbsp;&nbsp;&nbsp; MyComm.Parameters.Refresh<BR>&nbsp;&nbsp;&nbsp;<FONT color=#008000> '调用存储过程二</FONT><BR>&nbsp;&nbsp;&nbsp; .....<BR>&nbsp;&nbsp;&nbsp; Set MyComm = Nothing<BR>&nbsp; <BR>&nbsp;&nbsp;&nbsp; 一般认为，重复创建对象是效率较低的一种方法，但是经测试(测试工具为Microsoft Application Center Test)，结果出人意料：<BR>&nbsp;&nbsp;&nbsp; <FONT color=#0000ff>方法2 &gt;= 方法1 &gt;&gt; 方法3<BR></FONT>&nbsp;&nbsp;&nbsp; 方法2的运行速度大于等于方法1(最多可高4%左右)，这两种方法的运行速度远大于方法3(最多竟高达130%)，所以建议在参数多时，采用方法1，在参数较少时，采用方法2。</P>
<P>&nbsp;&nbsp;&nbsp; 花了一天的时间，终于把我对于在ASP中调用存储过程的一些粗浅的经验形成了文字。这其中，有些是我只知其果而不明其因的，有些可能是错误的，但是，这些都是经过我亲身实践的。各位看官批判地接受吧。有不同意见，希望一定向我指明，先谢了。</P><img src ="http://www.blogjava.net/guming123416/aggbug/31916.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/guming123416/" target="_blank">lovajava_ye</a> 2006-02-22 10:26 <a href="http://www.blogjava.net/guming123416/archive/2006/02/22/31916.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>