中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 数据库开发 > MSSQL Server
用SQL Server数据库处理数据层错误
作者:Tony Patton 时间:2007-06-25 16:07 出处:Builder.com.cn 责编:月夜寒箫
              摘要:用SQL Server数据库处理数据层错误

开发人员在努力做到妥善地处理意外,这样用户就不用担心天书般的系统错误信息。出于这个原因,异常处理是每个.NET应用程序的一个标准部分。Try/catch块让你能够捕捉异常并从该点控制应用程序的执行。与数据库进行交互操作的时候会发生很多错误,但是很多开发人员都不知道如何处理数据库层的错误。本周我们将探讨如何利用SQLServer和T-SQL来处理你数据库代码里的错误。

 

处理T-SQL里的错误

 

SQLServer的SQL对话让你能够轻松地处理可能会在存储进程、函数里发生的非致命错误,但是并不是所有的错误都很容易处理。事实上,致命和非致命的错误有很多。什么是致命的,什么是非致命的,对此没有很完备的文档说明,但是你的应用程序代码总是可以利用try/catch块来处理致命的数据库错误。对于其他所有的错误,你可以使用下面的技术。

 

事务

 

你应该在数据库代码里使用事务,以确保在一切都没有问题的时候所有的更改都被完成。SQLServer的在线帮助将事务描述为任务的一个逻辑单元,它由一系列语句(选择、插入、更新,或者删除等)组成。如果在事务期间没有发生任何错误,那么对事务的所有改动都会成为数据库的永久部分。如果在这期间发生了错误,不会对数据库进行任何修改。

 

事务包含在BEGIN TRANSACTION和END TRANSACTION语句之间。ROLLBACK TRANSACTION语句可以取消所有的更改,因此不会发生任何变化。用COMMIT TRANSACTION语句可以进行永久的更改。现在,就让我们把注意力放在如何处理T-SQL里的错误上。

 

@@Error

 

@@Error函数让你可以实现T-SQL错误处理。它会返回由系统所返回的错误代码。如果没有错误发生就会返回“0”。@@Error函数必须紧接在一个语句之后立即被调用,因为它会在每个T-SQL语句之后被清除。

 

RAISERROR

 

RAISERROR语句让你能够生成一个自定义的错误信息或者使用一个放在sysmessages表格里的已有消息。你可以在线查看它的句法,但是它的最基本格式包括了消息(用于自定义的消息)或者消息id(用于已有的消息)和它的严重度及状态。SQLServer没有使用状态,所以随便传递给它一个数字就可以了。严重度表示了错误的严重程度,0-18供用户使用,而19-25保留给管理员使用。

下面的示例存储过程使用了这些特性来更新示例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块被用来捕捉在与数据库进行交互操作过程中可能发生的任何致命错误。看看下面的代码:

 

<%@ 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>

下面是相应的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语言为你处理代码异常提供了所需要的一切。

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有