¡Hola, chicos!
En el post de hoy voy a traer una solución muy simple, pero resolvió un problema de alguien que me pidió ayuda para sincronizar datos de una tabla entre diferentes bases, en una misma instancia, de la forma más sencilla posible, donde insertas, actualizas o eliminas datos de la tabla fuente y todos los cambios se replican en una tabla espejo en otra base.
Como el enfoque de la solución es ser rápida, simple, funcionar en cualquier versión y edición de SQL Server, no requerir un trabajo para seguir actualizándose, tener los datos actualizados casi en tiempo real y solo hay unas pocas tablas en lugar de toda la base de datos, pensé que la mejor solución para este escenario es usar Triggers.
¿Existen otras soluciones para solucionar este problema de replicar datos entre diferentes bases de datos? ¡Con seguridad!
- Cambiar captura de datos: Es rápido, fácil de usar, pero no funciona en ninguna edición de SQL Server y almacena todos los cambios en una base de datos histórica (no es necesario en este caso).
- Tablas Temporales: Es rápido, es sencillo, pero solo funciona desde SQL Server 2016, requerirá un trabajo para sincronizar los datos.
- Grupo de disponibilidad siempre activo: No será fácil de implementar ni rápido. No replicará solo algunas tablas, sino toda la base de datos y no funciona en todas las versiones de SQL Server.
- Replicación: No será fácil de implementar ni rápido, pero cumple con los requisitos de trabajar en todas las versiones y ediciones de SQL Server, no requiere trabajo, los datos se actualizan casi en tiempo real y es posible replicar solo unas pocas tablas.
Creación de tablas fuente y espejo.
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
Activador que reflejará la tabla original.
Con el activador a continuación, replicaré todas las operaciones INSERTAR, ACTUALIZAR y ELIMINAR realizadas en la tabla original en la tabla reflejada.
Recuerde que si cambia la estructura de la tabla de origen, como una nueva columna, elimina o cambia el nombre de las columnas existentes, por ejemplo, siempre debe aplicar los mismos cambios a la tabla reflejada. De lo contrario, esto generará errores al ejecutar el disparador, a menos que cambies el código del disparador para especificar exactamente el nombre de las columnas en el INSERT y también incluyas los cambios en el 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
Probando la solución
Probemos ahora si el disparador realmente funciona como se esperaba.
Insertaré 10 filas aleatorias en la tabla dbo.Vendas en la base de datos 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
Ahora voy a hacer una ACTUALIZACIÓN en la tabla original:
UPDATE Base1.dbo.Vendas
SET Valor = 9999
WHERE Id_Pedido = 1
Y por último finalizar las pruebas con un DELETE en la tabla original:
DELETE Base1.dbo.Vendas
WHERE Id_Pedido = 7
¡Y eso es todo, amigos!
Espero que te haya gustado este consejo súper sencillo, pero puede ayudar a mucha gente en su vida diaria con una solución sencilla, pero funciona 🙂



Comentários (0)
Carregando comentários…