sql - 如果其中一个查询失败,存储过程会失败吗?

标签 sql sql-server stored-procedures

假设我有一个包含SELECTINSERTUPDATE 语句的存储过程。

事务 block 内没有任何内容。也没有 Try/Catch block 。 我还将 XACT_ABORT 设置为 OFF。

如果 INSERT 失败,UPDATE 是否仍有可能发生?

INSERT 失败的原因是我将 null 值传递给不允许这样做的列。我只能访问程序抛出的称为存储过程的异常,据我所知,它没有任何严重性级别。

最佳答案

有可能。这取决于失败的严重程度。

用户代码错误通常为 16。

任何超过 20 的都自动失败。

重复键阻止插入将是 14,即非致命的。

将 NULL 插入到不支持它的列中 - 这被视为用户代码错误 (16) - 因此不会导致批处理停止。 UPDATE 将继续进行。

另一个主要因素是批处理是否将 XACT_ABORT 配置为 ON。这将导致中止整个批处理的任何失败。

这里有一些进一步的阅读:

list-of-errors-and-severity-level-in-sql-server-with-catalog-view-sysmessages

exceptionerror-handling-in-sql-server

对于 XACT_ABORT

https://www.red-gate.com/simple-talk/sql/t-sql-programming/defensive-error-handling/

https://learn.microsoft.com/en-us/sql/t-sql/statements/set-xact-abort-transact-sql

为了了解存储过程中任何步骤的结果,具有适当权限的人(例如管理员)将需要编辑存储过程并捕获错误消息。这将提供有关存储过程进度的反馈。 0 的非结构化错误(即不在 try/catch 中)代码表示成功,否则它将包含错误代码(我认为对于 NULL 插入将是 515)。正如评论中提到的那样,这是不理想的,因为它仍然不会导致批处理停止,但它会警告您存在问题。

最简单的例子:

DECLARE @errnum AS int;
-- Run the insert code
SET @errnum = @@ERROR;
PRINT 'Error code: ' + CAST(@errornum AS VARCHAR);

错误处理可能是一个复杂的问题;它需要对数据库结构和预期的传入数据有深入的了解。

选项可以包括使用中间步骤(如 HLGEM 所述)、修改 INSERT 以包含 ISNULL/COALESCE 语句以清除空值、检查客户端上的数据边删除麻烦的问题等。如果您知道要插入的行数,存储过程可以返回 SET @Rows=@@ROWCOUNTSET @errnum 相同= @@错误

如果您对存储过程没有权限,也没有能力说服管理员修改它……您无能为力。

如果您有权直接对数据库运行自己的查询(而不是仅通过存储过程或 View ),那么您可以通过对原始数据运行自己的查询来推断结果,执行存储过程更新,然后重新运行您的查询并查找更改。如果您有权限,您还可以尝试查询事务日志(fn_dblog)或错误日志(sp_readerrorlog)。

关于sql - 如果其中一个查询失败,存储过程会失败吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45092910/

相关文章:

sql - 在团队中使用 Oracle 存储过程的工具?

java - 使用 Java 从本地 SQLite 数据库读取表情符号

c# - 如何使用 C# 代码将大量数据插入 SQL Server 2008?

c# - 具有表值参数的 Dapper 动态参数

sql - 如何查找和更新包含上标字符的列

c# - SQL 查询正在复制行并在我的聚合函数中使用这些行

sql - 如何在oracle中打印游标值?

带有 JOIN、SUM 和 GROUP BY 的 SQL SELECT 查询

mysql - Oracle 相当于 MySQL 代码 "insert into dummy"返回错误消息

mysql - 获取给定日期范围内的连续月份