AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 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

O bloco Catch dentro de um gatilho não é atingido quando um SP com erros de SQL dinâmico ocorre - causando falha na transação maior

  • 772

Não sou fã de gatilhos e SQL dinâmico, porém, o que estou trabalhando requer ambos.

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 

Eis aqui o que está acontecendo.

  1. Uma tarefa de replicação do AWS DMS está replicando dados em lotes de 10.000. A implementação da replicação é uma caixa preta, mas parece haver transações aninhadas nas conexões.
  2. EXEC spAddEditFormItemView chama um procedimento armazenado que executa o SQL dinâmico e gera erros em um registro.
  3. O bloco CATCH nunca é executado
  4. O erro nunca chega ao AdminErrorLog.
  5. O AWS Batch apresenta erros e nunca é confirmado e toda a tarefa falha.
  6. Em eventos estendidos, o seguinte erro sql é detectado. Este é o erro que falhou na tarefa. Eu li sobre condições em que os comandos não podem estar em estado de confirmação ou reversão, mas realmente não entendi totalmente esse conceito.

mensagem: A transação atual não pode ser confirmada e não pode suportar operações gravadas no arquivo de log. Reverta a transação.

gravidade: 16

Alguém pode explicar por que o bloco catch não está sendo capturado e por que o aplicativo cliente está recebendo, o que eu acho, uma exceção sql e revertendo tudo. Meu palpite é que as exceções dinâmicas de SQL estão sendo tratadas de maneira diferente e a transação de gatilho implícita está sendo revertida em vez de capturar o erro. Além disso, alguém sabe uma maneira de evitar que a exceção seja propagada?

Aposto que a solução mais segura seria modificar o gatilho para amontoar os comandos sql em uma tabela e, em seguida, fazer com que um trabalho do agente sql procure comandos para serem executados a cada minuto ou mais.

EDIT - Adicionando procedimento para recriar: No SSSM:

EXEC [spAddEditFormItemView] 30032,'VP_BENCHMARKING_V05'

Comandos concluídos com sucesso.

Prazo de conclusão: 2023-11-27T16:11:18.1762097-05:00

No gatilho ele força um rollback com uma mensagem de erro horrível.

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

EDIT: agora posso duplicar no SSMS.

insira a descrição da imagem aqui

sql-server
  • 1 1 respostas
  • 84 Views

1 respostas

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

    O gatilho é executado como parte da transação. Portanto, independentemente de o bloco catch ser executado ou não, a transação está condenada e nunca poderá ser confirmada na tabela AdminErrorLog.

    Portanto, realmente não importa se o bloco CATCH é executado. Mas isso não acontece porque erros no escopo do gatilho geralmente abortam o lote. Veja o artigo clássico de Erland Sommarskog sobre tratamento de erros TSQL aqui: https://www.sommarskog.se/error-handling-I.html#triggercontext

    • 4

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

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

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve