【发布时间】:2019-03-19 13:25:34
【问题描述】:
我有一个应该从数据库中删除模式的存储过程。我从后端执行这个存储过程(使用 C#)。结果,如果删除成功与否,我想接收布尔值。
var result = await session.Sp<bool>(c => c.spDeleteSchemaTotally, new { schemaName})
.SingleAsync()
.ConfigureAwait(false);
if (result)
{
tracer.Info("Deleted successfully");
}
else
{
tracer.Warn("Schema was not deleted appropriately");
}
存储过程:
ALTER PROCEDURE [dbo].[spDeleteSchemaTotally]
(@schemaName NVARCHAR(100))
AS
SET FMTONLY OFF
BEGIN TRY
UPDATE SchemaList
SET [Status] = 2 /* DELETING */
WHERE SchemaName = @schemaName
EXEC [dbo].[spDeleteSchema] @schemaName
EXEC [dbo].[spDeleteSchemaOwner] @schemaName
EXEC [dbo].[spDeleteSchemaUserRoles] @schemaName
UPDATE SchemaList
SET [Status] = 1 /* DELETED */,
SchemaName = SchemaName + '|deleted|' + FORMAT(GETUTCDATE(), 'MM-d-yyyy-hh:mm')
WHERE SchemaName = @schemaName
SELECT CAST(1 AS BIT);
END TRY
BEGIN CATCH
UPDATE SchemaList
SET [Status] = 3 /* ERRORED */
WHERE SchemaName = @schemaName
SELECT CAST(0 AS BIT);
END CATCH
我有一个表,其中存储了所有模式的列表。对于每个模式,我都有一些状态。每个模式都有一些自己的表、规则等。
但由于某些原因,我注意到(有时)发生了一些错误,并且模式留下了状态 2(正在删除)。什么样的错误 - 我不知道,因为无法抓住这一刻。
逻辑上认为,存储过程内部发生了一些错误,但为此,我有 catch 块。根据this topic 内部存储过程中的错误应该由外部catch 处理。所以我认为一切都以正确的方式编写......但不正确的行为仍然存在。
有人可以指出我在上述存储过程中处理错误的正确方法吗?
我正在使用 SQL Server。
【问题讨论】:
-
在不触发 CATCH 块的情况下如何知道发生了错误?您能否提供一个其他人可以运行的脚本来重现该行为?
-
@TabAlleman,很难重现这个“错误”或我对“错误”的假设。手动尝试过 - 但没有运气。
-
我相信你需要在调用的每个单独的 sp 中都有 catch 块。如果有意义的话,存储过程中的错误超出了调用 SQL 的范围。
-
你能分享其他程序的代码吗?他们也有尝试/静噪块吗?你的 catch 问题是,如果你确实捕获了一个错误,那么你已经吞下了细节。调试起来会非常痛苦,因为您只是将状态更新为 3 并且不对错误信息做任何有用的操作。
-
使用 try/catch 并不能替代使用事务来保证在发生错误时回滚所有数据库更新。似乎您需要更彻底地研究 Erland 关于错误处理的讨论。吃掉错误将使诊断任何问题变得不可能。
标签: c# sql sql-server stored-procedures error-handling