AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 333495
Accepted
Ross Bush
Ross Bush
Asked: 2023-11-28 01:24:18 +0800 CST2023-11-28 01:24:18 +0800 CST 2023-11-28 01:24:18 +0800 CST

当具有动态 SQL 的 SP 出错时,触发器内部的 Catch 块不会被命中 - 导致较大的事务失败

  • 772

我不喜欢触发器和动态 sql,但是,我正在使用的东西需要两者。

CREATE TRIGGER [dbo].[GenerateDynamicFormItemViews] ON [dbo].[tblFormItems] AFTER INSERT, UPDATE
AS
BEGIN   
    SET NOCOUNT ON;
    DECLARE @DatabaseName NVARCHAR(100)
    DECLARE @FormItemID INT

    DECLARE db_cursor CURSOR FOR
    SELECT SourceID,FormItemID from Inserted

    OPEN db_cursor  
    FETCH NEXT FROM db_cursor INTO @DatabaseName, @FormItemID

    WHILE @@FETCH_STATUS = 0  
    BEGIN  

        BEGIN TRY    
            EXEC spAddEditFormItemView @FormItemID, @DatabaseName WITH RESULT SETS NONE
        END TRY    
        BEGIN CATCH 
            INSERT INTO AdminErrorLog(SourceID, ErrorNumber, ErrorState, ErrorSeverity, ErrorProcedure, ErrorLine, ErrorMessage, ErrorDateTime) 
            SELECT @DatabaseName, ERROR_NUMBER(), ERROR_STATE(), ERROR_SEVERITY(), ERROR_PROCEDURE(), ERROR_LINE(), ERROR_MESSAGE(), GETDATE()
        END CATCH     

        FETCH NEXT FROM db_cursor INTO @DatabaseName, @FormItemID
    END

    CLOSE db_cursor  
    DEALLOCATE db_cursor
END 

这就是正在发生的事情。

  1. AWS DMS 复制任务正在批量复制 10,000 个数据。复制的实现是一个黑匣子,但连接上似乎存在嵌套事务。
  2. EXEC spAddEditFormItemView 调用一个存储过程,该存储过程执行动态 sql 并在一条记录上出错。
  3. CATCH 块永远不会被执行
  4. 该错误永远不会进入 AdminErrorLog。
  5. AWS Batch 出错并且从未提交,整个任务失败。
  6. 在扩展事件中,捕获以下 SQL 错误。这是导致任务失败的错误。我读到了有关命令既不能处于提交或回滚状态的情况,但确实没有完全理解这个概念。

消息:当前事务无法提交,并且无法支持写入日志文件的操作。回滚事务。

严重程度:16

任何人都可以解释为什么 catch 块没有被捕获以及为什么客户端应用程序得到(我的猜测是)sql 异常并回滚所有内容。我的猜测是动态 sql 异常的处理方式不同,并且隐式触发事务正在回滚而不是捕获错误。另外,有谁知道避免传播异常的方法吗?

我敢打赌最安全的解决方案是修改触发器以将 sql 命令填充到表中,然后让 sql 代理作业查找每分钟左右运行的命令。

编辑-添加重新创建的过程:在 SSSM 中:

EXEC [spAddEditFormItemView] 30032,'VP_BENCHMARKING_V05'

命令成功完成。

完成时间:2023-11-27T16:11:18.1762097-05:00

在触发器中,它会强制回滚并显示可怕的错误消息。

ALTER PROCEDURE [dbo].[spAddEditFormItemView] ( 
    @FormItemID int,
    @Schema nvarchar(100)
)
AS
    DECLARE @SQL NVARCHAR(MAX) = 'e2e2e2e2e'
    BEGIN TRY   
        EXEC (@SQLCommand)      
    END TRY
    BEGIN CATCH
        DECLARE @X INT
    END CATCH

编辑:我现在可以在 SSMS 中复制。

在此输入图像描述

sql-server
  • 1 1 个回答
  • 84 Views

1 个回答

  • Voted
  1. Best Answer
    David Browne - Microsoft
    2023-11-28T06:51:04+08:002023-11-28T06:51:04+08:00

    触发器作为事务的一部分运行。因此,无论 catch 块是否运行,事务都注定会失败,并且永远无法提交到 AdminErrorLog 表。

    因此 CATCH 块是否执行并不重要。但事实并非如此,因为触发器范围内的错误通常会中止批处理。请参阅 Erland Sommarskog 关于 TSQL 错误处理的经典文章: https: //www.sommarskog.se/error-handling-I.html#triggercontext

    • 4

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve