让我们假设我想通知应用程序发生了什么/返回了SQL服务器。让我们使用这个代码块:
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() as ErrorState,
ERROR_PROCEDURE() as ErrorProcedure,
ERROR_LINE() as ErrorLine,
ERROR_MESSAGE() as ErrorMessage;
END CATCH;
GO让我们使用这个代码块:
SELECT 1/0;我的问题是:都返回零错误除法。我不明白的是,当我在这两种情况下都有这个错误时,我为什么要将它包围在try catch clausule上呢?在这两种情况下,这个错误都会传播到客户端应用程序,这不是真的吗?
发布于 2010-06-10 13:18:13
是的,尝试捕获的唯一原因(在普通代码中)是,如果您能够“处理”错误,即您可以更正错误并成功地完成该过程所指定的任何功能,或者,如果您希望在将错误返回给客户端之前对错误进行处理(比如修改消息,或者将其存储在错误日志表中,或者发送电子邮件等等)(尽管我更愿意从DAL层完成大部分这些事情)。
但是,从技术上讲,catch子句并不返回错误。它只是返回一个带有错误信息的结果集。这是非常不同的,因为它不会导致客户端代码中的异常。这就是为什么您的结论是正确的,您应该让原始错误直接传播回客户端代码。
正如您所写的,不会将错误返回给客户端。与普通代码一样,如果不处理catch子句中的错误(更正),则应该始终在catch子句中重新抛出它(在sql中,这意味着Raiserror函数)。通常,上面所做的都是错误的,客户端代码可能有能力,也可能没有能力正确地处理与预期完全不同的记录集(一个记录集有错误信息)。有些调用(如插入、更新或删除)可能根本没有期待或查找返回的记录集.相反,如果您希望或需要在将错误返回给客户端之前处理过程中的错误,请使用Raiserror()函数。
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
-- Other code to do logging, whatever ...
Raiserror(ERROR_MESSAGE(), ERROR_NUMBER(), ERROR_STATE() )
END CATCH; 发布于 2010-06-10 17:41:33
如果Try部分中的所有内容都是select,则try Catch就没有那么有用了。但是,如果您有一个具有多个步骤的事务,catch块将用于回滚所有步骤,并可能用于在日志中记录导致问题的详细信息。但最重要的部分是回滚,以确保数据的完整性。
如果要在Try块中创建动态SQl,记录失败的动态SQl变量和传入的任何参数也是有帮助的。这可以帮助解决一些难以捕捉的错误,“我们不知道用户到底做了什么导致了问题”错误。
发布于 2010-06-10 13:15:20
不,通过在TRY/CATCH块中执行Select 1/0,select语句不会返回任何内容,而catch块中的select语句将优雅地显示错误细节。查询成功完成-没有引发错误。
如果您自己运行Select 1/0,查询就不会成功完成--它会引发错误。
在SQL中使用catch块使您有机会在那里做一些事情,而不仅仅是让错误冒泡到应用程序。
看到错误详细信息的唯一原因是您正在选择它们。如果Catch块中没有代码,则不会看到任何错误信息。
https://stackoverflow.com/questions/3014609
复制相似问题