GVKun编程网logo

SQL Server:使用原始异常号重新抛出异常(数据库初始化异常)

22

针对SQLServer:使用原始异常号重新抛出异常和数据库初始化异常这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展c#–BackgroundWorker.RunWorkCompleted–

针对SQL Server:使用原始异常号重新抛出异常数据库初始化异常这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展c# – BackgroundWorker.RunWorkCompleted – 无法重新抛出异常、c#在设计用于处理异常和保留堆栈跟踪的方法中重新抛出异常、iphone – openDatabase()方法抛出异常(SECURITY_ERR:DOM异常18)、JAVA 7新特性——在单个catch代码块中捕获多个异常,以及用升级版的类型检查重新抛出异常等相关知识,希望可以帮助到你。

本文目录一览:

SQL Server:使用原始异常号重新抛出异常(数据库初始化异常)

SQL Server:使用原始异常号重新抛出异常(数据库初始化异常)

我在有两个INSERT指令的存储过程中使用TRY CATCH块。

如果出现问题,则CATCH块负责回滚所做的所有更改,并且除一件事外,它都可以正常工作!

我的ASP.NET应用程序捕获的异常是一个SqlException,其编号为50000。这不是原始编号!(我期望的数字是2627)

在异常的Message属性中,我可以看到原始的异常编号和格式化的消息。

我如何获得原始的异常编号?

