<?xml version="1.0" encoding="UTF-8"?>
  <feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html"><![CDATA[中软网博客]]></title>
  <subtitle type="html"><![CDATA[专注软件开发技术 报道行业资讯信息]]></subtitle>
  <id>http://www.cnsdn.com.cn/blog/</id> 
  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/" /> 
  <link rel="self" type="application/atom+xml" href="http://www.cnsdn.com.cn/blog/atom.asp" /> 
  <generator uri="http://www.pjhome.net/" version="2.4.1022">PJBlog2</generator> 
  <updated>2007-09-11T06:10:36+08:00</updated> 

  <entry>
	  <title type="html"><![CDATA[asp中利用数组实现数据库记录的批量录入方法 ]]></title>
	  <author>
		 <name>admin</name>
		 <uri>http://www.cnsdn.com.cn/blog/</uri>
		 <email>cnsdn@163.com</email>
	  </author>
	  <category term="" scheme="http://www.cnsdn.com.cn/blog/default.asp?cateID=4" label="B/S开发" /> 
	  <updated>2007-09-11T06:10:36+08:00</updated>
	  <published>2007-09-11T06:10:36+08:00</published>
		  <summary type="html"><![CDATA[包括两个文件<br/>1。allneeddj.asp：实现表单的生成<br/>2. allneeddjresult.asp 处理表单批量录入<br/>3.hbedu.mdb :数据库文件<br/>其数据库结构如下<br/>provinceid:省份编号 数值型<br/>dytaocount:打样套数 数值型<br/>papertaocount:纸样套数 数值型<br/>cpcontent:出片内容 数值型<br/>filename:文件名 文本型<br/>beizhu:备注 备注型<br/><br/>本例子中以10条记录，每条记录6个字段说明.<br/><br/>1。allneeddj.asp<br/><br/>&lt;html&gt;<br/><br/>&lt;head&gt;<br/>&lt;meta http-equiv=&#34;Content-Language&#34; content=&#34;zh-cn&#34;&gt;<br/>&lt;meta http-equiv=&#34;Content-Type&#34; content=&#34;text/html; charset=gb2312&#34;&gt;<br/>&lt;meta name=&#34;GENERATOR&#34; content=&#34;Microsoft FrontPage 4.0&#34;&gt;<br/>&lt;meta name=&#34;ProgId&#34; content=&#34;FrontPage.Editor.Document&#34;&gt;<br/>&lt;title&gt;需求登记&lt;/title&gt;<br/>&lt;/head&gt;<br/><br/>&lt;body&gt;<br/>&lt;%<br/>set conn=server.cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>conn.Open &#34;driver={Microsoft Access Driver (*.mdb)};dbq=&#34; &amp; _<br/>Server.MapPath(&#34;hbedu.mdb&#34;)<br/>%&gt;<br/>&lt;form method=&#34;POST&#34; action=&#34;allneeddjresult.asp&#34;&gt;<br/>&lt;table border=&#34;1&#34; width=&#34;700&#34; bordercolorlight=&#34;#FFFFFF&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr align=&#34;center&#34;&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td width=&#34;660&#34; colspan=&#34;6&#34;&gt;需求登记&lt;/td&gt;<br/>&lt;/tr&gt;<br/>&lt;tr&gt;<br/>&lt;td width=&#34;54&#34; align=&#34;center&#34;&gt;省份&lt;/td&gt;<br/>&lt;td width=&#34;66&#34; align=&#34;center&#34;&gt;打样张数&lt;/td&gt;<br/>&lt;td width=&#34;66&#34; align=&#34;center&#34;&gt;纸样张数&lt;/td&gt;<br/>&lt;td width=&#34;66&#34; align=&#34;center&#34;&gt;出片内容&lt;/td&gt;<br/>&lt;td width=&#34;80&#34; align=&#34;center&#34;&gt;文件名&lt;/td&gt;<br/>&lt;td width=&#34;328&#34; align=&#34;center&#34;&gt;备注&lt;/td&gt;<br/>&lt;/tr&gt;<br/>&lt;%<br/>rem 通过循环动态生成不同名称表单域<br/>for i=1 to 10 <br/>%&gt;<br/>&lt;%<br/>set rs=server.cr&#101;ateobject(&#34;adodb.recordset&#34;)<br/>sql=&#34;sel&#101;ct * from provinceinfo &#34;<br/>rs.open sql,conn,1,1<br/><br/><br/><br/><br/>set rs1=server.cr&#101;ateobject(&#34;adodb.recordset&#34;)<br/>sql1=&#34;sel&#101;ct * from filename &#34;<br/>rs1.open sql1,conn,1,1<br/>%&gt;<br/>&lt;tr&gt;<br/>&lt;td width=&#34;54&#34;&gt;&lt;sel&#101;ct name=&#34;&lt;% response.write&#34;data1&#34;&amp;i %&gt;&#34; size=&#34;1&#34;&gt;<br/>&lt;%<br/>do while not rs.eof<br/>if province=cstr(rs(&#34;id&#34;)) then<br/>sel=&#34;sel&#101;cted&#34;<br/>else<br/>sel=&#34;&#34;<br/>end if <br/>response.write &#34;&lt;option &#34; &amp; sel &amp; &#34; value=&#39;&#34;+CStr(rs(&#34;id&#34;))+&#34;&#39;&gt;&#34;+rs(&#34;province&#34;)+&#34;&lt;/option&gt;&#34;+chr(13)+chr(10)<br/>rs.movenext<br/>loop<br/>set rs=nothing<br/>%&gt; &lt;/sel&#101;ct&gt;&lt;/td&gt;<br/>&lt;td width=&#34;66&#34;&gt;&lt;input type=&#34;text&#34; name=&#34;&lt;% response.write&#34;data2&#34;&amp;i %&gt;&#34; size=&#34;8&#34;&gt;&lt;/td&gt;<br/>&lt;td width=&#34;66&#34;&gt;&lt;input type=&#34;text&#34; name=&#34;&lt;% response.write&#34;data3&#34;&amp;i %&gt;&#34; size=&#34;8&#34;&gt;&lt;/td&gt;<br/>&lt;td width=&#34;66&#34;&gt;&lt;sel&#101;ct size=&#34;1&#34; name=&#34;&lt;% response.write&#34;data4&#34;&amp;i %&gt;&#34;&gt;<br/>&lt;option value=&#34;1&#34;&gt;改动部分&lt;/option&gt;<br/>&lt;option value=&#34;2&#34;&gt;全部内容&lt;/option&gt;<br/>&lt;/sel&#101;ct&gt;&lt;/td&gt;<br/>&lt;td width=&#34;80&#34;&gt;&lt;sel&#101;ct name=&#34;&lt;% response.write&#34;data5&#34;&amp;i %&gt;&#34; size=&#34;1&#34;&gt;<br/>&lt;%<br/>do while not rs1.eof<br/>if filename=cstr(rs1(&#34;filename&#34;)) then<br/>sel=&#34;sel&#101;cted&#34;<br/>else<br/>sel=&#34;&#34;<br/>end if <br/>response.write &#34;&lt;option &#34; &amp; sel &amp; &#34; value=&#39;&#34;+CStr(rs1(&#34;filename&#34;))+&#34;&#39;&gt;&#34;+rs1(&#34;filename&#34;)+&#34;&lt;/option&gt;&#34;+chr(13)+chr(10)<br/>rs1.movenext<br/>loop<br/><br/>set rs1=nothing<br/>%&gt; &lt;/sel&#101;ct&gt;　&lt;/td&gt;<br/>&lt;td width=&#34;328&#34;&gt;&lt;textarea rows=&#34;2&#34; name=&#34;&lt;% response.write&#34;data6&#34;&amp;i %&gt;&#34; cols=&#34;46&#34;&gt;&lt;/textarea&gt;&lt;/td&gt;<br/>&lt;/tr&gt;<br/>&lt;% next %&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr align=&#34;center&#34;&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td width=&#34;660&#34; colspan=&#34;6&#34;&gt;<br/>&lt;input type=&#34;submit&#34; value=&#34;提交&#34; name=&#34;B1&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/td&gt;<br/>&lt;/tr&gt;<br/>&lt;/table&gt;<br/>&lt;/form&gt;<br/><br/>&lt;/body&gt;<br/><br/>&lt;/html&gt;<br/><br/>2.allneeddjresult.asp<br/><br/>&lt;%<br/>rem 定义二维数组存放从表单获取的值<br/>dim data(10,6)<br/>for i= 1 to 6<br/>for j= 1 to 10<br/>mydata=&#34;data&#34;+cstr(i)+cstr(j)<br/>data(j,i)=request.form(mydata)<br/>next<br/>next<br/>%&gt;<br/><br/>&lt;%<br/>rem 输出表单输入的值<br/>for i= 1 to 10<br/>for j= 1 to 6<br/>response.write data(i,j)<br/>next<br/>response.write&#34;&#34;<br/>next<br/>&#39;response.end<br/>%&gt;<br/>&lt;% <br/>dim conn,rs<br/>Set conn = Server.Cr&#101;ateObject(&#34;ADODB.Connection&#34;)<br/>conn.Open &#34;driver={Microsoft Access Driver (*.mdb)};dbq=&#34; &amp; _<br/>Server.MapPath(&#34;hbedu.mdb&#34;)<br/><br/><br/>for i= 1 to 10<br/>rem 循环批量入库<br/><br/>Set rs=SERVER.Cr&#101;ateObject(&#34;ADODB.Recordset&#34;)<br/>rs.Open &#34;hbedu&#34;,conn,1,3<br/>rs.AddNew<br/>rs(&#34;beizhu&#34;)=data(i,6)<br/>rs(&#34;filename&#34;)=data(i,5)<br/>rs(&#34;cpcontent&#34;)=data(i,4)<br/>rs(&#34;papertaocount&#34;)=data(i,3)<br/>rs(&#34;dytaocount&#34;)=data(i,2)<br/>rs(&#34;provinceid&#34;)=data(i,1)<br/>rs.Up&#100;ate<br/>rs.close<br/>set rs=nothing<br/>response.write&#34;ok&#34;<br/>next<br/>%&gt;<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/default.asp?id=2177" /> 
	  <id>http://www.cnsdn.com.cn/blog/default.asp?id=2177</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[ASP数据库语法总结]]></title>
	  <author>
		 <name>admin</name>
		 <uri>http://www.cnsdn.com.cn/blog/</uri>
		 <email>cnsdn@163.com</email>
	  </author>
	  <category term="" scheme="http://www.cnsdn.com.cn/blog/default.asp?cateID=4" label="B/S开发" /> 
	  <updated>2007-09-10T08:09:28+08:00</updated>
	  <published>2007-09-10T08:09:28+08:00</published>
		  <summary type="html"><![CDATA[经常使用到有关数据库的操作。包括连接代码、SQL命令等等，又不曾刻意去记忆它们（我本人是不愿意去记这东东），所以常常在用到的时候又去查书本，翻来翻去。一些比较少用的数据库还不一定能顺利找到，所以现在把它们全归纳到这里，提供大家参考。（个人水平有限，有缺陷之处，欢迎大家指正。）<br/><br/>&lt;一&gt;。数据库的连接方法：<br/><br/>1.Access数据库的DSN-less连接方法:<br/><br/>set adocon=Server.Cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adoconn.Open&#34;Driver={Microsoft Access Driver(*.mdb)};DBQ=&#34;&amp; _<br/>Server.MapPath(&#34;数据库所在路径&#34;)<br/><br/>2.Access OLE DB连接方法：<br/><br/>set adocon=Server.Cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adocon.open&#34;Provider=Microsoft.Jet.OLEDB.4.0;&#34;&amp; _<br/>&#34;Data Source=&#34; &amp; Server.MapPath(&#34;数据库所在路径&#34;)<br/><br/>3.SQL server连接方法：<br/><br/>set adocon=server.cr&#101;ateobject(&#34;adodb.recordset&#34;)<br/>adocon.Open&#34;Driver={SQL Server};Server=(Local);UID=***;PWD=***;&#34;&amp; _<br/>&#34;database=数据库名;&#34;<br/><br/>4.SQL server OLE DB连接方法:<br/><br/>set adocon=Server.Cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adocon.open&#34;provider=SQLOLEDB.1;Data Source=RITANT4;&#34;&amp; _<br/>&#34;user ID=***;Password=***;&#34;&amp; _<br/>&#34;inital Catalog=数据库名&#34;<br/><br/>5.Oracle 连接方法:<br/><br/>set adocon=Server.Cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adocon.open&#34;Driver={microsoft odbc for o&#114;acle};server=oraclesever.world;uid=admin;pwd=pass;&#34;<br/><br/>6.Oracle OLE DB 连接方法:<br/><br/>set adocon=Server.Cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adocon.open&#34;Provider=OraOLEDB.Oracle;data source=dbname;user id=admin;password=pass;&#34;<br/><br/>7.dBase 连接方法:<br/><br/>set adocon=Server.Cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adocon.open&#34;Driver={microsoft dbase driver(*.dbf)};driverid=277;dbq=------------;&#34;<br/><br/>8.mySQL 连接方法:<br/><br/>set adocon=Server.Cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adocon.open&#34;Driver={mysql};database=yourdatabase;uid=username;pwd=yourpassword;option=16386;&#34;<br/><br/>9.Visual Foxpro 连接方法:<br/><br/>set adocon=Server.Cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adocon.open&#34;Driver={microsoft Visual Foxpro driver};sourcetype=DBC;sourceDB=*.dbc;Exclusive=No;&#34;<br/><br/>10.MS text 连接方法:<br/><br/>set adocon=Server.Cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adocon.open&#34;Driver={microsoft text driver(*.txt; *.csv)};dbq=-----;&#34;&amp;_<br/>&#34;extensions=asc,csv,tab,txt;Persist SecurityInfo=false;&#34;<br/><br/>11.MS text OLE DB 连接方法:<br/><br/>set adocon=Server.Cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adocon.open&#34;Provider=microsof.jet.oledb.4.0;data source=your_path;&#34;&amp;_<br/>&#34;Extended Properties&#39;text;FMT=Delimited&#39;&#34;<br/><br/>&lt;二&gt;。常用的四种SQL命令：<br/><br/>1.查询数据记录(Sel&#101;ct)<br/>语法：Sel&#101;ct 字段串行 From table Wh&#101;re 字段=内容<br/>例子：想从book表中找出作者为&#34;cancer&#34;的所有记录，SQL语句便如下：<br/>sel&#101;ct * from book wh&#101;re author=’cancer’<br/>&#34;*&#34;是取出book表所有的字段，如查询的字段值为数字，则其后的&#34;内容&#34;便无须加上单引号，<br/><br/>如是日期，则在Access中用(#)包括，而在SQL server中则用(’)包括，<br/>如:<br/><br/>sel&#101;ct * from book wh&#101;re id=1<br/>sel&#101;ct * from book wh&#101;re pub_date=#2002-1-7# (Access)<br/>sel&#101;ct * from book wh&#101;re pub_date=’2002-1-7’ (SQL Server)<br/><br/>提示：<br/>日期函数to_date不是标准sql文，不是所有的数据库适用，所以大家在使用的时候要参考数据库具体语法<br/><br/>另外如果是查询传入的变量，则如下：<br/><br/>strau=request.form(&#34;author&#34;)<br/>strsql=&#34;sel&#101;ct * from book wh&#101;re author=’&#34;&amp;strau&amp;&#34;’&#34;<br/><br/>如果查询的是数字，则：<br/><br/>intID=request.form(&#34;id&#34;)<br/>strsql=&#34;sel&#101;ct * from book wh&#101;re id=&#34;&amp;intID<br/><br/>在很多数据库中，如：oracle，上面的语句是可以写成：<br/>strsql=&#34;sel&#101;ct * from book wh&#101;re id=&#39;&#34;&amp;intID&amp;&#34;&#39;&#34;的。<br/>但是字符型一定不能按照数字格式写，需要注意。<br/><br/>2.添加记录(Ins&#101;rt)<br/>语法：Ins&#101;rt into table(field1,field2,....) Values (value1,value2,....)<br/>例子：添加一作者是&#34;cancer&#34;的记录入book表:<br/>ins&#101;rt into book (bookno,author,bookname) values (’CF001’,’cancer’,’Cancer无组件上传程序’)<br/>同样，如果用到变量就如下：<br/><br/>strno=request.form(&#34;bookno&#34;)<br/>strau=request.form(&#34;author&#34;)<br/>strname=request.form(&#34;bookname&#34;)<br/>strsql=&#34;ins&#101;rt into book (bookno,author,bookname) values (’&#34;&amp;strno&amp;&#34;’,’&#34;&amp;strau&amp;&#34;’,’&#34;&amp;strname&amp;&#34;’)&#34;<br/><br/>3.用Recordset对象的Addnew插入数据的方法:<br/>语法：<br/><br/>rs.addnew<br/>rs(&#34;field1&#34;).value=value1<br/>rs(&#34;field2&#34;).value=value2<br/>...<br/>rs.up&#100;ate<br/><br/>4.修改数据记录(Up&#100;ate)<br/>语法：up&#100;ate table set field1=value1,field2=value2,...wh&#101;re fieldx=valuex<br/>例子：up&#100;ate book set author=’babycrazy’ wh&#101;re bookno=’CF001’<br/>如果用到变量就如下：<br/><br/>strno=request.form(&#34;bookno&#34;)<br/>strau=request.form(&#34;author&#34;)<br/>strsql=&#34;up&#100;ate book set author=’&#34;&amp;strau&amp;&#34;’ wh&#101;re bookno=’&#34;&amp;strno&#34;’&#34;<br/><br/>5.Recordset对象的Up&#100;ate方法:<br/>语法：<br/><br/>rs(&#34;field1&#34;).value=value1<br/>rs(&#34;field2&#34;).value=value2<br/>...<br/>rs.up&#100;ate<br/><br/>注意：使用语法3和语法5的时候，一定要注意字段的类型（尤其是日期型）一致，否则出错的几率非常的高。<br/><br/><br/>例子：<br/><br/>strno=request.form(&#34;bookno&#34;)<br/>strau=request.form(&#34;author&#34;)<br/>set adocon=server.cr&#101;ateobject(&#34;adodb.connection&#34;)<br/>adocon.open &#34;Driver={Microsoft Access Driver(*.mdb)};DBQ=&#34; &amp; _<br/>Server.Mappath=(&#34;/cancer/cancer.mdb&#34;)<br/>strsql=&#34;sel&#101;ct * from book wh&#101;re bookno=’&#34;&amp;strno&amp;&#34;’&#34;<br/>set rs=server.cr&#101;ateobject(&#34;adodb.recordset&#34;)<br/>rs.open strsql,adconn,1,3<br/>if not rs.eof then ’如果有此记录的话<br/>rs(&#34;author&#34;).value=strau<br/>rs.up&#100;ate<br/>end if<br/>rs.close<br/>set rs=nothing<br/>adocon.close<br/>set adocon=nothing<br/><br/>6.删除一条记录(Del&#101;te)<br/>语法：Del&#101;te table wh&#101;re field=value<br/>例子：删除book表中作者是cancer的记录<br/><br/>del&#101;te book wh&#101;re author=’cancer’<br/><br/>(注意：如果book表中author字段的值为cancer的记录有多条，将会删除所有author为cancer的记录)<br/><br/>好了，学会了用这些操作，大家在用asp操作数据库的时候，该是没有什么问题了。<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/default.asp?id=2176" /> 
	  <id>http://www.cnsdn.com.cn/blog/default.asp?id=2176</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[C#下实现动态系统托盘图标 ]]></title>
	  <author>
		 <name>admin</name>
		 <uri>http://www.cnsdn.com.cn/blog/</uri>
		 <email>cnsdn@163.com</email>
	  </author>
	  <category term="" scheme="http://www.cnsdn.com.cn/blog/default.asp?cateID=6" label="C#" /> 
	  <updated>2007-09-09T04:03:31+08:00</updated>
	  <published>2007-09-09T04:03:31+08:00</published>
		  <summary type="html"><![CDATA[　　Visual C#是微软公司推出的下一代程序开发语言，是微软.Net框架中的的一个重要组成部分。微软的.Net平台堪称为新一代的互联网平台。对于技术开发人员来说，.Net平台的两大特性是非常卓越的，首先是其所提供的公共语言运行时,也就是公用语言运行平台,另一方面就是其庞大而全面的统一编程类。Visual C#就是通过调用这些类、对象来实现许多比较强大的功能。 <br/><br/> <br/>　　本文通过向大家介绍一个.Net平台上用C#写的可以停放在任务栏上的图标程序(类似于Flashget、OICQ那种系统托盘图标)来和大家一起体验一下用C#编程的乐趣。 <br/><br/>　　一、概述： <br/><br/>　　我这里所指的图标程序是类似于在Windows中经常接触的停放在任务栏上，在后台运行的病毒监视、媒体播放等程序。它们一般都具有单击显示或隐藏主界面，击右键弹出菜单，当鼠标停在图标上时显示提示信息的功能。 <br/><br/>　　程序主要用到了一下几个类： <br/><br/>　　System.Windows.Fomrs.NotifyIcon类<br/><br/>　　System.Windows.Forms.ContextMenu类<br/><br/>　　System.Windows.Forms.MenuItem类<br/><br/>　　System.Windows.Forms.Label类<br/><br/>　　System.Windows.Forms.Timer类 <br/><br/>　　二、程序设计和运行的环境： <br/><br/>　　(1)微软公司视窗2000服务器版或视窗XP版 <br/><br/>　　(2).Net FrameWrok SDK Beta 2版 <br/><br/>　　三、具体实现步骤： <br/><br/>　　(1).在Visual Studio下新建一个C#的工程，不妨命名为AnimateSystemTray。图示如下： <br/><br/><br/><br/>　　(2).现在我们来设计程序的主界面： <br/><br/>　　先将窗体的Text属性设置为&#34;动画系统图标示例&#34;，MaximiseBox、MinimiseBox、ShowInTaskbar属性均设置为False。 <br/><br/>　　再往窗体上添加Label控件、NotifyIcon控件、ContextMenu控件、Timer控件各一个。 <br/><br/>　　将Label控件的Text属性设置为&#34;请右击系统托盘图标&#34;；将NotifyIcon控件的Icon属性设置为一个图标文件： ，Text属性设置为&#34;这是个示例程序！&#34;,ContextMenu属性设置为&#34;contextMenu1&#34;；接下来开始编辑ContextMenu控件，图示如下： <br/><br/><br/><br/>　　最后还要在导入两个图标 (Icon1.ico)， (Icon2.ico)文件到该项目。 <br/><br/>　　(3).现在我们开始编写代码部分： <br/><br/>　　首先在我们的类中添加以下数据成员： <br/><br/>　　private Icon m_Icon1;<br/><br/>　　private Icon m_Icon2;<br/><br/>　　private bool m_bFlag;<br/><br/>　　private bool m_bShowWnd; <br/><br/>　　修改Form1()函数为： <br/><br/>　　public Form1()<br/><br/>　　{<br/><br/>　　//<br/><br/>　　// Required for Windows Form Designer support<br/><br/>　　//<br/><br/>　　InitializeComponent();<br/><br/>　　//<br/><br/>　　// TODO: Add any constructor code after InitializeComponent call<br/><br/>　　//<br/><br/>　　m_bFlag=true;<br/><br/>　　m_bShowWnd=true;<br/><br/>　　try<br/><br/>　　{<br/><br/>　　m_Icon1 = new Icon(&#34;Icon1.ico&#34;);//导入图标文件<br/><br/>　　m_Icon2 = new Icon(&#34;Icon2.ico&#34;);<br/><br/>　　}<br/><br/>　　catch ( Exception e )<br/><br/>　　{<br/><br/>　　MessageBox.Show(&#34;Error &#34; + e.Message,&#34;Animate Tray - Error&#34;);<br/><br/>　　menuItem2.Enabled = false;<br/><br/>　　menuItem3.Enabled = false;<br/><br/>　　}<br/><br/>　　}<br/><br/>　　添加menuItem1、menuItem2、menuItem3、m_trayIcon的Click事件，消息处理函数如下：<br/><br/>　　private void menuItem1_Click(object sender, System.EventArgs e)<br/><br/>　　{<br/><br/>　　timer1.Start();//打开计时器<br/><br/>　　}<br/><br/>　　private void menuItem2_Click(object sender, System.EventArgs e)<br/><br/>　　{<br/><br/>　　timer1.Stop();//停止计时器<br/><br/>　　}<br/><br/>　　private void menuItem3_Click(object sender, System.EventArgs e)<br/><br/>　　{<br/><br/>　　Application.Exit();//退出应用程序<br/><br/>　　}<br/><br/>　　private void m_trayIcon_Click(object sender, System.EventArgs e)<br/><br/>　　{<br/><br/>　　if(m_bShowWnd == true)//隐藏主界面<br/><br/>　　{<br/><br/>　　this.Visible = false;<br/><br/>　　m_bShowWnd = false;<br/><br/>　　}<br/><br/>　　else//显示主界面<br/><br/>　　{<br/><br/>　　this.Visible = true;<br/><br/>　　m_bShowWnd = true;<br/><br/>　　}<br/><br/>　　}<br/><br/>　　最后还要添加timer1的Tick()函数： <br/><br/>　　private void timer1_Tick(object sender, System.EventArgs e)<br/><br/>　　{<br/><br/>　　if ( m_Icon1 != null &amp;&amp; m_Icon2 != null ) //如果两个图标文件都被正确载入<br/><br/>　　{<br/><br/>　　//只要timer1被启动，则在两个图标之间不断进行选择变换，实现动画效果<br/><br/>　　if ( m_bFlag == true )<br/><br/>　　{<br/><br/>　　m_trayIcon.Icon = m_Icon2;<br/><br/>　　m_bFlag = false;<br/><br/>　　}<br/><br/>　　else<br/><br/>　　{<br/><br/>　　m_trayIcon.Icon = m_Icon1;<br/><br/>　　m_bFlag = true;<br/><br/>　　}<br/><br/>　　}<br/><br/>　　} <br/><br/>　　好了，按Ctrl+F5试试效果吧！ <br/><br/>　　运行程序，将显示一个主窗口，此时还可以看到在任务栏上面多了一个图标。当鼠标移到其上停留一下时，将显示一个简单的提示信息，点击该图标则将隐藏主窗口，单击右键，出来一个菜单，选&#34;动画图标开始&#34;和&#34;动画图标结束&#34;可以控制图标状态。 <br/><br/>　　四.总结： <br/><br/>　　做完这个程序，我们不难发现用C#做一些运用程序效果是非常方便的。以前我在SDK、MFC下，用到了Shell_NotifyIcon()、TrackPopMenu()以及DestroyMenu()，还要自己添加消息处理函数，工作量是非常大的。现在微软为我们做好了这些工作，是不是很方便？快快加入C#的行列吧。 <br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/default.asp?id=2175" /> 
	  <id>http://www.cnsdn.com.cn/blog/default.asp?id=2175</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[用C#写系统托盘图标]]></title>
	  <author>
		 <name>admin</name>
		 <uri>http://www.cnsdn.com.cn/blog/</uri>
		 <email>cnsdn@163.com</email>
	  </author>
	  <category term="" scheme="http://www.cnsdn.com.cn/blog/default.asp?cateID=6" label="C#" /> 
	  <updated>2007-09-08T08:01:45+08:00</updated>
	  <published>2007-09-08T08:01:45+08:00</published>
		  <summary type="html"><![CDATA[　　本文通过向大家介绍一个.Net平台上用C#写的可以停放在任务栏上的图标程序（类似于Flashget、OICQ那种系统托盘图标）来和大家一起体验一下用C＃编程的乐趣。 <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp;一、概述： <br/>&nbsp;&nbsp; <br/>　　我这里所指的图标程序是类似于在Windows中经常接触的停放在任务栏上，在后台运行的病毒监视、媒体播放等程序。它们一般都具有单击显示或隐藏主界面，击右键弹出菜单，当鼠标停在图标上时显示提示信息的功能。 <br/>&nbsp;&nbsp; <br/>　　程序主要用到了一下几个类： <br/>&nbsp;&nbsp; <br/><br/>&nbsp;&nbsp;System.Windows.Fomrs.NotifyIcon类 <br/>&nbsp;&nbsp;System.Windows.Forms.ContextMenu类 <br/>&nbsp;&nbsp;System.Windows.Forms.MenuItem类 <br/>&nbsp;&nbsp;System.Windows.Forms.Label类 <br/>&nbsp;&nbsp;System.Windows.Forms.Timer类 <br/><br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp; 二、程序设计和运行的环境： <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp; <br/>　　（1）微软公司视窗2000服务器版或视窗XP版 <br/>&nbsp;&nbsp; <br/>　　（2）.Net FrameWrok SDK<br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp;三、具体实现步骤： <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp; <br/>　　（1）．在Visual Studio下新建一个C＃的工程，不妨命名为AnimateSystemTray。图示如下： <br/>&nbsp;&nbsp; <br/>　　（2）.现在我们来设计程序的主界面： <br/>&nbsp;&nbsp; <br/>　　先将窗体的Text属性设置为&#34;动画系统图标示例&#34;，MaximiseBox、MinimiseBox、ShowInTaskbar属性均设置为False。 <br/>&nbsp;&nbsp; <br/>　　再往窗体上添加Label控件、NotifyIcon控件、ContextMenu控件、Timer控件各一个。 <br/>&nbsp;&nbsp; <br/>　　将Label控件的Text属性设置为&#34;请右击系统托盘图标&#34;；将NotifyIcon控件的Icon属性设置为一个图标文件： ，Text属性设置为&#34;这是个示例程序！&#34;,ContextMenu属性设置为&#34;contextMenu1&#34;；接下来开始编辑ContextMenu控件，图示如下： <br/>&nbsp;&nbsp; <br/>　　最后还要在导入两个图标 (Icon1.ico)， (Icon2.ico)文件到该项目。 <br/>　　（3）.现在我们开始编写代码部分： <br/>&nbsp;&nbsp; <br/>　　首先在我们的类中添加以下数据成员： <br/>&nbsp;&nbsp; <br/> <br/> private Icon m_Icon1; <br/>&nbsp;&nbsp;private Icon m_Icon2; <br/>&nbsp;&nbsp;private bool m_bFlag; <br/>&nbsp;&nbsp;private bool m_bShowWnd; <br/><br/> <br/><br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp;修改Form1()函数为： <br/>&nbsp;&nbsp; <br/> <br/>&nbsp;&nbsp;public Form1() <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;// <br/>&nbsp;&nbsp;// Required for Windows Form Designer support <br/>&nbsp;&nbsp;// <br/>&nbsp;&nbsp;InitializeComponent(); <br/>&nbsp;&nbsp;// <br/>&nbsp;&nbsp;// TODO: Add any constructor code after InitializeComponent call <br/>&nbsp;&nbsp;// <br/>&nbsp;&nbsp;m_bFlag=true; <br/>&nbsp;&nbsp;m_bShowWnd=true; <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp;try <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;m_Icon1 = new Icon(&#34;Icon1.ico&#34;);//导入图标文件 <br/>&nbsp;&nbsp;m_Icon2 = new Icon(&#34;Icon2.ico&#34;); <br/>&nbsp;&nbsp;} <br/>&nbsp;&nbsp;catch ( Exception e ) <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;MessageBox.Show(&#34;Error &#34; + e.Message,&#34;Animate Tray - Error&#34;); <br/>&nbsp;&nbsp;menuItem2.Enabled = false; <br/>&nbsp;&nbsp;menuItem3.Enabled = false; <br/>&nbsp;&nbsp;} <br/>&nbsp;&nbsp;} <br/><br/> <br/><br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp;添加menuItem1、menuItem2、menuItem3、m_trayIcon的Click事件，消息处理函数如下： <br/> <br/>&nbsp;&nbsp;private void menuItem1_Click(object sender, System.EventArgs e) <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;timer1.Start();//打开计时器 <br/>&nbsp;&nbsp;} <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp;private void menuItem2_Click(object sender, System.EventArgs e) <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;timer1.Stop();//停止计时器 <br/>&nbsp;&nbsp;} <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp;private void menuItem3_Click(object sender, System.EventArgs e) <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;Application.Exit();//退出应用程序 <br/>&nbsp;&nbsp;} <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp;private void m_trayIcon_Click(object sender, System.EventArgs e) <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;if(m_bShowWnd == true)//隐藏主界面 <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;this.Visible = false; <br/>&nbsp;&nbsp;m_bShowWnd = false; <br/>&nbsp;&nbsp;} <br/>&nbsp;&nbsp;else//显示主界面 <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;this.Visible = true; <br/>&nbsp;&nbsp;m_bShowWnd = true; <br/>&nbsp;&nbsp;} <br/>&nbsp;&nbsp;} <br/><br/> <br/><br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp; <br/>&nbsp;&nbsp;最后还要添加timer1的Tick（）函数： <br/>&nbsp;&nbsp; <br/> <br/>&nbsp;&nbsp;private void timer1_Tick(object sender, System.EventArgs e) <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;if ( m_Icon1 != null &amp;&amp; m_Icon2 != null ) //如果两个图标文件都被正确载入 <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;//只要timer1被启动，则在两个图标之间不断进行选择变换，实现动画效果 <br/>&nbsp;&nbsp;if ( m_bFlag == true ) <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;m_trayIcon.Icon = m_Icon2; <br/>&nbsp;&nbsp;m_bFlag = false; <br/>&nbsp;&nbsp;} <br/>&nbsp;&nbsp;else <br/>&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;m_trayIcon.Icon = m_Icon1; <br/>&nbsp;&nbsp;m_bFlag = true; <br/>&nbsp;&nbsp;} <br/>&nbsp;&nbsp;} <br/>&nbsp;&nbsp;} <br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/default.asp?id=2174" /> 
	  <id>http://www.cnsdn.com.cn/blog/default.asp?id=2174</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[存储过程入门与提高]]></title>
	  <author>
		 <name>admin</name>
		 <uri>http://www.cnsdn.com.cn/blog/</uri>
		 <email>cnsdn@163.com</email>
	  </author>
	  <category term="" scheme="http://www.cnsdn.com.cn/blog/default.asp?cateID=8" label=".Net综合" /> 
	  <updated>2007-09-07T10:58:37+08:00</updated>
	  <published>2007-09-07T10:58:37+08:00</published>
		  <summary type="html"><![CDATA[存储过程入门与提高 <br/>什么是存储过程呢？<br/><br/>定义：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将常用的或很复杂的工作，预先用SQL语句写好并用一个指定的名称存储起来, 那么以后要叫数据库提供与已定义好的存储过程的功能相同的服务时,只需调用execute,即可自动完成命令。<br/><br/>讲到这里,可能有人要问：这么说存储过程就是一堆SQL语句而已啊？<br/><br/>&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft公司为什么还要添加这个技术呢?<br/><br/>那么存储过程与一般的SQL语句有什么区别呢?<br/><br/>存储过程的优点：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.存储过程只在创造时进行编译，以后每次执行存储过程都不需再重新编译，而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.当对数据库进行复杂操作时(如对多个表进行Up&#100;ate,Ins&#101;rt,Query,Del&#101;te时），可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.存储过程可以重复使用,可减少数据库开发人员的工作量<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.安全性高,可设定只有某此用户才具有对指定存储过程的使用权<br/><br/>存储过程的种类：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;1.系统存储过程：以sp_开头,用来进行系统的各项设定.取得信息.相关管理工作,<br/><br/>&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;&nbsp; 如 sp_help就是取得指定对象的相关信息<br/><br/>&nbsp;&nbsp; 2.扩展存储过程&nbsp;&nbsp; 以XP_开头,用来调用操作系统提供的功能<br/><br/>&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;&nbsp;exec master..xp_cmdshell &#39;ping 10.8.16.1&#39;<br/><br/>&nbsp;&nbsp; 3.用户自定义的存储过程,这是我们所指的存储过程<br/><br/>&nbsp;&nbsp; 常用格式<br/><br/>&nbsp;&nbsp; Cr&#101;ate procedure procedue_name<br/><br/>&nbsp;&nbsp; [@parameter data_type][output]<br/><br/>&nbsp;&nbsp; [with]{recompile|encryption}<br/><br/>&nbsp;&nbsp; as<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sql_statement<br/><br/>解释:&nbsp;&nbsp;<br/><br/>output：表示此参数是可传回的<br/><br/>with {recompile|encryption}<br/><br/>recompile:表示每次执行此存储过程时都重新编译一次<br/><br/>encryption:所创建的存储过程的内容会被加密<br/><br/>如:<br/><br/>&nbsp;&nbsp; 表book的内容如下<br/><br/>&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;&nbsp;&nbsp;&nbsp; 价格<br/><br/>&nbsp;&nbsp; 001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C语言入门&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $30<br/><br/>&nbsp;&nbsp; 002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PowerBuilder报表开发&nbsp;&nbsp;$52<br/><br/> 实例1:查询表Book的内容的存储过程<br/><br/>&nbsp;&nbsp; cr&#101;ate proc query_book<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;as <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct * from book<br/><br/>&nbsp;&nbsp; go<br/><br/>&nbsp;&nbsp; exec query_book<br/><br/> 实例2:加入一笔记录到表book,并查询此表中所有书籍的总金额<br/><br/>&nbsp;&nbsp; Cr&#101;ate proc ins&#101;rt_book<br/><br/>&nbsp;&nbsp; @param1 char(10),@param2 varchar(20),@param3 money,@param4 money output<br/><br/>&nbsp;&nbsp; with encryption&nbsp;&nbsp;---------加密<br/><br/>&nbsp;&nbsp; as<br/><br/>&nbsp;&nbsp; ins&#101;rt book(编号,书名，价格） Values(@param1,@param2,@param3)<br/>&nbsp;&nbsp; sel&#101;ct @param4=sum(价格) from book<br/>&nbsp;&nbsp;go<br/><br/>&nbsp;&nbsp;执行例子: <br/>&nbsp;&nbsp;declare @total_price money <br/>&nbsp;&nbsp;exec ins&#101;rt_book &#39;003&#39;,&#39;Delphi 控件开发指南&#39;,$100,@total_price<br/>&nbsp;&nbsp;print &#39;总金额为&#39;+convert(varchar,@total_price)<br/>&nbsp;&nbsp;go<br/>存储过程的3种传回值:<br/>&nbsp;&nbsp; 1.以Return传回整数<br/>&nbsp;&nbsp; 2.以output格式传回参数<br/>&nbsp;&nbsp; 3.Recordset<br/>传回值的区别:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output和return都可在批次程式中用变量接收,而recordset则传回到执行批次的客户端中&nbsp;&nbsp;<br/><br/>实例3：设有两个表为Product,Order,其表内容如下：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Product<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 产品编号&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 产品名称&nbsp;&nbsp;&nbsp;&nbsp;客户订数&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 钢笔&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 毛笔&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 50&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 铅笔&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o&#114;der&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 产品编号&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 客户名&nbsp;&nbsp;&nbsp;&nbsp; 客户订金<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;南山区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$30<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;罗湖区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$50<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;宝安区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$4<br/>请实现按编号为连接条件,将两个表连接成一个临时表,该表只含编号.产品名.客户名.订金.总金额,<br/>总金额=订金*订数,临时表放在存储过程中<br/><br/>代码如下:<br/>&nbsp;&nbsp;&nbsp;&nbsp; Cr&#101;ate proc temp_sale<br/>&nbsp;&nbsp;&nbsp;&nbsp; as<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sel&#101;ct a.产品编号,a.产品名称,b.客户名,b.客户订金,a.客户订数* b.客户订金 as总金额<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; into #temptable from Product a inner join o&#114;der b on a.产品编号=b.产品编号<br/>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;&nbsp;@@error=0 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &#39;Good&#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &#39;Fail&#39;<br/>&nbsp;&nbsp;&nbsp;&nbsp; go<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/default.asp?id=2173" /> 
	  <id>http://www.cnsdn.com.cn/blog/default.asp?id=2173</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[ASP与存储过程]]></title>
	  <author>
		 <name>admin</name>
		 <uri>http://www.cnsdn.com.cn/blog/</uri>
		 <email>cnsdn@163.com</email>
	  </author>
	  <category term="" scheme="http://www.cnsdn.com.cn/blog/default.asp?cateID=4" label="B/S开发" /> 
	  <updated>2007-09-06T05:56:43+08:00</updated>
	  <published>2007-09-06T05:56:43+08:00</published>
		  <summary type="html"><![CDATA[ASP与存储过程(Stored Procedures)的文章不少，但是我怀疑作者们是否真正实践过。我在初学时查阅过大量相关资料，发现其中提供的很多方法实际操作起来并不是那么回事。对于简单的应用，这些资料也许是有帮助的，但仅限于此，因为它们根本就是千篇一律，互相抄袭，稍微复杂点的应用，就全都语焉不详了。<br/>&nbsp;&nbsp;&nbsp;&nbsp;现在，我基本上通过调用存储过程访问SQL Server，以下的文字虽不敢保证绝对正确，但都是实践的总结，希望对大家能有帮助。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;存储过程就是作为可执行对象存放在数据库中的一个或多个SQL命令。<br/>&nbsp;&nbsp;&nbsp;&nbsp;定义总是很抽象。存储过程其实就是能完成一定操作的一组SQL语句，只不过这组语句是放在数据库中的(这里我们只谈SQL Server)。如果我们通过创建存储过程以及在ASP中调用存储过程，就可以避免将SQL语句同ASP代码混杂在一起。这样做的好处至少有三个：<br/>&nbsp;&nbsp;&nbsp;&nbsp;第一、大大提高效率。存储过程本身的执行速度非常快，而且，调用存储过程可以大大减少同数据库的交互次数。<br/>&nbsp;&nbsp;&nbsp;&nbsp;第二、提高安全性。假如将SQL语句混合在ASP代码中，一旦代码失密，同时也就意味着库结构失密。<br/>&nbsp;&nbsp;&nbsp;&nbsp;第三、有利于SQL语句的重用。<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;在ASP中，一般通过command对象调用存储过程，根据不同情况，本文也介绍其它调用方法。为了方便说明，根据存储过程的输入输出，作以下简单分类：<br/>&nbsp;&nbsp;&nbsp;&nbsp;1. 只返回单一记录集的存储过程<br/>&nbsp;&nbsp;&nbsp;&nbsp;假设有以下存储过程(本文的目的不在于讲述T-SQL语法，所以存储过程只给出代码，不作说明)：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/*SP1*/<br/>&nbsp;&nbsp;&nbsp;&nbsp;Cr&#101;ate PROCEDURE dbo.getUserList<br/>&nbsp;&nbsp;&nbsp;&nbsp;as<br/>&nbsp;&nbsp;&nbsp;&nbsp;set nocount on<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sel&#101;ct * from dbo.[userinfo]<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;go<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;以上存储过程取得userinfo表中的所有记录，返回一个记录集。通过command对象调用该存储过程的ASP代码如下:<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**通过Command对象调用存储过程**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm,MyRst<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MyConStr是数据库连接字串<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &#34;getUserList&#34;&nbsp;&nbsp;&nbsp;&nbsp; &#39;指定存储过程名<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;表明这是一个存储过程<br/>&nbsp;&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;&nbsp;&#39;要求将SQL命令先行编译<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyRst = MyComm.Execute<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;存储过程取得的记录集赋给MyRst，接下来，可以对MyRst进行操作。<br/>&nbsp;&nbsp;&nbsp;&nbsp;在以上代码中，CommandType属性表明请求的类型，取值及说明如下：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-1&nbsp;&nbsp; 表明CommandText参数的类型无法确定<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;表明CommandText是一般的命令类型<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;表明CommandText参数是一个存在的表名称<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;表明CommandText参数是一个存储过程的名称<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;还可以通过Connection对象或Recordset对象调用存储过程，方法分别如下：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**通过Connection对象调用存储过程**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyConn,MyRst<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyConn = Server.Cr&#101;ateObject(&#34;ADODB.Connection&#34;)<br/>&nbsp;&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;&nbsp;&#39;MyConStr是数据库连接字串<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyRst&nbsp;&nbsp;= MyConn.Execute(&#34;getUserList&#34;,0,4)&nbsp;&nbsp;&#39;最后一个参断含义同CommandType<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyConn = Nothing<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**通过Recordset对象调用存储过程**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyRst<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyRst = Server.Cr&#101;ateObject(&#34;ADODB.Recordset&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyRst.open &#34;getUserList&#34;,MyConStr,0,1,4<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;MyConStr是数据库连接字串,最后一个参断含义与CommandType相同<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;2. 没有输入输出的存储过程<br/>&nbsp;&nbsp;&nbsp;&nbsp;请看以下存储过程：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/*SP2*/<br/>&nbsp;&nbsp;&nbsp;&nbsp;Cr&#101;ate PROCEDURE dbo.delUserAll<br/>&nbsp;&nbsp;&nbsp;&nbsp;as<br/>&nbsp;&nbsp;&nbsp;&nbsp;set nocount on<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del&#101;te from dbo.[userinfo]<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;go<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;该存储过程删去userinfo表中的所有记录，没有任何输入及输出，调用方法与上面讲过的基本相同，只是不用取得记录集：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**通过Command对象调用存储过程**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MyConStr是数据库连接字串<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &#34;delUserAll&#34;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;指定存储过程名<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;表明这是一个存储过程<br/>&nbsp;&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;&nbsp;&#39;要求将SQL命令先行编译<br/>&nbsp;&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;&nbsp;&#39;此处不必再取得记录集<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing&nbsp;&nbsp;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;当然也可通过Connection对象或Recordset对象调用此类存储过程，不过建立Recordset对象是为了取得记录集，在没有返回记录集的情况下，还是利用Command对象吧。<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;3. 有返回值的存储过程<br/>&nbsp;&nbsp;&nbsp;&nbsp;在进行类似SP2的操作时，应充分利用SQL Server强大的事务处理功能，以维护数据的一致性。并且，我们可能需要存储过程返回执行情况，为此，将SP2修改如下：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/*SP3*/<br/>&nbsp;&nbsp;&nbsp;&nbsp;Cr&#101;ate PROCEDURE dbo.delUserAll<br/>&nbsp;&nbsp;&nbsp;&nbsp;as<br/>&nbsp;&nbsp;&nbsp;&nbsp;set nocount on<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BEGIN TRANSACTION<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del&#101;te from dbo.[userinfo]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF @@error=0 <br/>&nbsp;&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;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ELSE<br/>&nbsp;&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;&nbsp;end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;go<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;以上存储过程，在del&#101;te顺利执行时，返回1，否则返回0，并进行回滚操作。为了在ASP中取得返回值，需要利用Parameters集合来声明参数：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**调用带有返回值的存储过程并取得返回值**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm,MyPara<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MyConStr是数据库连接字串<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &#34;delUserAll&#34;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;指定存储过程名<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;表明这是一个存储过程<br/>&nbsp;&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;&nbsp;&#39;要求将SQL命令先行编译<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;声明返回值<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set Mypara = MyComm.Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Parameters.Append MyPara<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Execute<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;取得返回值<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM retValue<br/>&nbsp;&nbsp;&nbsp;&nbsp;retValue = MyComm(0)&nbsp;&nbsp;&nbsp;&nbsp;&#39;或retValue = MyComm.Parameters(0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;在MyComm.Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)中，各参数的含义如下：<br/>&nbsp;&nbsp;&nbsp;&nbsp;第一个参数(&#34;RETURE&#34;)为参数名。参数名可以任意设定，但一般应与存储过程中声明的参数名相同。此处是返回值，我习惯上设为&#34;RETURE&#34;；<br/>&nbsp;&nbsp;&nbsp;&nbsp;第二个参数(2)，表明该参数的数据类型，具体的类型代码请参阅ADO参考，以下给出常用的类型代码：<br/>&nbsp;&nbsp;&nbsp;&nbsp;adBigInt: 20 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;adBinary : 128 ; <br/>&nbsp;&nbsp;&nbsp;&nbsp;adBoolean: 11 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;adChar: 129 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;adDBTimeStamp: 135 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;adEmpty: 0 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;adInteger: 3 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;adSmallInt: 2 ; <br/>&nbsp;&nbsp;&nbsp;&nbsp;adTinyInt: 16 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;adVarChar: 200 ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;对于返回值，只能取整形，且-1到-99为保留值；<br/>&nbsp;&nbsp;&nbsp;&nbsp;第三个参数(4)，表明参数的性质，此处4表明这是一个返回值。此参数取值的说明如下：<br/>&nbsp;&nbsp;&nbsp;&nbsp;0 : 类型无法确定； 1: 输入参数；2: 输入参数；3：输入或输出参数；4: 返回值<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;以上给出的ASP代码，应该说是完整的代码，也即最复杂的代码，其实<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;Set Mypara = MyComm.Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Parameters.Append MyPara<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;可以简化为<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Parameters.Append MyComm.Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;甚至还可以继续简化，稍后会做说明。<br/>&nbsp;&nbsp;&nbsp;&nbsp;对于带参数的存储过程，只能使用Command对象调用(也有资料说可通过Connection对象或Recordset对象调用，但我没有试成过)。<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;4. 有输入参数和输出参数的存储过程<br/>&nbsp;&nbsp;&nbsp;&nbsp;返回值其实是一种特殊的输出参数。在大多数情况下，我们用到的是同时有输入及输出参数的存储过程，比如我们想取得用户信息表中，某ID用户的用户名，这时候，有一个输入参数----用户ID，和一个输出参数----用户名。实现这一功能的存储过程如下：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/*SP4*/<br/>&nbsp;&nbsp;&nbsp;&nbsp;Cr&#101;ate 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;&nbsp;as<br/>&nbsp;&nbsp;&nbsp;&nbsp;set nocount on<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if @UserID is null return<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sel&#101;ct @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; wh&#101;re userid=@UserID<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;go<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;调用该存储过程的ASP代码如下：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**调用带有输入输出参数的存储过程**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm,UserID,UserName<br/>&nbsp;&nbsp;&nbsp;&nbsp;UserID = 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MyConStr是数据库连接字串<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &#34;getUserName&#34;&nbsp;&nbsp;&nbsp;&nbsp; &#39;指定存储过程名<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;表明这是一个存储过程<br/>&nbsp;&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;&nbsp;&#39;要求将SQL命令先行编译<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;声明参数<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Parameters.append MyComm.Cr&#101;ateParameter(&#34;@UserID&#34;,3,1,4,UserID)<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Parameters.append MyComm.Cr&#101;ateParameter(&#34;@UserName&#34;,200,2,40)<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Execute<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;取得出参<br/>&nbsp;&nbsp;&nbsp;&nbsp;UserName = MyComm(1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;在以上代码中，可以看到，与声明返回值不同，声明输入参数时需要5个参数，声明输出参数时需要4个参数。声明输入参数时5个参数分别为：参数名、参数数据类型、参数类型、数据长度、参数值。声明输出参数时，没有最后一个参数：参数值。<br/>&nbsp;&nbsp;&nbsp;&nbsp;需要特别注意的是：在声明参数时，顺序一定要与存储过程中定义的顺序相同，而且各参数的数据类型、长度也要与存储过程中定义的相同。<br/>&nbsp;&nbsp;&nbsp;&nbsp;如果存储过程有多个参数，ASP代码会显得繁琐，可以使用with命令简化代码：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**调用带有输入输出参数的存储过程(简化代码)**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm,UserID,UserName<br/>&nbsp;&nbsp;&nbsp;&nbsp;UserID = 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;with MyComm<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MyConStr是数据库连接字串<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &#34;getUserName&#34;&nbsp;&nbsp;&nbsp;&nbsp; &#39;指定存储过程名<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;表明这是一个存储过程<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;&nbsp;&#39;要求将SQL命令先行编译<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .Cr&#101;ateParameter(&#34;@UserID&#34;,3,1,4,UserID)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .Cr&#101;ateParameter(&#34;@UserName&#34;,200,2,40)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Execute<br/>&nbsp;&nbsp;&nbsp;&nbsp;end with<br/>&nbsp;&nbsp;&nbsp;&nbsp;UserName = MyComm(1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;假如我们要取得ID为1到10，10位用户的用户名，是不是要创建10次Command对象呢？不是的。如果需要多次调用同一存储过程，只需改变输入参数，就会得到不同的输出：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**多次调用同一存储过程**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm,UserID,UserName<br/>&nbsp;&nbsp;&nbsp;&nbsp;UserName = &#34;&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&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;&nbsp;.ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MyConStr是数据库连接字串<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &#34;getUserName&#34;&nbsp;&nbsp;&nbsp;&nbsp; &#39;指定存储过程名<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;表明这是一个存储过程<br/>&nbsp;&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;&nbsp;&#39;要求将SQL命令先行编译<br/>&nbsp;&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 .Cr&#101;ateParameter(&#34;@UserID&#34;,3,1,4,UserID)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .Cr&#101;ateParameter(&#34;@UserName&#34;,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;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;重新给入参赋值(此时参数值不发生变化的入参以及出参不必重新声明)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters(&#34;@UserID&#34;) = 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;&nbsp;end if<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end with<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserName = UserName + MyComm(1) + &#34;,&#34;&nbsp;&nbsp;&nbsp;&nbsp;&#39;也许你喜欢用数组存储<br/>&nbsp;&nbsp;&nbsp;&nbsp;next<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;通过以上代码可以看出：重复调用同一存储过程时，只需为值发生改变的输入参数重新赋值即可，这一方法在有多个输入输出参数，且每次调用时只有一个输入参数的值发生变化时，可以大大减少代码量。<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;5. 同时具有返回值、输入参数、输出参数的存储过程<br/>&nbsp;&nbsp;&nbsp;&nbsp;前面说过，在调用存储过程时，声明参数的顺序要与存储过程中定义的顺序相同。还有一点要特别注意：如果存储过程同时具有返回值以及输入、输出参数，返回值要最先声明。<br/>&nbsp;&nbsp;&nbsp;&nbsp;为了演示这种情况下的调用方法，我们改善一下上面的例子。还是取得ID为1的用户的用户名，但是有可能该用户不存在(该用户已删除，而userid是自增长的字段)。存储过程根据用户存在与否，返回不同的值。此时，存储过程和ASP代码如下：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/*SP5*/<br/>&nbsp;&nbsp;&nbsp;&nbsp;Cr&#101;ate PROCEDURE dbo.getUserName<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --为了加深对&#34;顺序&#34;的印象，将以下两参数的定义顺序颠倒一下<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @UserName varchar(40) output,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @UserID int<br/>&nbsp;&nbsp;&nbsp;&nbsp;as<br/>&nbsp;&nbsp;&nbsp;&nbsp;set nocount on<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if @UserID is null return<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sel&#101;ct @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; wh&#101;re userid=@UserID<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if @@rowcount&gt;0<br/>&nbsp;&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;&nbsp;return 0<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;go<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**调用同时具有返回值、输入参数、输出参数的存储过程**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm,UserID,UserName<br/>&nbsp;&nbsp;&nbsp;&nbsp;UserID = 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;with MyComm<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MyConStr是数据库连接字串<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &#34;getUserName&#34;&nbsp;&nbsp;&nbsp;&nbsp; &#39;指定存储过程名<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;表明这是一个存储过程<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;&nbsp;&#39;要求将SQL命令先行编译<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;返回值要最先被声明<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.Append .Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;以下两参数的声明顺序也做相应颠倒<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .Cr&#101;ateParameter(&#34;@UserName&#34;,200,2,40)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .Cr&#101;ateParameter(&#34;@UserID&#34;,3,1,4,UserID)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Execute<br/>&nbsp;&nbsp;&nbsp;&nbsp;end with<br/>&nbsp;&nbsp;&nbsp;&nbsp;if MyComm(0) = 1 then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserName = MyComm(1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserName = &#34;该用户不存在&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;end if<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;6. 同时返回参数和记录集的存储过程<br/>&nbsp;&nbsp;&nbsp;&nbsp;有时候，我们需要存储过程同时返回参数和记录集，比如在利用存储过程分页时，要同时返回记录集以及数据总量等参数。以下给出一个进行分页处理的存储过程：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/*SP6*/<br/>&nbsp;&nbsp;&nbsp;&nbsp;Cr&#101;ate PROCEDURE dbo.getUserList<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @iPageCount int OUTPUT,&nbsp;&nbsp; --总页数<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @iPage int,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --当前页号<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @iPageSize int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--每页记录数<br/>&nbsp;&nbsp;&nbsp;&nbsp;as<br/>&nbsp;&nbsp;&nbsp;&nbsp;set nocount on<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --创建临时表 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cr&#101;ate table #t (ID int IDENTITY,&nbsp;&nbsp; --自增字段<br/>&nbsp;&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;&nbsp;username varchar(40))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --向临时表中写入数据<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ins&#101;rt into #t <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct userid,username from dbo.[UserInfo]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&#114;der by userid<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --取得记录总数 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; declare @iRecordCount int<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set @iRecordCount = @@rowcount<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --确定总页数<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF @iRecordCount%@iPageSize=0<br/>&nbsp;&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;&nbsp;SET @iPageCount=CEILING(@iRecordCount/@iPageSize)+1<br/> <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --若请求的页号大于总页数，则显示最后一页<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF @iPage &gt; @iPageCount<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ct @iPage = @iPageCount<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --确定当前页的始末记录<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DECLARE @iStart int&nbsp;&nbsp;&nbsp;&nbsp;--start record<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DECLARE @iEnd int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--end record<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sel&#101;ct @iStart = (@iPage - 1) * @iPageSize<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sel&#101;ct @iEnd = @iStart + @iPageSize + 1<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --取当前页记录&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sel&#101;ct * from #t wh&#101;re ID&gt;@iStart and ID&lt;@iEnd<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --删除临时表<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dro&#112; TABLE #t<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --返回记录总数<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return @iRecordCount<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;go<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;在上面的存储过程中，输入当前页号及每页记录数，返回当前页的记录集，总页数及记录总数。为了更具典型性，将记录总数以返回值的形式返回。以下是调用该存储过程的ASP代码(具体的分页操作略去):<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**调用分页存储过程**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM pagenow,pagesize,pagecount,recordcount<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm,MyRst<br/>&nbsp;&nbsp;&nbsp;&nbsp;pagenow = Request(&#34;pn&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;自定义函数用于验证自然数<br/>&nbsp;&nbsp;&nbsp;&nbsp;if CheckNar(pagenow) = false then pagenow = 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;pagesize = 20<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;with MyComm<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MyConStr是数据库连接字串<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &#34;getUserList&#34;&nbsp;&nbsp;&nbsp;&nbsp; &#39;指定存储过程名<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;表明这是一个存储过程<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;&nbsp;&#39;要求将SQL命令先行编译<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;返回值(记录总量) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.Append .Cr&#101;ateParameter(&#34;RETURN&#34;,2,4)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;出参(总页数)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.Append .Cr&#101;ateParameter(&#34;@iPageCount&#34;,3,2)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;入参(当前页号)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .Cr&#101;ateParameter(&#34;@iPage&#34;,3,1,4,pagenow)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;入参(每页记录数)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .Cr&#101;ateParameter(&#34;@iPageSize&#34;,3,1,4,pagesize)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set MyRst = .Execute<br/>&nbsp;&nbsp;&nbsp;&nbsp;end with<br/>&nbsp;&nbsp;&nbsp;&nbsp;if MyRst.state = 0 then&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;未取到数据，MyRst关闭<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; recordcount = -1<br/>&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyRst.close&nbsp;&nbsp;&nbsp;&nbsp;&#39;注意：若要取得参数值，需先关闭记录集对象<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;&nbsp;end if<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;以下显示记录<br/>&nbsp;&nbsp;&nbsp;&nbsp;if recordcount = 0 then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &#34;无记录&#34;<br/>&nbsp;&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; &#39;以下显示分页信息<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......<br/>&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&#39;recordcount=-1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &#34;参数错误&#34;<br/>&nbsp;&nbsp;&nbsp;&nbsp;end if<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;对于以上代码，只有一点需要说明：同时返回记录集和参数时，若要取得参数，需先将记录集关闭，使用记录集时再将其打开。<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;7. 返回多个记录集的存储过程<br/>&nbsp;&nbsp;&nbsp;&nbsp;本文最先介绍的是返回记录集的存储过程。有时候，需要一个存储过程返回多个记录集，在ASP中，如何同时取得这些记录集呢？为了说明这一问题，在userinfo表中增加两个字段：usertel及usermail，并设定只有登录用户可以查看这两项内容。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;/*SP7*/<br/>&nbsp;&nbsp;&nbsp;&nbsp;Cr&#101;ate 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;&nbsp;as<br/>&nbsp;&nbsp;&nbsp;&nbsp;set nocount on<br/>&nbsp;&nbsp;&nbsp;&nbsp;begin<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if @userid is null o&#114; @checklogin is null return<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sel&#101;ct username<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from dbo.[usrinfo]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wh&#101;re userid=@userid<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --若为登录用户，取usertel及usermail<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if @checklogin=1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sel&#101;ct 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; wh&#101;re userid=@userid<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;go<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;以下是ASP代码：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;**调用返回多个记录集的存储过程**<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM checklg,UserID,UserName,UserTel,UserMail<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm,MyRst<br/>&nbsp;&nbsp;&nbsp;&nbsp;UserID = 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;checklogin()为自定义函数，判断访问者是否登录<br/>&nbsp;&nbsp;&nbsp;&nbsp;checklg = checklogin()<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;with MyComm<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ActiveConnection = MyConStr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;MyConStr是数据库连接字串<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= &#34;getUserInfo&#34;&nbsp;&nbsp;&nbsp;&nbsp; &#39;指定存储过程名<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .CommandType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;= 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;表明这是一个存储过程<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;&nbsp;&#39;要求将SQL命令先行编译<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .Cr&#101;ateParameter(&#34;@userid&#34;,3,1,4,UserID)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .Parameters.append .Cr&#101;ateParameter(&#34;@checklogin&#34;,11,1,1,checklg)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set MyRst = .Execute<br/>&nbsp;&nbsp;&nbsp;&nbsp;end with<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;从第一个记录集中取值<br/>&nbsp;&nbsp;&nbsp;&nbsp;UserName = MyRst(0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;从第二个记录集中取值<br/>&nbsp;&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;&nbsp;= MyRst(0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserMail = MyRst(1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;end if<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyRst = Nothing<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;以上代码中，利用Recordset对象的NextRecordset方法，取得了存储过程返回的多个记录集。<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;至此，针对ASP调用存储过程的各种情况，本文已做了较为全面的说明。最后说一下在一个ASP程序中，调用多个存储过程的不同方法。<br/>&nbsp;&nbsp;&nbsp;&nbsp;在一个ASP程序中，调用多个存储过程至少有以下三种方法是可行的：<br/>&nbsp;&nbsp;&nbsp;&nbsp;1. 创建多个Command对象<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;调用存储过程一<br/>&nbsp;&nbsp;&nbsp;&nbsp;......<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;调用存储过程二<br/>&nbsp;&nbsp;&nbsp;&nbsp;......<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/>&nbsp;&nbsp;&nbsp;&nbsp;......<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;2. 只创建一个Command对象，结束一次调用时，清除其参数<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;调用存储过程一<br/>&nbsp;&nbsp;&nbsp;&nbsp;.....<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;清除参数(假设有三个参数)<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Parameters.del&#101;te 2<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Parameters.del&#101;te 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Parameters.del&#101;te 0<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;调用存储过程二并清除参数<br/>&nbsp;&nbsp;&nbsp;&nbsp;......<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;此时要注意：清除参数的顺序与参数声明的顺序相反，原因嘛，我也不知道。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;3. 利用Parameters数据集合的Refresh方法重置Parameter对象<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;DIM MyComm<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Server.Cr&#101;ateObject(&#34;ADODB.Command&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;调用存储过程一<br/>&nbsp;&nbsp;&nbsp;&nbsp;.....<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;重置Parameters数据集合中包含的所有Parameter对象<br/>&nbsp;&nbsp;&nbsp;&nbsp;MyComm.Parameters.Refresh<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#39;调用存储过程二<br/>&nbsp;&nbsp;&nbsp;&nbsp;.....<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set MyComm = Nothing<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;一般认为，重复创建对象是效率较低的一种方法，但是经测试(测试工具为Microsoft Application Center Test)，结果出人意料：<br/>&nbsp;&nbsp;&nbsp;&nbsp;方法2 &gt;= 方法1 &gt;&gt; 方法3<br/>&nbsp;&nbsp;&nbsp;&nbsp;方法2的运行速度大于等于方法1(最多可高4%左右)，这两种方法的运行速度远大于方法3(最多竟高达130%)，所以建议在参数多时，采用方法1，在参数较少时，采用方法2。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;花了一天的时间，终于把我对于在ASP中调用存储过程的一些粗浅的经验形成了文字。这其中，有些是我只知其果而不明其因的，有些可能是错误的，但是，这些都是经过我亲身实践的。各位看官批判地接受吧。有不同意见，希望一定向我指明，先谢了<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/default.asp?id=2172" /> 
	  <id>http://www.cnsdn.com.cn/blog/default.asp?id=2172</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[ASP.Net+XML打造留言薄]]></title>
	  <author>
		 <name>admin</name>
		 <uri>http://www.cnsdn.com.cn/blog/</uri>
		 <email>cnsdn@163.com</email>
	  </author>
	  <category term="" scheme="http://www.cnsdn.com.cn/blog/default.asp?cateID=5" label="Asp.Net" /> 
	  <updated>2007-09-05T04:38:08+08:00</updated>
	  <published>2007-09-05T04:38:08+08:00</published>
		  <summary type="html"><![CDATA[　　一．概述：<br/><br/>　　留言簿是网站的一个重要组成部分，是访问者发表意见的场所，也是网站管理员了解网站基本运行情况的有力工具，所以留言簿在现在的网站中扮演了十分重要的角色。<br/><br/>　　不过在以前开发一个留言簿并不是一件容易的事，开发者的工作量往往会很大。而现在随着微软推出VS.NET，相应的技术也推陈出新。特别是XML技术在.NET Framework中的广泛运用，使得整个.NET构架具有十分优越的基础。而ASP.NET中推出的崭新的编程模型更使得开发Web应用程序变得非常容易。本文就结合ASP.NET技术和XML技术的优点向大家介绍如何打造一个属于自己的留言簿。<br/><br/>　　二．实现方法：<br/><br/>　　一个基本的留言簿应至少包括两个功能：接受用户输入的信息并保存该信息到后台数据库；显示用户输入的信息。用户输入的信息一般包括用户名、Email地址、QQ号码、用户主页、留言信息等，这些信息通常是保存在后台数据库的某个表中的，不过本文要运用一个XML文件来存储这些信息。显示用户输入的信息时一般得把所有的信息都显示出来，这里的方法就是从XML文件中读取数据并运用XSLT技术对其进行格式转换，最后以HTML的形式显示在浏览器中。<br/><br/>　　这样，我们的留言簿就需要两个Web页面，一个用于接受用户的输入信息，另一个用于显示用户已经输入过的信息。而存储信息的XML文件（guestbook.xml）则需具有如下的结构：<br/><br/>&lt;?xml version=&#34;1.0&#34; encoding=&#34;GB2312&#34;?&gt;<br/>&lt;guestbook&gt;<br/>&lt;guest&gt;<br/>&lt;name&gt;令狐冲&lt;/name&gt;<br/>&lt;email&gt;doose@etang.com&lt;/email&gt;<br/>&lt;qq&gt;10102350&lt;/qq&gt;<br/>&lt;homepage&gt;www.doose.com&lt;/homepage&gt;<br/>&lt;comment&gt;本留言簿由&#34;令狐冲&#34;创建，希望你能喜欢哦：）要知道如何创建一个属于自己的留言簿，那么就请仔细阅读《运用ASP.NET和XML技术打造留言簿》一文！&lt;/comment&gt;<br/>&lt;/guest&gt;<br/>&lt;/guestbook&gt; <br/><br/>　　下面我们先来创建用于接受用户输入信息的Web页面－GuestBook.aspx。根据前面所提的基本要求，该Web页面包括了以下几个部分：留言簿标题、&#34;用户名：&#34;标签及输入框、&#34;Email地址：&#34;标签及输入框、&#34;QQ号码：&#34;标签及输入框、&#34;个人主页：&#34;标签及输入框、&#34;留言信息：&#34;标签及输入框、一个&#34;确定&#34;按钮、一个&#34;重置&#34;按钮、一个&#34;查看留言簿&#34;按钮，同时该页面还包括了两个验证按钮，分别用于验证用户名以及Email地址是否为空，若为空，则提醒用户输入。同时，为使留言簿具有良好的用户界面，我运用了表格进行页面布置，这样留言簿中的各个成分就能有条有理，层次分明了。有关该Web页面的详细代码请参考文后附带的源代码，这里就不给出了。<br/><img src="http://www.hackhome.com/upimg/2006-06-12/143804_01_689.gif" border="0" alt=""/><br/><br/>　　完成了该Web页面的布置，我们仅仅是完成了一部分的工作，到此为止我们并没有进行过真正的编码。我想大家对ASP.NET中的代码后置技术肯定是了解或熟悉的，它将Web页面的布置工作和后端的编码工作区分开来，达到了良好的分离效果。下面我们就为该Web页面中的三个按钮分别编写消息相应函数：<br/><br/>private void btnOK_Click(object sender, System.EventArgs e)<br/>{<br/>SaveXMLData();<br/><br/>name.Text = &#34;&#34;;<br/>email.Text = &#34;&#34;;<br/>qq.Text = &#34;&#34;;<br/>homepage.Text = &#34;&#34;;<br/>comment.Text = &#34;&#34;;<br/>}<br/><br/>private void btnReset_Click(object sender, System.EventArgs e)<br/>{<br/>name.Text = &#34;&#34;;<br/>email.Text = &#34;&#34;;<br/>qq.Text = &#34;&#34;;<br/>homepage.Text = &#34;&#34;;<br/>comment.Text = &#34;&#34;;<br/>}<br/><br/>private void btnView_Click(object sender, System.EventArgs e)<br/>{<br/>// 显示所有用户的留言信息<br/>Response.Redirect( &#34;ViewGuestBook.aspx&#34; );<br/>} <br/><br/>　　其中，第一个按钮是最重要的，它能将用户的输入信息存储到XML文件中，调用的方法就是SaveXMLData（）；而第二个按钮仅仅完成文本框的重置清空工作；第三个按钮的作用是运用另一个Web页面显示所有的用户输入信息。同时，第一个按钮在成功保存信息后也会将浏览器导向到显示所有用户输入信息的页面。<br/>　　下面我们来详细分析一下SaveXMLData（）方法，其实现如下：<br/><br/>private void SaveXMLData()<br/>{<br/>try<br/>{<br/>// 创建一个XmlDocument对象，用于载入存储信息的XML文件<br/>XmlDocument xdoc = new XmlDocument();<br/>xdoc.Load( Server.MapPath( &#34;guestbook.xml&#34; ));<br/><br/>// 创建一个新的guest节点并将它添加到根节点下<br/>XmlElement parentNode = xdoc.Cr&#101;ateElement( &#34;guest&#34; );<br/>xdoc.DocumentElement.PrependChild( parentNode );<br/><br/>// 创建所有用于存储信息的节点<br/>XmlElement nameNode = xdoc.Cr&#101;ateElement( &#34;name&#34; );<br/>XmlElement emailNode = xdoc.Cr&#101;ateElement( &#34;email&#34; );<br/>XmlElement qqNode = xdoc.Cr&#101;ateElement( &#34;qq&#34; );<br/>XmlElement homepageNode = xdoc.Cr&#101;ateElement( &#34;homepage&#34; );<br/>XmlElement commentNode = xdoc.Cr&#101;ateElement( &#34;comment&#34; );<br/><br/>// 获取文本信息<br/>XmlText nameText = xdoc.Cr&#101;ateTextNode( name.Text );<br/>XmlText emailText = xdoc.Cr&#101;ateTextNode( email.Text );<br/>XmlText qqText = xdoc.Cr&#101;ateTextNode( qq.Text );<br/>XmlText homepageText = xdoc.Cr&#101;ateTextNode( homepage.Text );<br/>XmlText commentText = xdoc.Cr&#101;ateTextNode( comment.Text );<br/><br/>// 将上面创建的各个存储信息的节点添加到guest节点下但并不包含最终的值<br/>parentNode.AppendChild( nameNode );<br/>parentNode.AppendChild( emailNode );<br/>parentNode.AppendChild( qqNode );<br/>parentNode.AppendChild( homepageNode );<br/>parentNode.AppendChild( commentNode );<br/><br/>// 将上面获取的文本信息添加到与之相对应的节点中<br/>nameNode.AppendChild( nameText );<br/>emailNode.AppendChild( emailText );<br/>qqNode.AppendChild( qqText );<br/>homepageNode.AppendChild( homepageText );<br/>commentNode.AppendChild( commentText );<br/><br/>// 保存存储信息的XML文件<br/>xdoc.Save( Server.MapPath( &#34;guestbook.xml&#34; ));<br/><br/>// 显示所有用户的留言信息<br/>Response.Redirect( &#34;ViewGuestBook.aspx&#34; );<br/>}<br/>catch( Exception e ) {}<br/>} <br/><br/>　　该方法主要运用了XmlDocument类、XmlElement类以及XmlText类等，这些类都是包含在System.Xml命名空间中的，所以请在代码文件的开头处添加using System.Xml的语句。该方法运用了一个try-catch语句块，在try部分首先通过创建一个XmlDocument对象来载入XML文件，然后创建根节点的儿子－guest节点并在guest节点下添加存储信息所必须的五个子节点。所有这些子节点都是XmlElement对象，它们是通过XmlDocument对象的Cr&#101;ateElement（）方法来获取的。同时，XmlDocument对象还通过Cr&#101;ateTextNode（）方法来获取文本信息并在后面将其添加到相对应的节点中。在合理的添加guest节点及其子节点以及文本信息后，XmlDocument对象通过Save（）方法将用户输入的信息保存到XML文件中。最后，浏览器会导向到显示所有用户输入信息的页面。这样，该Web页面运行的效果如图2所示：<br/><br/><img src="http://www.hackhome.com/upimg/2006-06-12/143806_02_965.gif" border="0" alt=""/><br/>　　下面我们来创建用于显示所有用户输入信息的页面－ViewGuestBook.aspx。在该Web页面中，我们要运用到XSLT技术，它能将前面创建的XML文件中的数据以HTML的形式显示出来。由于是运用XSLT技术显示用户输入信息的，所以在设计该Web页面时我们无需添加任何Web控件，只要重载该Web页面的Load（）方法即可。<br/><br/>private void Page_Load(object sender, System.EventArgs e)<br/>{<br/>// 创建一个XmlDocument对象以载入存储信息的XML文件<br/>XmlDocument xdoc = new XmlDocument();<br/>xdoc.Load( Server.MapPath( &#34;guestbook.xml&#34; ));<br/><br/>// 创建一个XslTransform对象并导入XSL文件<br/>XslTransform xslt = new XslTransform();<br/>xslt.Load( Server.MapPath( &#34;guestbook.xsl&#34; ));<br/><br/>string xmlQuery = &#34;//guestbook&#34;;<br/>XmlNodeList nodeList = xdoc.DocumentElement.Sel&#101;ctNodes( xmlQuery );<br/><br/>MemoryStream ms = new MemoryStream();<br/>xslt.Transform( xdoc, null, ms );<br/>ms.Seek( 0, SeekOrigin.Begin );<br/><br/>StreamReader sr = new StreamReader( ms );<br/><br/>// 显示输出结果<br/>Response.Write( sr.ReadToEnd() );<br/>} <br/><br/>　　该方法首先创建一个XmlDocument对象用于载入前面创建的XML数据文件，之后创建一个XslTransform对象并导入相应的XSL文件。通过该XSL文件中的内容它能将原来的XML文件中的数据格式化为HTML的形式并显示在浏览器中。因为其中运用到了XSLT转换，所以我们还得在代码文件的开头处添加using System.Xml.Xsl的语句。<br/><br/>　　下面便是XSL文件的源代码，其中最重要的部分是&lt;xsl:template match=&#34;name&#34;&gt;……&lt;/xsl:template&gt;一块。<br/><br/>&lt;xsl:stylesheet xmlns:xsl=&#34;<a href="http://www.w3.org/1999/XSL/Transform" target="_blank">http://www.w3.org/1999/XSL/Transform</a>&#34; version=&#34;1.0&#34;&gt;<br/>&lt;xsl:template match=&#34;/&#34;&gt;<br/>&lt;table border=&#34;1&#34; style=&#34;border-collapse: collapse&#34; bordercolor=&#34;Teal&#34; align=&#34;center&#34; width=&#34;505&#34; height=&#34;34&#34;&gt; <br/>&lt;tr&gt;<br/>&lt;td valign=&#34;middle&#34; align=&#34;center&#34; bgcolor=&#34;Teal&#34; colspan=&#34;2&#34; width=&#34;505&#34; height=&#34;85&#34;&gt;<br/>&lt;font style=&#34;color:White;background-color:Teal;font-family:华文行楷;font-size:X-Large;font-weight:bold;&#34;&gt;欢迎访问&#34;令狐冲&#34;的留言簿！&lt;/font&gt;<br/>&lt;/td&gt;<br/>&lt;/tr&gt;<br/>&lt;tr&gt;&lt;td width=&#34;505&#34; height=&#34;26&#34; align=&#34;left&#34; colspan=&#34;2&#34;&gt;&lt;/td&gt;&lt;/tr&gt;<br/>&lt;xsl:for-each sel&#101;ct=&#34;//guest&#34;&gt;<br/>&lt;xsl:apply-templates sel&#101;ct=&#34;name&#34;/&gt; <br/>&lt;/xsl:for-each&gt;<br/>&lt;tr&gt;<br/>&lt;td valign=&#34;middle&#34; align=&#34;center&#34; colspan=&#34;2&#34; width=&#34;505&#34;&gt;<br/>&lt;font&gt;<br/>本留言簿由&lt;a href=&#34;mailto:0024108@fudan.edu.cn&#34;&gt;王凯明&lt;/a&gt;开发！ &lt;/font&gt;<br/>&lt;/td&gt;<br/>&lt;/tr&gt;<br/>&lt;/table&gt;<br/>&lt;/xsl:template&gt;<br/>&lt;xsl:template match=&#34;name&#34;&gt;<br/>&lt;tr&gt;<br/>&lt;td width=&#34;95&#34; height=&#34;26&#34; align=&#34;right&#34;&gt;<br/>&lt;font&gt;用户名：&lt;/font&gt;<br/>&lt;/td&gt;<br/>&lt;td width=&#34;400&#34; height=&#34;26&#34; valign=&#34;middle&#34; align=&#34;left&#34;&gt;<br/>&lt;font&gt;&lt;xsl:value-of sel&#101;ct=&#39;.&#39;/&gt;&lt;/font&gt;<br/>&lt;/td&gt;<br/>&lt;/tr&gt;<br/>&lt;tr&gt;<br/>&lt;td width=&#34;95&#34; height=&#34;26&#34; align=&#34;right&#34; bgcolor=&#34;e0e0e0&#34;&gt;<br/>&lt;font&gt;Email地址：&lt;/font&gt;<br/>&lt;/td&gt;<br/>&lt;td width=&#34;400&#34; height=&#34;26&#34; valign=&#34;middle&#34; align=&#34;left&#34; bgcolor=&#34;#e0e0e0&#34;&gt;<br/>&lt;font&gt;&lt;a HREF=&#34;mailto:{../email}&#34;&gt;&lt;xsl:apply-templates sel&#101;ct=&#34;../email&#34;/&gt;&lt;/a&gt;&lt;/font&gt;<br/>&lt;/td&gt; <br/>&lt;/tr&gt;<br/>&lt;tr&gt;<br/>&lt;td width=&#34;95&#34; height=&#34;26&#34; align=&#34;right&#34;&gt;<br/>&lt;font&gt;QQ号码：&lt;/font&gt;<br/>&lt;/td&gt;<br/>&lt;td width=&#34;400&#34; height=&#34;26&#34; valign=&#34;middle&#34; align=&#34;left&#34;&gt;<br/>&lt;font&gt;&lt;xsl:apply-templates sel&#101;ct=&#34;../qq&#34;/&gt;&lt;/font&gt;<br/>&lt;/td&gt;<br/>&lt;/tr&gt;<br/>&lt;tr&gt;<br/>&lt;td width=&#34;95&#34; height=&#34;26&#34; align=&#34;right&#34; bgcolor=&#34;#e0e0e0&#34;&gt;<br/>&lt;font&gt;个人主页：&lt;/font&gt;<br/>&lt;/td&gt;<br/>&lt;td width=&#34;400&#34; height=&#34;26&#34; valign=&#34;middle&#34; align=&#34;left&#34; bgcolor=&#34;#e0e0e0&#34;&gt;<br/>&lt;font&gt;&lt;a HREF=&#34;<a href="http://" target="_blank">http://</a>{../homepage}&#34; target=&#34;_blank&#34;&gt;&lt;xsl:apply-templates sel&#101;ct=&#34;../homepage&#34;/&gt;&lt;/a&gt;&lt;/font&gt;<br/>&lt;/td&gt; <br/>&lt;/tr&gt;<br/>&lt;tr&gt;<br/>&lt;td width=&#34;95&#34; height=&#34;26&#34; valign=&#34;top&#34; align=&#34;right&#34;&gt;<br/>&lt;font&gt;留言信息：&lt;/font&gt;<br/>&lt;/td&gt;<br/>&lt;td width=&#34;400&#34; height=&#34;26&#34; valign=&#34;top&#34; align=&#34;left&#34;&gt;<br/>&lt;font&gt;&lt;xsl:apply-templates sel&#101;ct=&#34;../comment&#34;/&gt;&lt;/font&gt;<br/>&lt;/td&gt; <br/>&lt;/tr&gt;<br/>&lt;tr&gt;&lt;td width=&#34;505&#34; height=&#34;26&#34; align=&#34;left&#34; colspan=&#34;2&#34;&gt;&lt;/td&gt;&lt;/tr&gt;<br/>&lt;/xsl:template&gt;<br/>&lt;/xsl:stylesheet&gt; <br/><br/>　　这样，当用户点击&#34;查看留言簿&#34;按钮或是成功输入信息后浏览器便导向到该显示所有用户输入信息的Web页面，其运行效果图示如下：<br/><br/><img src="http://www.hackhome.com/upimg/2006-06-12/143808_03_520.gif" border="0" alt=""/><br/>　　三．总结：<br/><br/>　　这样，一个具有基本功能的留言簿就完成了，从中我们可以体会到运用ASP.NET技术开发Web应用程序是相当容易的，同时在结合了XML技术之后，ASP.NET可以变得更加强大。还有文章中介绍的XSLT技术是非常有用的，你可以参考其它相关的更多资料以使它成为你开发过程中的一个有力工具。<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/default.asp?id=2170" /> 
	  <id>http://www.cnsdn.com.cn/blog/default.asp?id=2170</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[.net环境下如何使用MySql数据库(原创) ]]></title>
	  <author>
		 <name>admin</name>
		 <uri>http://www.cnsdn.com.cn/blog/</uri>
		 <email>cnsdn@163.com</email>
	  </author>
	  <category term="" scheme="http://www.cnsdn.com.cn/blog/default.asp?cateID=5" label="Asp.Net" /> 
	  <updated>2007-09-04T10:52:21+08:00</updated>
	  <published>2007-09-04T10:52:21+08:00</published>
		  <summary type="html"><![CDATA[在网上看到一篇关于Asp.net和mysql的文章，mysql安装和.NET中连接MySQL数据库的方法详细请看《ASP.NET+MySQL简明图示入门》<a href="http://www.yesky.com/431/1944431.shtml" target="_blank">http://www.yesky.com/431/1944431.shtml</a>用vb.net写的，我现在把代码改为C#的，数据库也使用了mysql5.0<br/><br/>这里我使用EMS Mysql Manager lite工具管理mysql5.0<br/> 如图:<br/><img src="http://www.cnblogs.com/images/cnblogs_com/halgogo/4.jpg" border="0" alt=""/><br/>这里我数据库和表已经建好，现在打开vs.net2003,新建一个项目mysqltest<br/><img src="http://www.cnblogs.com/images/cnblogs_com/halgogo/3.jpg" border="0" alt=""/><br/>现在我们安装MySQL Connector/Net<br/><br/>具体安装方法请看《ASP.NET+MySQL简明图示入门》<a href="http://www.yesky.com/431/1944431.shtml" target="_blank">http://www.yesky.com/431/1944431.shtml</a><br/><br/>如果是默认安装，可以在C:\Program Files\MySQL\MySQL Connector Net 1.0.4\bin\.NET 1.1\找到MySql.Data.dll，然后复制到mysqltest目录下的bin目录下<br/><br/>选择工具箱上的数据,点右键选择添加/移除项<br/><br/>如下图<br/><br/><img src="http://www.cnblogs.com/images/cnblogs_com/halgogo/2.jpg" border="0" alt=""/><br/>选择浏览, mysqltest项目的bin目录下,选取MySql.Data.dll<br/><img src="http://www.cnblogs.com/images/cnblogs_com/halgogo/1.jpg" border="0" alt=""/><br/>在解决方案管理器中引用mysqltest项目的bin目录下的MySql.Data.dll<br/><br/>在aspx页中加入DataGrid控件<br/><br/>这里是C#代码<br/><br/>using System.Data;<br/><br/>using System.Drawing;<br/><br/>using System.Web;<br/><br/>using System.Web.SessionState;<br/><br/>using System.Web.UI;<br/><br/>using System.Web.UI.WebControls;<br/><br/>using System.Web.UI.HtmlControls;<br/><br/>using MySql.Data.MySqlClient;<br/><br/> <br/><br/>namespace mysqltest<br/><br/>{<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// WebForm1 的摘要说明。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public class WebForm1 : System.Web.UI.Page<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected System.Web.UI.WebControls.DataGrid DataGrid1;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private void Page_Load(object sender, System.EventArgs e)<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 在此处放置用户代码以初始化页面<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MySqlConnection MyConn = new MySqlConnection(&#34;Server=localhost;userid=root;password=;Database=guestbook&#34;);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string Sql = &#34;sel&#101;ct * from guestbook&#34;;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MySqlDataAdapter Myda = new MySqlDataAdapter(Sql,MyConn);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataSet ds = new DataSet();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Myda.Fill(ds,&#34;guestbook&#34;);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataGrid1.DataSource = ds.Tables[&#34;guestbook&#34;].DefaultView;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataGrid1.DataBind();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#region Web 窗体设计器生成的代码<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;override protected void OnInit(EventArgs e)<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base.OnInit(e);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 设计器支持所需的方法 - 不要使用代码编辑器修改<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 此方法的内容。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private void InitializeComponent()<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Load += new System.EventHandler(this.Page_Load);<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#endregion<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/><br/>}<br/><br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/default.asp?id=2171" /> 
	  <id>http://www.cnsdn.com.cn/blog/default.asp?id=2171</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[用C#生成随机中文汉字验证码的基本原理 ]]></title>
	  <author>
		 <name>admin</name>
		 <uri>http://www.cnsdn.com.cn/blog/</uri>
		 <email>cnsdn@163.com</email>
	  </author>
	  <category term="" scheme="http://www.cnsdn.com.cn/blog/default.asp?cateID=6" label="C#" /> 
	  <updated>2007-09-03T06:34:53+08:00</updated>
	  <published>2007-09-03T06:34:53+08:00</published>
		  <summary type="html"><![CDATA[前几天去申请免费QQ号码，突然发现申请表单中的验证码内容换成了中文，这叫真叫我大跌眼镜感到好笑，Moper上的猫儿们都大骂腾讯采用中文验证码。 ^_^ 我不得不佩服腾讯为了防止目前网络上横行的QQ号码自动注册机而采取中文验证码的手段。仔细想了想感觉用程序生成随机的中文验证码并不是很难，下面就来介绍一下使用C#生成随机的中文汉字的原理。 <br/>&nbsp;&nbsp;<br/>　　1、汉字编码原理 <br/><br/>　　到底怎么办到随机生成汉字的呢？汉字从哪里来的呢？是不是有个后台数据表，其中存放了所需要的所有汉字，使用程序随机取出几个汉字组合就行了呢？使用后台数据库先将所有汉字存起来使用时随机取出，这也是一种办法，但是中文汉字有这么多，怎么来制作呢？其实可以不使用任何后台数据库，使用程序就能做到这一切。要知道如何生成汉字，就得先了解中文汉字的编码原理。<br/><br/>　　1980年，为了使每一个汉字有一个全国统一的代码，我国颁布了第一个汉字编码的国家标准： GB2312-80《信息交换用汉字编码字符集》基本集，简称GB2312，这个字符集是我国中文信息处理技术的发展基础，也是国内所有汉字系统的统一标准。到了后来又公布了国家标准GB18030-2000《信息交换用汉字编码字符集基本集的扩充》，简称GB18030，编程时如果涉及到编码和本地化的朋友应该对GB18030很熟悉。这是是我国继GB2312-1980和GB13000-1993之后最重要的汉字编码标准，同时也是未来我国计算机系统必须遵循的基础性标准之一。 <br/><br/>　　目前在中文WINDOWS操作系统中，.NET编程中默认的的代码页就是GB18030简体中文。但是事实上如果生成中文汉字验证码只须要使用GB2312字符集就已经足够了。字符集中除了我们平时大家都认识的汉字外，也包含了很多我们不认识平时也很少见到的汉字。如果生成中文汉字验证码中有很多我们不认识的汉字让我们输入，对于使用拼音输入法的朋友来说可不是好事，五笔使用者还能勉强根据汉字的长相打出来，呵呵！所以对于GB2312字符集中的汉字我们也不是全都要用。 <br/><br/>　　中文汉字字符可以使用区位码来表示，见汉字区位码表 <a href="http://navicy2005.home4u.china.com/resource/gb2312tbl.htm" target="_blank">http://navicy2005.home4u.china.com/resource/gb2312tbl.htm</a> <br/><br/>　　汉字区位码代码表 <a href="http://navicy2005.home4u.china.com/resource/gb2312tbm.htm" target="_blank">http://navicy2005.home4u.china.com/resource/gb2312tbm.htm</a> <br/>&nbsp;&nbsp;<br/>　　其实这两个表是同一回事，只不过一个使用十六进制分区表示，一个使用区位所在的数字位置表示。 例如“好”字的十六进制区位码是ba c3，前两位是区域，后两位代表位置，ba处在第26区，“好”处在此区汉字的第35位也就是c3位置，所以数字代码就是2635。这就是GB2312汉字区位原理。根据《汉字区位码表》我们可以发现第15区也就是AF区以前都没有汉字，只有少量符号，汉字都从第16区B0开始，这就是为什么GB2312字符集都是从16区开始的。 <br/>&nbsp;&nbsp;<br/>　　2、.Net程序处理汉字编码原理分析<br/><br/>　　在.Net中可以使用System.Text来处理所有语言的编码。在System.Text命名空间中包含众多编码的类，可供进行操作及转换。其中的 Encoding类就是重点处理汉字编码的类。通过在.NET文档中查询Encoding类的方法我们可以发现所有和文字编码有关的都是字节数组，其中有两个很好用的方法：&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>　　Encoding.GetBytes ()方法将指定的 String 或字符数组的全部或部分内容编码为字节数组 <br/>　　Encoding.GetString ()方法将指定字节数组解码为字符串。 <br/>&nbsp;&nbsp;<br/>　　没错我们可以通过这两个方法将汉字字符编码为字节数组，同样知道了汉字GB2312的字节数组编码也就可以将字节数组解码为汉字字符。通过对“好”字进行编码为字节数组后&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>　　Encoding gb=System.Text.Encoding.GetEncoding(&#34;gb2312&#34;); <br/>　　object[] bytes=gb.Encoding.GetBytes (&#34;好&#34;)； <br/>&nbsp;&nbsp;<br/>　　发现得到了一个长度为2的字节数组bytes，使用 <br/>&nbsp;&nbsp;<br/>　　string lowCode = System.Convert.ToString(bytes[0], 16); //取出元素1编码内容（两位16进制） <br/>　　string hightCode = System.Convert.ToString(bytes[1], 16);//取出元素2编码内容（两位16进制） <br/><br/>　　之后发现字节数组bytes16进制变码后内容竟然是{ba,c3}，刚好是“好”字的十六进制区位码（见区位码表）。 <br/><br/>　　因此我们就可以随机生成一个长度为2的十六进制字节数组，使用GetString ()方法对其进行解码就可以得到汉字字符了。不过对于生成中文汉字验证码来说，因为第15区也就是AF区以前都没有汉字，只有少量符号，汉字都从第16区 B0开始，并且从区位D7开始以后的汉字都是和很难见到的繁杂汉字，所以这些都要排出掉。所以随机生成的汉字十六进制区位码第1位范围在B、C、D之间，如果第1位是D的话，第2位区位码就不能是7以后的十六进制数。在来看看区位码表发现每区的第一个位置和最后一个位置都是空的，没有汉字，因此随机生成的区位码第3位如果是A的话，第4位就不能是0；第3位如果是F的话，第4位就不能是F。<br/><br/>　　好了，知道了原理，随机生成中文汉字的程序也就出来了，以下就是生成4个随机汉字的C#控制台代码： <br/>&nbsp;&nbsp;<br/>　　3、程序代码：&nbsp;&nbsp; <br/><br/>using System;<br/>using System.Text;<br/><br/>namespace ConsoleApplication<br/>{<br/>&nbsp;&nbsp;class ChineseCode<br/>　　{<br/>&nbsp;&nbsp;public static void Main()<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;//获取GB2312编码页（表）<br/>&nbsp;&nbsp;Encoding gb=Encoding.GetEncoding(&#34;gb2312&#34;);<br/><br/>&nbsp;&nbsp;//调用函数产生4个随机中文汉字编码<br/>&nbsp;&nbsp;object[] bytes=Cr&#101;ateRegionCode(4);<br/><br/>&nbsp;&nbsp;//根据汉字编码的字节数组解码出中文汉字<br/>&nbsp;&nbsp;string str1=gb.GetString((byte[])Convert.ChangeType(bytes[0], typeof(byte[])));<br/>&nbsp;&nbsp;string str2=gb.GetString((byte[])Convert.ChangeType(bytes[1], typeof(byte[])));<br/>&nbsp;&nbsp;string str3=gb.GetString((byte[])Convert.ChangeType(bytes[2], typeof(byte[])));<br/>&nbsp;&nbsp;string str4=gb.GetString((byte[])Convert.ChangeType(bytes[3], typeof(byte[])));<br/><br/>&nbsp;&nbsp;//输出的控制台<br/>　　 Console.WriteLine(str1 + str2 +str3 +str4);<br/>　　 }<br/><br/><br/>&nbsp;&nbsp;/**//* <br/><br/>　　此函数在汉字编码范围内随机创建含两个元素的十六进制字节数组，每个字节数组代表一个汉字，并将 <br/>四个字节数组存储在object数组中。<br/>&nbsp;&nbsp;参数：strlength，代表需要产生的汉字个数<br/>&nbsp;&nbsp;*/<br/>&nbsp;&nbsp;public static object[] Cr&#101;ateRegionCode(int strlength)<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;//定义一个字符串数组储存汉字编码的组成元素<br/>&nbsp;&nbsp;string[] rBase=new String [16]{&#34;0&#34;,&#34;1&#34;,&#34;2&#34;,&#34;3&#34;,&#34;4&#34;,&#34;5&#34;,&#34;6&#34;,&#34;7&#34;,&#34;8&#34;,&#34;9&#34;,&#34;a&#34;,&#34;b&#34;,&#34;c&#34;,&#34;d&#34;,&#34;e&#34;,&#34;f&#34;};<br/><br/>&nbsp;&nbsp;Random rnd=new Random();<br/><br/>&nbsp;&nbsp;//定义一个object数组用来<br/>&nbsp;&nbsp;object[] bytes=new object[strlength];<br/><br/>&nbsp;&nbsp;/**//*每循环一次产生一个含两个元素的十六进制字节数组，并将其放入bject数组中<br/>&nbsp;&nbsp;每个汉字有四个区位码组成<br/>&nbsp;&nbsp;区位码第1位和区位码第2位作为字节数组第一个元素<br/>&nbsp;&nbsp;区位码第3位和区位码第4位作为字节数组第二个元素<br/>&nbsp;&nbsp;*/<br/>&nbsp;&nbsp;for(int i=0;i&lt;strlength;i++)<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;//区位码第1位<br/>&nbsp;&nbsp;int r1=rnd.Next(11,14);<br/>&nbsp;&nbsp;string str_r1=rBase[r1].Trim();<br/><br/>&nbsp;&nbsp;//区位码第2位<br/>&nbsp;&nbsp;rnd=new Random(r1*unchecked((int)DateTime.Now.Ticks)+i);//更换随机数发生器的<br/><br/>种子避免产生重复值<br/>&nbsp;&nbsp;int r2;<br/>&nbsp;&nbsp;if (r1==13)<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;r2=rnd.Next(0,7);<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;else<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;r2=rnd.Next(0,16);<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;string str_r2=rBase[r2].Trim();<br/><br/>&nbsp;&nbsp;//区位码第3位<br/>&nbsp;&nbsp;rnd=new Random(r2*unchecked((int)DateTime.Now.Ticks)+i);<br/>&nbsp;&nbsp;int r3=rnd.Next(10,16);<br/>&nbsp;&nbsp;string str_r3=rBase[r3].Trim();<br/><br/>&nbsp;&nbsp;//区位码第4位<br/>&nbsp;&nbsp;rnd=new Random(r3*unchecked((int)DateTime.Now.Ticks)+i);<br/>&nbsp;&nbsp;int r4;<br/>&nbsp;&nbsp;if (r3==10)<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;r4=rnd.Next(1,16);<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;else if (r3==15)<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;r4=rnd.Next(0,15);<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;else<br/>&nbsp;&nbsp;{<br/>&nbsp;&nbsp;r4=rnd.Next(0,16);<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;string str_r4=rBase[r4].Trim();<br/><br/>&nbsp;&nbsp;//定义两个字节变量存储产生的随机汉字区位码<br/>&nbsp;&nbsp;byte byte1=Convert.ToByte(str_r1 + str_r2,16);<br/>&nbsp;&nbsp;byte byte2=Convert.ToByte(str_r3 + str_r4,16);<br/>&nbsp;&nbsp;//将两个字节变量存储在字节数组中<br/>&nbsp;&nbsp;byte[] str_r=new byte[]{byte1,byte2};<br/><br/>&nbsp;&nbsp;//将产生的一个汉字的字节数组放入object数组中<br/>&nbsp;&nbsp;bytes.SetValue(str_r,i);<br/><br/>&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;return bytes;<br/><br/>&nbsp;&nbsp;}<br/>　　}<br/><br/>} <br/>&nbsp;&nbsp;<br/>　　实现了随机生成汉字后，就可以使用.NET GDI来绘制自己需要的验证码图形了。具体的怎样生成验证码图片，以及改变其中字符的长和宽等效果网上已经有很多相关的文章，这里由于篇幅就不再介绍了。不过有一点要说明的是以上代码在中文版的Windows下才能运行，因为它带有GB的字符集，如果你是其他语言的操作系统，就需要安装GB字符集了。]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/default.asp?id=2169" /> 
	  <id>http://www.cnsdn.com.cn/blog/default.asp?id=2169</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[MySQL5.0中文问题及JDBC数据库连接和JSP汉字编码问题解决方法总结]]></title>
	  <author>
		 <name>admin</name>
		 <uri>http://www.cnsdn.com.cn/blog/</uri>
		 <email>cnsdn@163.com</email>
	  </author>
	  <category term="" scheme="http://www.cnsdn.com.cn/blog/default.asp?cateID=10" label="Java" /> 
	  <updated>2007-09-02T06:32:56+08:00</updated>
	  <published>2007-09-02T06:32:56+08:00</published>
		  <summary type="html"><![CDATA[解决这类问题的方法很多，今天在此简单的总结一下，把常碰到的问题解决方法记下来! <br/>1， MySQL5.0中文问题解决方案如下： <br/>1、在dos环境下，用mysql --default-character-set=gbk -u root -p 这句话进入mysql~~ <br/>2、建数据库、表，如下： <br/>cr&#101;ate database admin; <br/>use admin; <br/>Cr&#101;ate TABLE admin ( <br/>admin_name char(20) NOT NULL, <br/>admin_password char(20) NOT NULL <br/>) TYPE=MyISAM, default character set gbk; <br/><br/>2， JDBC的设置问题：(这里主要讲的是mysql-connector-java-3.1.8这个JDBC驱动程序而言) <br/>这只是一个压缩包，并不需要安装，只要将其解压，使用的是文件夹mysql-connector-java-3.1.8里的文件：mysql-connector-java-3.1.8-bin.jar． <br/>需要配置环境变量的是JDBC驱动．在配置前先要把刚才说到的mysql-connector-java-3.1.8-bin.jar放到本地硬盘某处（我放的地方：E:\JAVA\MySQLJDBC），然后根据你放的地方，配置classpath，我的配置是这样的： <br/>.;E:\Java\j2se5.0\lib\tools.jar; E:\Java\j2se5.0\lib\mysql-connector-java-3.1.8-bin-g.jar; E:\JAVA\MySQLJDBC\mysql-connector-java-3.1.8-bin.jar <br/><br/><br/><br/>配置这个的目的是让你的java应用程序找到连接mysql的驱动． <br/>配置完环境变量后还有很重要一步就是为JSP连接数据库配置驱动，这个其实很简单，就是把mysql-connector-java-3.1.8-bin.jar拷到某些文件夹里就行了，我在网上看了很多资料问了很多人，各种说法都有，我综合了一下，为了保险，我都全做了，呵呵，反正就是拷一个400K的文件而已，现列出要把mysql-connector-java-3.1.8-bin.jar拷进去的文件夹，如下： <br/>E:\Java\Tomcat5.0\common\lib <br/>E:\Java\Tomcat5.0\shared\lib <br/>一般情况下只要考到Tomcat5.0上面的两个问题夹里面就可以解决问题了，如果需要，也可以将mysql-connector-java-3.1.8-bin.jar这个驱动文件拷贝到你的WEB站点的 …\WEB-INF\lib 目录下面。 <br/><br/><br/>3， Eclipse中数据库插件中操作数据库时的中文编码问题： <br/>当在Eclipse中装上来你所喜欢的数据库插件的时候，都会出现在你查询某一个数据库之后出现记录中的汉字乱码。解决方法很简单，只要在你建立数据库连接的时候把URL设置成下面这个样子就可以了： <br/>URL= jdbc:mysql://localhost:3306/?useUnicode=true&amp;characterEncoding=GBK <br/><br/><br/>4， 在JSP网页编辑中个人经验：在经过很多的次调试之后，发现在装了myeclipse之后，有这么条小巧： <br/>①在用myeclipse编写HTML文件时charset=GBK设置成这个样子，那么在浏览器中浏览时就不会出现乱码； <br/>②而在用myeclipse编辑JSP文件时，&lt;%@ page contentType=&#34;text/html;charset=GB2312&#34; %&gt;设置成这样子，且这条语句必须是整个JSP文件的第一条语句,就可以避免JSP文件在浏览器中显示时出现乱码； ③对于如果在JSP网页中要从HTML页面中接收数据，那么在JSP中的接收语句的汉字编码应与数据来源的HTML的汉字编码相同；例如②中的HTML的汉字编码为charset=GBK，那么在JSP中的接收语句就应该这样设置：request.setCharacterEncoding(&#34;GBK&#34;);如果还要将接受的数据插入到数据库中(以插入MySQL5.0数据库为例)，那么在插入数据库时的汉字编码也应与HTML文件中的汉字编码相同，我的设置如下：con= DriverManager.getConnection(&#34;jdbc:mysql://localhost:3306/sample_db?user=dazern&amp;password=5201314&amp;useUnicode=true&amp;characterEncoding=GBK&#34;);这样设置后数据库中的数据才不会乱码. <br/><br/><br/><br/>以上经验都是在myeclipse3.8.3+Tomcat5.0.28中测试过，没有错误！在此仅供大家借鉴，具体情况还得具体分析！ <br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.cnsdn.com.cn/blog/default.asp?id=2168" /> 
	  <id>http://www.cnsdn.com.cn/blog/default.asp?id=2168</id> 
  </entry>	
		
</feed>