50114.htm
来自「一本很基础的SQL讲解」· HTM 代码 · 共 152 行 · 第 1/2 页
HTM
152 行
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>[SqlProcedure]<BR>public static void GetAllCustomers()<BR>{<BR>SqlConnection cnn = new SqlConnection<BR>("context connection=true");<BR>cnn.Open();<BR>SqlCommand cmd = new SqlCommand();<BR>cmd.Connection = cnn;<BR>cmd.CommandText = "select * from customers";<BR>SqlDataReader reader = cmd.ExecuteReader();<BR>SqlContext.Pipe.Send(reader);<BR>reader.Close();<BR>cnn.Close();<BR>}</PRE></TD></TR></TBODY></TABLE></P>
<P>这个GetAllCustomers()方法用了一个[SqlProcedure]属性来修饰。 在方法内创建一个SqlConnection和一个SqlCommand对象。 然后使用ExecuteReader()方法来执行SELECT语句。 接下来用Send()方法将取得的SqlDataReader数据发送到客户端。 最后就是关闭SqlDataReader和SqlConnection。 在这种方法中,是我们自己创建的SqlDataReader。 其实,我们也可以把这个任务交给SqlContext类去完成,代码如下:</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P>[SqlProcedure]<BR>public static void GetCustomerByID<BR>(SqlString CustomerID)<BR>{<BR>SqlConnection cnn = new SqlConnection<BR>("context connection=true");<BR>cnn.Open();<BR>SqlCommand cmd = new SqlCommand();<BR>cmd.Connection = cnn;<BR>cmd.CommandText = "select * from customers <BR>where <A href="mailto:customerid=@p1">customerid=@p1</A>";<BR>SqlParameter p1 = new SqlParameter("@p1", CustomerID);<BR>cmd.Parameters.Add(p1);<BR>SqlContext.Pipe.ExecuteAndSend(cmd);<BR>cnn.Close();<BR>}</P></PRE></TD></TR></TBODY></TABLE></P>
<P>GetCustomerByID()方法需要一个参数 – CustomerID,它将从Customers表中返回某个customer的记录。 这个方法内的代码,除了ExecuteAndSend()方法外,你应该都已经比较熟悉了。 ExecuteAndSend()方法接收一个SqlCommand对象作为参数,执行它就会返回数据集给客户端。</P>
<P>#p#</P>
<P><STRONG>有输出参数的存储过程</STRONG></P>
<P>我们在使用存储过程时,经常会通过输出参数返回一个经过计算的值。 所以,现在让我们来看一看如何创建具有一个或多个输出参数的存储过程。</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P>[SqlProcedure]<BR>public static void GetCompanyName<BR>(SqlString CustomerID,out SqlString CompanyName)<BR>{<BR>SqlConnection cnn = new SqlConnection<BR>("context connection=true");<BR>cnn.Open();<BR>SqlCommand cmd = new SqlCommand();<BR>cmd.Connection = cnn;<BR>cmd.CommandText = "select companyname from <BR>customers where <A href="mailto:customerid=@p1">customerid=@p1</A>";<BR>SqlParameter p1 = new SqlParameter<BR>("@p1", CustomerID);<BR>cmd.Parameters.Add(p1);<BR>object obj = cmd.ExecuteScalar();<BR>cnn.Close();<BR>CompanyName = obj.ToString();<BR>}</P></PRE></TD></TR></TBODY></TABLE></P>
<P>这是一个名为GetCompanyName()的方法,它需要两个参数。 第一个参数是CustomerID,它是一个输入参数;第二个参数是CompanyName,它是一个输出参数(用关键字out来指明)。 这两个参数都是SqlString类型的。 GetCompanyName()方法会接收一个CustomerID参数,然后返回CompanyName(作为输出参数)。</P>
<P>该方法内的代码首先设置了SqlConnection和SqlCommand对象。 然后,使用ExecuteScalar()方法来执行SELECT语句。 ExecuteScalar()方法返回的值是一个object类型,它其实就是公司名称。 最后将输出参数CompanyName设置为这个值。</P>
<P><STRONG>返回一行或多行自定义数据的存储过程</STRONG></P>
<P>我们在使用存储过程时,更多的还是从某些表中读取数据。 但是,某些情况下我们需要的数据可能不在任何表里。 例如,你可能会基于某些计算来生成一个数据表格。 因为它的数据不是从表中获得的,所以上面的方法就不在适用了。 幸运的是,SQL Server的CLR集成特性给我们提供了一个解决这个问题的方法。 请看如下代码:</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P>[SqlProcedure]<BR>public static void GetCustomRow()<BR>{<BR>SqlMetaData[] metadata = new SqlMetaData[2];<BR>metadata[0] = new SqlMetaData<BR>("CustomerID", SqlDbType.NVarChar,50);<BR>metadata[1] = new SqlMetaData<BR>("CompanyName", SqlDbType.NVarChar,50);<BR>SqlDataRecord record = new SqlDataRecord(metadata);<BR>record.SetString(0, "ALFKI");<BR>record.SetString(1, "Alfreds Futterkiste");<BR>SqlContext.Pipe.Send(record);<BR>}</P></PRE></TD></TR></TBODY></TABLE></P>
<P>GetCustomRow()方法会返回一条记录并发送给客户端。 这个方法首先声明了一个SqlMetaData对象。 当你要用到自定义列的时候,就可以使用这个SqlMetaData类。 在我们的示例中,创建了两个类型为NVarChar,长度为50的列。然后创建了一个SqlDataRecord对象。 SqlDataRecord类可以用来表示一个自定义行。 它的构造函数需要一个SqlMetaData数组作为参数。 SqlDataRecord对象的SetString()方法用来设置列的值。 另外,还有许多不同的类似SetString()这样的方法,可以用来处理不同的数据类型。 最后,调用Send()方法将SqlDataRecord对象发送到客户端。</P>
<P>在上面的示例中,我们只返回了一行数据给调用者。 那么,如果要返回多行呢? 请看下面的代码:</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P>[SqlProcedure]<BR>public static void GetMultipleCustomRows()<BR>{<BR>SqlMetaData[] metadata = new SqlMetaData[2];<BR>metadata[0] = new SqlMetaData<BR>("CustomerID", SqlDbType.NVarChar, 50);<BR>metadata[1] = new SqlMetaData<BR>("CompanyName", SqlDbType.NVarChar, 50);<BR>SqlDataRecord record = new SqlDataRecord(metadata);<BR>SqlContext.Pipe.SendResultsStart(record);<BR>record.SetString(0, "ALFKI");<BR>record.SetString(1, "Alfreds Futterkiste");<BR>SqlContext.Pipe.SendResultsRow(record);<BR>record.SetString(0, "ANATR");<BR>record.SetString(1, "Ana Trujillo Emparedados y helados");<BR>SqlContext.Pipe.SendResultsRow(record);<BR>SqlContext.Pipe.SendResultsEnd();<BR>}</P></PRE></TD></TR></TBODY></TABLE></P>
<P>GetMultipleCustomRows()方法将会返回多个SqlDataRecord对象到客户端。 接下来创建自定义列和设置列的值都和之前的例子一样。 但是,我们使用的是SendResutlsStart()方法来传输数据。 SendResultsRow()方法也是发送一个SqlDataRecord对象到客户端,但是我们可以多次调用它,从而做到发送多条记录。 最后,调用SendResultsEnd()方法用来标记已经完成数据传输操作。</P>
<P>我们已经开发完了存储过程。 现在就可以将这个项目编译为一个程序集(.DLL)。 但是我们的工作并没有到此结束。 我们还需要部署这个程序集和存储过程到SQL Server数据库。 有两种方法可以完成这个工作 – 手动和自动。 手动方法是使用T-SQL语句注册你的程序集,并将存储过程部署到SQL Server数据库中。 在本例中,我将使用自动的方法来部署存储过程到SQL Server数据库。</P>
<P>右键单击你的项目,然后在菜单中选择“部署”选项。</P>
<TABLE class=ln cellSpacing=0 borderColorDark=#ffffff align=center bgColor=#ddddd borderColorLight=#999999 border=1>
<TBODY>
<TR>
<TD bgColor=#ffffff><IMG src="/files/uploadimg/20070627/103431877.jpg"></TD></TR>
<TR>
<TD class=it align=middle bgColor=#dddddd>图4</TD></TR></TBODY></TABLE>
<P>#p#</P>
<P>如此就会自动地完成注册程序集和部署存储过程的工作。 注意,只有在你创建项目时添加了数据库引用的时候,才会出现“部署”选项。 如果因为某些原因你没能添加数据库引用,那么你可以通过项目属性对话框来设置它。</P>
<TABLE class=ln cellSpacing=0 borderColorDark=#ffffff align=center bgColor=#ddddd borderColorLight=#999999 border=1>
<TBODY>
<TR>
<TD bgColor=#ffffff><IMG src="/files/uploadimg/20070627/103451548.jpg"></TD></TR>
<TR>
<TD class=it align=middle bgColor=#dddddd>图5</TD></TR></TBODY></TABLE>
<P>如果你在SQL Server Management Studio查看Northwind数据库的话,那么就应该可以看到和下图相似的结果。</P>
<TABLE class=ln cellSpacing=0 borderColorDark=#ffffff align=center bgColor=#ddddd borderColorLight=#999999 border=1>
<TBODY>
<TR>
<TD bgColor=#ffffff><IMG src="/files/uploadimg/20070627/103516986.jpg"></TD></TR>
<TR>
<TD class=it align=middle bgColor=#dddddd>图6</TD></TR></TBODY></TABLE>
<P>注意,在存储过程节点下出现了我们创建的所有方法(有“锁”图标的),并且在程序集节点下出现了我们的程序集。 </P>
<P>就是这些东西,很简单吧。 现在你就可以在你的程序中调用这些存储过程了。你也可以在SQL Server Management Studio中来测试它们。</P>
<P><STRONG>作者简介:</STRONG>Bipin Joshi是DotNetBips.com的管理员。他是<A href="http://www.binaryintellect.com/">http://www.binaryintellect.com/</A>的发起人,这个公司提供.NET framwork的培训和咨询服务。他在印度孟买为开发者提供培训。他也是微软的MVP(ASP.Net)和ASPInsiders的会员。</P>
<P><FONT size=4>【相关文章】</FONT></P>
<UL type=disc>
<LI><A href="http://database.51cto.com/art/200704/46306.htm" target=_blank><U><FONT color=blue>动态创建SQL Server数据库表存储过程</FONT></U></A></LI></UL>
<UL type=disc>
<LI><A href="http://developer.51cto.com/art/200705/47344.htm" target=_blank><U><FONT color=blue>详解SQL Server中数据库快照工作原理</FONT></U></A></LI></UL>
<UL type=disc>
<LI><A href="http://database.51cto.com/art/200612/36919.htm" target=_blank><U><FONT color=blue>使用SQL Server 2005的三个理由</FONT></U></A></LI></UL>
<DIV align=right>【责任编辑:<A class=ln href="mailto:sunsj@51cto.com">火凤凰</A> TEL:(010)68476606-8007】</DIV> </td> </tr> <tr> <td class="d_font4"> </td> </tr> </table>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?