try{    // ... code}catch(SqlException sqlException){    switch (sqlException.Number)    {        // Name already exists        case 2627:            throw new ItemTypeNameAlreadyExistsException();        // Some other error        // As the exception number is 50000 it always ends here!!!!!!        default:            throw new ItemTypeException();    }}

现在,返回值已被使用。我想我可以使用输出参数来获取异常号,但这是一个好主意吗?

我该怎么办才能获得例外编号?谢谢

PS:这是必需的,因为我有两个INSERT指令。

答案1

小编典典

谢谢你们的回答。我已经做过一些事情,可以从重新抛出异常的信息中获取错误。

@gbn我也喜欢gbn的答案,但是我会坚持这个答案,因为这是最有效的答案,我在这里发布它,希望它对其他人也有用。

答案是在应用程序中使用事务。
如果在存储过程中未捕获到异常,则将在SqlException对象中获取原始编号。在应用程序中捕获原始异常之后,我编写以下代码

transaction.Rollback();

否则:

transaction.Commit();

它比我最初预期的要简单得多!

http://msdn.microsoft.com/zh-
CN/library/system.data.sqlclient.sqltransaction.aspx

c# – BackgroundWorker.RunWorkCompleted – 无法重新抛出异常

c# – BackgroundWorker.RunWorkCompleted – 无法重新抛出异常

我正在为WCF调用(使用BackgroundWorker)编写某种包装器,以便在调用正在进行时保持GUI不冻结.它主要是按预期工作,但是当WCF调用抛出异常时,我遇到了BackgroundWorker的问题.如果在DoWork中发生异常,我可以在RunWorkCompleted中检测到它,但是将其重新抛出到GUI不起作用.我已经读了很多线程,人们提到这应该有效.

包装器的代码(注意WCF调用由抛出的异常表示):

private void GetSomething(Action<IEnumerable<int>> completedAction)
{
    BackgroundWorker b = new BackgroundWorker();

    b.DoWork += (s,evt) => { throw new Exception(); evt.Result = new List<int> { 1,2,3 }; };

    b.RunWorkerCompleted += (s,evt) =>
    {
        if (evt.Error == null && completedAction != null)
        {
           completedAction((IEnumerable<int>)evt.Result);
        }
        else if(evt.Error != null)
        {
           throw evt.Error;
        }
    };

    b.RunWorkerAsync();
}

在Windows窗体中调用代码:

private void button3_Click(object sender,EventArgs e)
{
    try
    {
        GetSomething(list =>
        {
           foreach (int i in list)
           {
              listView1.Items.Add(new ListViewItem(i.ToString()));
           }
        });
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

在调试时,我得到:

  1. “Exception of type ‘System.Exception’ was thrown” in DoWork
  2. “Exception of type ‘System.Exception’ was thrown” at throw evt.Error
  3. “TargetInvocationException was unhandled” at Application.Run(new Form1()) in the Main method

我究竟做错了什么?我想在Windows窗体中捕获异常.

解决方法

事件b.RunWorkerCompleted是您应该进行错误处理的地方.您可以传递一个Action< Exception>做错误处理就像

private void GetSomething(Action<IEnumerable<int>> completedAction,Action<Exception> exceptionAction)
{
    BackgroundWorker b = new BackgroundWorker();

    b.DoWork += (s,evt) =>
    {
        if (evt.Error == null && completedAction != null)
            completedAction((IEnumerable<int>)evt.Result);
        else if(evt.Error != null)
            exceptionAction(evt.Error);
    };

    b.RunWorkerAsync();
}

然而,这往往会变得丑陋.如果您使用.Net 4或4.5,则可以使用“任务”.任务< TResult>是为了这种情况而创建的:

Task<IEnumerable<int>> GetSomething()
{
    return Task.Factory.StartNew(() => { 
        Thread.Sleep(2000);
        throw new Exception(); 
        return (new List<int> { 1,3 }).AsEnumerable(); 
        });
}

任务基本上是一个信号构造

> a.结果财产
> .Exception属性
> a .ContinueWith()方法

在ContinueWith()中,您可以检查Task是否处于故障状态(Exception被抛出).

你可以像使用它一样

private void button3_Click(object sender,EventArgs e)
    {
        GetSomething()
            .ContinueWith(task =>
                {
                    if (task.IsCanceled)
                    {
                    }
                    else if (task.IsFaulted)
                    {
                        var ex = task.Exception.InnerException;
                        MessageBox.Show(ex.Message);
                    }
                    else if (task.IsCompleted)
                    {
                        var list = task.Result;
                        foreach (int i in list)
                        {
                            listView1.Items.Add(new ListViewItem(i.ToString()));
                        }
                    }
                });
    }

如果您使用.Net 4.5和C#5(您需要VS2012或VS2010和Async CTP),您甚至可以使用异步并等待

private async void button3_Click(object sender,EventArgs e)
    {
        try
        {
            var list = await GetSomething();
            foreach (int i in list)
            {
                listView1.Items.Add(new ListViewItem(i.ToString()));
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

……所有的魔力都是由编译器完成的.请注意,您可以像以前一样使用try catch.

c#在设计用于处理异常和保留堆栈跟踪的方法中重新抛出异常

c#在设计用于处理异常和保留堆栈跟踪的方法中重新抛出异常

我想编写一个处理异常的方法,它将在catch块中调用.根据传递的异常的类型,异常要么作为新异常的内部异常传递,要么只是重新抛出.如何在第二种情况下保留堆栈跟踪?

示例:

public void TestMethod()
{
    try
    {
        // can throw an exception specific to the project or a .Net exception 
        SomeWorkMethod() 
    }
    catch(Exception ex)
    {
        HandleException(ex);
    }
}

private void HandleException(Exception ex)
{
    if(ex is SpecificException)
         throw ex; //will not preserve stack trace...
    else
         throw new SpecificException(ex);
}

我不想做的是,因为模式在很多地方重复,并且没有因子分解:

try
{
    SomeWorkMethod();
}
catch(Exception ex)
{
    if(ex is SpecificException)
         throw;
    else
         throw new SpecificException(ex);
}

解决方法

您需要在不指定异常的情况下使用throw来保留堆栈跟踪.这只能在catch块内完成.你可以做的是从HandleException返回而不抛出原始异常,然后使用throw:

public void TestMethod()
{
    try
    {
        // can throw an exception specific to the project or a .Net exception 
        SomeWorkMethod() 
    }
    catch(Exception ex)
    {
        HandleException(ex);
        throw;
    }
}

private void HandleException(Exception ex)
{
    if(ex is SpecificException)
         return;
    else
         throw new SpecificException(ex);
}

只要您只使用is来对异常进行分类,首选方法是两个catch块:

public void TestMethod()
{
    try
    {
        // can throw an exception specific to the project or a .Net exception 
        SomeWorkMethod() 
    }
    catch (SpecificException)
    {
        throw;
    }
    catch(Exception ex)
    {
        throw new SpecificException(ex);
    }
}

使用C#6.0,您还可以使用何时让异常通过:

public void TestMethod()
{
    try
    {
        // can throw an exception specific to the project or a .Net exception 
        SomeWorkMethod() 
    }
    catch(Exception ex) when (!(ex is SpecificException))
    {
        throw new SpecificException(ex);
    }
}

iphone – openDatabase()方法抛出异常(SECURITY_ERR:DOM异常18)

iphone – openDatabase()方法抛出异常(SECURITY_ERR:DOM异常18)

当数据库大小指定大于5 MB时,open Database()方法会在iPad 4.3以及所有iOS Simulator 4.x上引发异常(Security_ERR:DOM异常18).

使用PhoneGap 1.0.0在XCode 4.2(Mac OS X 10.6.8)下进行编译.

我们可以绕过这个限制吗?

这是一个示例代码:

<!DOCTYPE html> 
<html> 
<head> 
    <script src="phonegap-1.0.0.js"></script>
    <script>        
        try {
            var db = window.openDatabase("TMA","1.0","TMA Mobile Database",1024 * 1024 * 10);
        } catch (err) {
            alert(err);
        }
    </script> 
    <Meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
</head> 
<body> 

</body>
</html>

解决方法

根据 this resource,iOS本身的最大尺寸为5mb.一旦达到5mb大小,它将询问用户是否希望它变大.

我怀疑它有什么好办法.

您是否尝试过创建多个数据库?也许两个5mb DB可以为你工作.

JAVA 7新特性——在单个catch代码块中捕获多个异常,以及用升级版的类型检查重新抛出异常

JAVA 7新特性——在单个catch代码块中捕获多个异常,以及用升级版的类型检查重新抛出异常

在Java 7中,catch代码块得到了升级,用以在单个catch块中处理多个异常。如果你要捕获多个异常并且它们包含相似的代码,使用这一特性将会减少代码重复度。下面用一个例子来理解。

Java 7之前的版本: java

catch (IOException ex) {
     logger.error(ex);
     throw new MyException(ex.getMessage());
catch (SQLException ex) {
     logger.error(ex);
     throw new MyException(ex.getMessage());
}catch (Exception ex) {
     logger.error(ex);
     throw new MyException(ex.getMessage());
}

//在Java 7中,我们可以用一个catch块捕获所有这些异常:

catch(IOException | SQLException | Exception ex){
     logger.error(ex);
     throw new MyException(ex.getMessage());
}

如果用一个catch块处理多个异常,可以用管道符(|)将它们分开,在这种情况下异常参数变量(ex)是定义为final的,所以不能被修改。这一特性将生成更少的字节码并减少代码冗余。

另一个升级是编译器对重新抛出异常(rethrown exceptions)的处理。这一特性允许在一个方法声明的throws从句中指定更多特定的异常类型。 第二个特性说实话我没有看懂,以后可以去原文再仔细学习下,目前会第一个特性暂时够了

今天关于SQL Server:使用原始异常号重新抛出异常数据库初始化异常的介绍到此结束,谢谢您的阅读,有关c# – BackgroundWorker.RunWorkCompleted – 无法重新抛出异常、c#在设计用于处理异常和保留堆栈跟踪的方法中重新抛出异常、iphone – openDatabase()方法抛出异常(SECURITY_ERR:DOM异常18)、JAVA 7新特性——在单个catch代码块中捕获多个异常,以及用升级版的类型检查重新抛出异常等更多相关知识的信息可以在本站进行查询。

本文标签: