在列表A里,示例存储过程使用了这些特性来更新示例Northwind数据库里的一条记录:
CREATE PROCEDURE sp_UpdateCustomerPhone(
@id nvarchar(5),
@phone nvarchar(24),
@retvalueint output
) AS
BEGIN
BEGIN TRANSACTION
UPDATE [dbo].[Customers] SET [Phone] = @phone WHERE([CustomerID] = @id)
IF (@@ERROR <> 0) -- a non-negative value signals an error
BEGIN
ROLLBACK TRANSACTION -- changes are not permanent
RAISERROR('Update Customers Error',1,1) -- raise a custom error message
-- Custom error message appears if run from console
SET @retvalue = -1 -- return negative value to signalproblems
END
COMMIT TRANSACTION -- make the changes permanent, so record is updated
SET @retvalue = 1 -- a positive return value signalssuccess
RETURN
END
如果没有错误发生,它就把电话号码列设置为一个值,传递给过程。它使用一个返回值参数,如果有问题发生它就返回一个负值,如果用所有的东西都执行没有问题,它会返回一个正值。
用存储过程返回值
通过存储过程返回值,我们可以把它用在我们的.NET代码里。SqlCommand对象允许你很容易就添加参数传递给过程以及存储返回值。参数的Direction属性被用来接收来自存储过程调用的值。它有两个属性值:InputOutput和Output。在我们的例子里,我们将使用Output来接收状态值。
这段代码是一个简单的ASP.NET页面,用来传递一个用于Northwind数据库的客户表格里某个数据的新值。而id值事实上被保存在一个隐藏字段里,可以被轻易地传递给表单,但是这个字段是用来说明的。在文本字段输入的值被用更新数据库表格里的电话号码字段。
参数被添加给SqlCommand对象(它们必须精确地符合存储过程的参数值)。命令通过SqlCommand对象的ExecuteNonQuery方法被执行。一旦它已经被执行,返回的值可以通过参数来取回。
代码会检查返回的值(-1表示有问题),而消息会显示在一个Label控件里。此外,一个try/catch块被用来捕捉在与数据库进行交互操作过程中可能发生的任何致命错误。看看列表B:
<%@ Import Namespace="System.Data.SqlClient"%>
<%@ Import Namespace="System.Data" %>
<%@ Page language="c#" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html><head>
<title>TechRepublic.com - Test</title>
</head><body>
<script language="C#" runat="server">
private SqlConnectionconn= null;
private SqlCommandcmd =null;
private String connString;
private intrvalue;
public void SubmitChanges() {
connString = "data source=localhost;uid=test;pwd=test;initial catalog=Northwind";
try {
conn = new SqlConnection(connString);
cmd = new SqlCommand("sp_UpdateCustomerPhone", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@id", SqlDbType.NVarChar, 5);
cmd.Parameters["@id"].Value = lblID.Text;
cmd.Parameters.Add("@phone", SqlDbType.NVarChar, 24);
cmd.Parameters["@phone"].Value = txtPhone.Text;
cmd.Parameters.Add("@retvalue",System.Data.SqlDbType.Int);
cmd.Parameters["@retvalue"].Direction= ParameterDirection.Output;
conn.Open();
cmd.ExecuteNonQuery();
rvalue = (int)cmd.Parameters["@retvalue"].Value;
if (rvalue == -1) {
lblMessage.Text = "Database error duringupdate.";
lblMessage.Visible = True;
} else {
lblMessage.Text = "Data has been updated.";
lblMessage.Visible = True;
}
conn.Close();
} catch (SqlException ex) {
lblMessage.Text = "Error accessing database:" + ex.ToString();
} catch (Exception ex) {
lblMessage.Text = "Exception: " + ex.ToString();
} finally {
if (conn.State == ConnectionState.Open){
conn.Close();
}
conn.Dispose();
} }
private void btnUpdatePhone_Click(object sender, System.EventArgs e) {
SubmitChanges();
}
</script>
<form id="frmTestUpdate"method="post" runat="server">
<asp:Label ID="lblMessage"Visible="False" runat="server"></asp:Label><br /><br />
<asp:Label ID="lblPhone"runat="server">New Number:</asp:Label>
<asp:TextBox ID="txtPhone"runat="server" /><br/><br />
<asp:Button ID="btnUpdatePhone"Text="Update" OnCommand="btnUpdatePhone_Click"
runat="server" />
<asp:Label ID="lblID"Visible="False" runat="server">ALFKI</asp:Label>
</form></body></html>
(列表C里是相应的VB.NET代码。)
<%@ Import Namespace="System.Data.SqlClient"%>
<%@ Import Namespace="System.Data" %>
<%@ Page language="VB" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html><head>
<title>TechRepublic.com - Test</title>
</head><body>
<script language="VB" runat="server">
Dim conn AS SqlConnection
Dim cmd As SqlCommand
Dim connString As String
Dim rvalue As Integer
Public Sub SubmitChanges()
connString = "datasource=LOU8-3590424PATTON;uid=test;pwd=test;initial catalog=Northwind"
Try
conn = new SqlConnection(connString)
cmd = new SqlCommand("sp_UpdateCustomerPhone", conn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("@id", SqlDbType.NVarChar, 5)
cmd.Parameters("@id").Value = lblID.Text
cmd.Parameters.Add("@phone", SqlDbType.NVarChar, 24)
cmd.Parameters("@phone").Value = txtPhone.Text
cmd.Parameters.Add("@retvalue",System.Data.SqlDbType.Int)
cmd.Parameters("@retvalue").Direction= ParameterDirection.Output
conn.Open()
cmd.ExecuteNonQuery()
rvalue = System.Convert.ToInt32(cmd.Parameters("@retvalue").Value)
If (rvalue = -1) Then
lblMessage.Text = "Database error duringupdate."
lblMessage.Visible = true
Else
lblMessage.Text = "Data has been updated."
lblMessage.Visible = true
End If
conn.Close()
Catch ex As SqlException
lblMessage.Text = "Error accessing database:" + ex.ToString()
Catch ex As Exception
lblMessage.Text = "Exception: " + ex.ToString()
Finally
If (conn.State = ConnectionState.Open)Then
conn.Close()
End If
conn.Dispose()
End Try
End Sub
Private Sub btnUpdatePhone_Click(sender As Object, eAs
System.Web.UI.WebControls.CommandEventArgs)
SubmitChanges()
End Sub
</script>
<form id="frmTestUpdate"method="post" runat="server">
<asp:Label ID="lblMessage"Visible="False" runat="server"></asp:Label><br /><br />
<asp:Label ID="lblPhone"runat="server">New Number:</asp:Label>
<asp:TextBox ID="txtPhone"runat="server" /><br/><br />
<asp:Button ID="btnUpdatePhone"Text="Update" OnCommand="btnUpdatePhone_Click" runat="server"/>
<asp:Label ID="lblID"Visible="False" runat="server">ALFKI</asp:Label>
</form></body></html>
涵盖所有的数据库
利用try/catch代码块来处理.NET应用程序代码里的异常是一个简单明了的过程,但是你还可以监视数据库层的异常。SQLServer的T-SQL语言为你处理代码异常提供了所需要的一切。
Tony Patton的职业生涯开始于应用程序开发员,并已经获得了证明其专业水平的Java、VB、Lotus和XML认证。
责任编辑:张琎
查看本文的国际来源
用户评论