gr9*_*28x 6 sql transactions try-catch
我在MSDN Lbrary中发现和文章解释说try/catch不能处理无法找到对象时抛出的错误.所以,即使我在try/catch中包装一个事务,回滚短语也不会执行:
BEGIN TRY
BEGIN TRANSACTION
SELECT 1 FROM dbo.TableDoesNotExists
PRINT ' Should not see this'
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
SELECT
ERROR_MESSAGE()
END CATCH
--PRINT 'Error Number before go: ' + CAST(@@Error AS VARCHAR)
go
PRINT 'Error Count After go: ' + CAST(@@Error AS VARCHAR)
PRINT 'Transaction Count ' + CAST(@@TRANCOUNT AS VARCHAR)
Run Code Online (Sandbox Code Playgroud)
当对象不存在时,特别是涉及事务时,建议的方法是处理抛出的错误.我应该用这一段代码代替最后两个打印语句:
IF @@ERROR <> 0 AND @@TRANCOUNT > 0
BEGIN
PRINT 'Rolling back txn'
ROLLBACK TRANSACTION
END
go
PRINT 'Transaction Count again: ' + CAST(@@TRANCOUNT AS VARCHAR)
Run Code Online (Sandbox Code Playgroud)
为什么要尝试从不存在的表中检索数据?
\n\n数据库的基本构建块是表。不知道架构中的内容本质上是试图将 SQL 用作动态语言,但事实并非如此。
\n\n我会重新考虑你的设计;如果不了解有关数据库中的表及其预期用途的更多信息,其他人很难在这方面提供帮助。请为您的问题添加更多信息。
\n\n编辑\n我读过 BOL,当对象不存在时处理错误的推荐方法如下:
\n\n\n\n\n您可以使用 TRY\xe2\x80\xa6CATCH 通过在 TRY 块内\n 单独的批处理中执行\n 错误生成代码来处理编译或语句级重新编译期间发生的错误。\n 例如,您可以通过将代码放入存储过程中或使用 sp_executesql 执行动态 Transact-SQL 语句来完成此操作。这允许 TRY\xe2\x80\xa6CATCH 在比错误发生时更高的执行级别捕获错误。
\n
我使用以下过程对此进行了测试
\n\nCREATE PROCEDURE [dbo].[BrokenProcedure]\nAS\nBEGIN\n SET NOCOUNT ON;\n SELECT * FROM MissingTable\nEND\nGO\nRun Code Online (Sandbox Code Playgroud)\n\n然后在块内调用它TRY..CATCH:
BEGIN TRY\n PRINT 'Error Number before: ' + CAST(@@Error AS VARCHAR)\n EXECUTE [dbo].[BrokenProcedure] \n PRINT ' Should not see this'\nEND TRY\nBEGIN CATCH\n PRINT 'Error Number in catch: ' + CAST(@@Error AS VARCHAR)\nEND CATCH\nRun Code Online (Sandbox Code Playgroud)\n\n产生以下输出:
\n\n\n\n\n之前的错误编号:0
\n\ncatch 中的错误号:208
\n
这不是一个完美的解决方案,因为您必须为所有表访问创建过程(或使用动态 SQL),但这是 MS 推荐的方法。
\n