5

我们有一个 .NET 应用程序 (VB / VS2010) 并在 SQL Server 2008 上调用许多存储过程以进行数据库查询。我们还有很多更新/插入/删除触发器,一旦这些存储过程修改了数据库表,它们就会自动执行。

在很多情况下调用存储过程并且它似乎执行正常,因为没有引发错误并且 .NET 应用程序照常继续。但是,如果我随后深入了解并通过 SQL Server 客户端手动执行存储过程调用,我会看到在存储过程失败后立即执行的触发器,从而回滚所有更改。

所以我的问题是:在我们的 .NET --> 存储过程 --> 触发场景中检测和传递错误的最佳方法是什么,以便在 .NET 应用程序中确定在发生错误时一切是否成功?

非常感谢,史蒂夫


更新:我现在在家,周末远离我的办公桌(和代码库),所以没有机会检查存储过程的细节。非常感谢到目前为止给出的答案。下周我可以再看一下代码。

但与此同时...

一个问题是关于 MS SQL Server 的版本:它是 2008 年。

据我所知,我们以这种方式调用存储过程(至少是那些不读取数据并且“只是”更新、删除或插入数据的过程):

Using connection As New SqlConnection("connectionString")
    Dim command As New SqlCommand("EXEC STORED_PROCEDUR_ENAME), connection)
    command.Connection.Open()
    command.ExecuteNonQuery()
End Using

我认为上面代码背后的假设是,如果存储过程或相关触发器中出现故障,那么

command.ExecuteNonQuery()

然后会失败。这可能是我的第一个问题,即我是否必须更改此代码?下面的一个问题是我是否使用 ExecuteDataReader,所以答案是否定的,至少目前还没有……

我将在下面评论 SQL 特定的问题和建议。

4

3 回答 3

1

我今天确实遇到了同样的问题,

为了解决它,我使用了一个输出@msg 并将其放在存储过程中的每个函数之后。

SET @msg = 'Test print 1'

每个部分我都添加了一个,所以我知道打印的最后一个数字是 sproc 失败的地方。然后我走到触发器失败的表并对其进行调整,直到它打印出最后一个数字并通过。

于 2012-08-08T03:54:21.930 回答
0

您应该在每条语句后检查@@error,如果存在则返回错误。

这是一篇给你的好文章。查看“为什么我的错误未引发”部分。它描述了一个可能是您的问题的场景。

http://www.sommarskog.se/error-handling-II.html

您可能还想尝试打开 XACT_ABORT,这样存储过程会因大多数错误而失败。

编辑:这是另一个可能有助于解释这一点的链接。

http://www.novicksoftware.com/tipsandtricks/tips-erorr-handling-in-a-stored-procedure.htm

如果您检查@@error 并找到它!= 0,您可以从您的过程中返回错误,或者您可以使用 RAISERROR,这肯定会导致调用代码时出现异常。

http://msdn.microsoft.com/en-us/library/ms178592.aspx

于 2012-06-29T18:11:21.857 回答
0

正如您提到的,您正在使用 sql server 2008。这提供了使用 try..catch 的能力。这是这篇文章。

http://msdn.microsoft.com/en-us/library/ms175976.aspx

也看看这个论坛。

http://social.msdn.microsoft.com/Forums/eu/transactsql/thread/03eae70e-d478-44a7-90f3-8e1d27d9f22e

我认为 try..catch 会完成这项工作。同样在.net 方面,我将使用以下代码。

try
{
   // your stored procedure execution code.
}
Catch (sqlexception e)
{
  // do something with sql exception.
}

试试这个场景,看看是否能解决你的问题。

于 2012-06-29T21:36:07.097 回答