我们有一个.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特定的问题和建议。
答案 0 :(得分:1)
我今天实际上遇到了同样的问题,
要解决这个问题,我使用输出@msg并将其放在sproc中的每个函数之后。
SET @msg = 'Test print 1'
我添加了一个部分,所以我知道打印的最后一个数字是sproc失败的地方。然后我去了触发器失败的表并调整它直到打印出最后一个数字并通过。
答案 1 :(得分: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,这肯定会导致调用代码时出现异常。
答案 2 :(得分: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.
}
尝试此方案,看看是否能解决您的问题。