Tenho uma trigger em uma tabela ( source ) que os dados devem ser copiados para a outra ( target ) em outro banco de dados. Estou tentando implementar o processo de sincronização personalizado para dados: quero que o banco de dados de destino (tabela) esteja atualizado para o banco de dados de origem (tabela). Tenho 3 centenas de tabelas para sincronizar. Alguns deles têm estrutura de dados física diferente. Não posso usar abordagens padrão do Sql Server (replicação, DTS...) devido a diferentes esquemas de dados e outras restrições (tempo de implementação, problemas de ambiente...). Meu objetivo é: esse gatilho NÃO deve impactar em INSERT, DELETE, UPDATE de registros em uma tabela de origem. Eu tentei assim solução:
CREATE TRIGGER dbo.MyTrigger
...
AFTER INSERT
....
BEGIN TRY
--RAISERROR('Test error', 16, 2)
END TRY
BEGIN CATCH
-- nothing
END CATCH
Eu inseri RAISEERROR
para simular erro. Eu esperava, try/catch
suprimido que o erro e o registro foram inseridos (excluídos ou atualizados) com sucesso. Não. Não funciona. Eu tenho erro:
Foi gerado um erro durante a execução do gatilho. O lote foi abortado e a transação do usuário, se houver, foi revertida.
É possível realizar minha solução dessa maneira. Como posso capturar e segurar (suprimir) qualquer erro no meu gatilho?
Que sentido usar try/catch
no trigger se não funcionar?
A transação está condenada a praticamente qualquer exceção e deve ser revertida.
De "Usando TRY...CATCH no Transact-SQL" no MSDN
Este exemplo mostra o porquê. XACT_STATE() não registra uma transação implícita (por exemplo, nenhum BEGIN TRAN explícito)
Encontrei uma solução um pouco arriscada* que suprime "transações não confirmáveis" que ocorrem em um gatilho DML.
Cuidado: geralmente não é seguro suprimir erros de transação em um gatilho, então pense muito antes de tentar fazer isso. Esse método é extremamente inseguro se houver outros gatilhos DML na mesma tabela, porque você pode estar confirmando dados inválidos que outro gatilho pretende reverter.
Para suprimir erros graves que ocorrem em seu gatilho DML: