Fala pessoal!
Nesse post de hoje eu vou trazer uma solução bem simples, mas que resolveu um problema de uma pessoa que me pediu ajuda para sincronizar dados de uma tabela entre bases diferentes, na mesma instância, da forma mais simples possível, onde você insere, atualiza ou apaga dados da tabela de origem e todas as alterações são replicadas para uma tabela espelho em outra base.
Como o foco da solução é ser rápida, simples, funcionar em qualquer versão e edição do SQL Server, não exigir um Job para ficar atualizando, tendo os dados atualizados quase que eu tempo real e são apenas algumas poucas tabelas ao invés da base inteira, pensei que a melhor solução para esse cenário é utilizar Triggers.
Existem outras soluções para resolver esse problema de replicar dados entre bases diferentes? Com certeza!
- Change Data Capture: É rápido, é simples de usar, mas não funciona em qualquer edição do SQL Server e armazena todas as alterações numa base de histórico (sem necessidade nesse caso).
- Temporal Tables: É rápido, é simples, mas só funciona a partir do SQL Server 2016, vai exigir um job para sincronizar os dados
- Always On availability group: Não será fácil de implementar e nem rápido. Não vai replicar apenas algumas tabelas e sim a base toda e não funciona em todas as versões do SQL Server
- Replicação: Não será fácil de implementar e nem rápido, mas atende aos requisitos de funcionar em todas as versões e edições do SQL Server, não exige um job, os dados são atualizados quase que em tempo real e dá para replicar apenas algumas tabelas
Criação das tabelas origem e espelho
IF (OBJECT_ID('Base1.dbo.Vendas') IS NOT NULL) DROP TABLE Base1.dbo.Vendas
CREATE TABLE Base1.dbo.Vendas (
Id_Pedido INT IDENTITY(1,1),
Dt_Pedido DATETIME,
[Status] INT,
Quantidade INT,
Valor NUMERIC(18, 2)
)
GO
IF (OBJECT_ID('Base2.dbo.Vendas') IS NOT NULL) DROP TABLE Base2.dbo.Vendas
CREATE TABLE Base2.dbo.Vendas (
Id_Pedido INT, -- Lembre de tirar o IDENTITY na tabela espelhada, se tiver
Dt_Pedido DATETIME,
[Status] INT,
Quantidade INT,
Valor NUMERIC(18, 2)
)
GO
Trigger que vai espelhar a tabela original
Com a trigger abaixo, vou replicar todas as operações de INSERT, UPDATE e DELETE feitas na tabela original para a tabela espelho.
Lembre-se de que se você alterar a estrutura da tabela de origem, como uma nova coluna, remover/renomear colunas existentes, por exemplo, você deverá sempre aplicar as mesmas alterações na tabela espelhada. Caso contrário, isso irá gerar erros na execução da trigger, a não ser que você altere o código da trigger para especificar exatamente o nome das colunas no INSERT e inclua as alterações também no UPDATE.
CREATE TRIGGER [trgEspelhoVendas] ON Base1.dbo.Vendas
AFTER INSERT, UPDATE, DELETE -- TRIGGER AFTER para evitar erros na escrita por erro na trigger
AS
BEGIN
SET NOCOUNT ON
-- UPDATE
IF (EXISTS(SELECT * FROM Inserted) AND EXISTS (SELECT * FROM Deleted))
BEGIN
UPDATE A
SET
A.Dt_Pedido = B.Dt_Pedido,
A.[Status] = B.[Status],
A.Quantidade = B.Quantidade,
A.Valor = B.Valor
FROM
Base2.dbo.Vendas A
JOIN Inserted B ON B.Id_Pedido = A.Id_Pedido
END
ELSE BEGIN
-- INSERT
IF (EXISTS(SELECT * FROM Inserted))
BEGIN
INSERT INTO Base2.dbo.Vendas
SELECT *
FROM Inserted
END
ELSE BEGIN -- DELETE
DELETE A
FROM
Base2.dbo.Vendas A
JOIN Deleted B ON B.Id_Pedido = A.Id_Pedido
END
END
END
Testando a solução
Vamos agora testar se a trigger realmente está funcionando conforme o esperado.
Vou inserir 10 linhas aleatórias na tabela dbo.Vendas no database Base1:
INSERT INTO Base1.dbo.Vendas ( Dt_Pedido, [Status], Quantidade, Valor )
SELECT
DATEADD(SECOND, (ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0) * 199999999, '2015-01-01'),
(ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0) * 9,
(ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0) * 10,
0.459485495 * (ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0) * DATEDIFF(DAY, '2015-01-01', GETDATE())
GO 10
Agora vou fazer um UPDATE na tabela original:
UPDATE Base1.dbo.Vendas
SET Valor = 9999
WHERE Id_Pedido = 1
E por fim, terminar os testes com um DELETE na tabela original:
DELETE Base1.dbo.Vendas
WHERE Id_Pedido = 7
E é isso aí, pessoal!
Espero que tenham gostado dessa dica supersimples, mas que pode ajudar bastante gente no dia a dia com uma solução simples, mas que funciona 🙂



Comentários (0)
Carregando comentários…