Cómo validar y sincronizar esquemas en SQL Server: paso a paso
La validación y sincronización de esquemas en SQL Server ayuda a garantizar que dos bases de datos (por ejemplo desarrollo y producción) tienen tablas, columnas y tipos coherentes. Esto evita errores de despliegue y fallos en aplicaciones que esperen un esquema específico.
Pre-requisitos
- SQL Server (versión compatible con sys.columns e INFORMATION_SCHEMA)
- Permisos de lectura en ambas bases de datos a comparar
- SQL Server Management Studio (SSMS) u otra herramienta SQL
Paso 1: Por qué comparar esquemas y qué diferencias buscar
Antes de sincronizar es importante entender qué puede diferir: tablas ausentes, columnas ausentes, tipos de datos distintos, nulabilidad diferente o columnas extra. Validar evita cambios destructivos y ayuda a planificar scripts de migración.
Paso 2: Crear una vista de comparación básica entre dos bases
Vamos a construir una consulta que liste tablas y columnas de cada base usando INFORMATION_SCHEMA. Sustituya db_origem y db_destino por los nombres reales.
-- Ajuste db_origem e db_destino para os nomes reais das bases
DECLARE @db_origem SYSNAME = 'db_origem';
DECLARE @db_destino SYSNAME = 'db_destino';
SELECT
o.TABLE_SCHEMA AS schema_origem,
o.TABLE_NAME AS table_origem,
o.COLUMN_NAME AS column_origem,
o.DATA_TYPE AS type_origem,
o.IS_NULLABLE AS nullable_origem,
d.TABLE_SCHEMA AS schema_destino,
d.TABLE_NAME AS table_destino,
d.COLUMN_NAME AS column_destino,
d.DATA_TYPE AS type_destino,
d.IS_NULLABLE AS nullable_destino
FROM
(SELECT * FROM [db_origem].INFORMATION_SCHEMA.COLUMNS) o
FULL OUTER JOIN
(SELECT * FROM [db_destino].INFORMATION_SCHEMA.COLUMNS) d
ON
o.TABLE_SCHEMA = d.TABLE_SCHEMA
AND o.TABLE_NAME = d.TABLE_NAME
AND o.COLUMN_NAME = d.COLUMN_NAME
ORDER BY COALESCE(o.TABLE_SCHEMA,d.TABLE_SCHEMA), COALESCE(o.TABLE_NAME,d.TABLE_NAME), COALESCE(o.ORDINAL_POSITION, d.ORDINAL_POSITION);
Paso 3: Identificar diferencias importantes
Con la consulta anterior, busque:
- Registros donde column_origem IS NULL → tabla/columna solo en la base destino.
- Registros donde column_destino IS NULL → solo en la base origen.
- Registros donde type_origem <> type_destino o la nulabilidad difiere → incompatibilidades.
Paso 4: Generar script de sincronización para tablas/columnas ausentes
Ejemplo de generación automática de ADD COLUMN en la base destino para columnas que existen en el origen y faltan en el destino. Revisar manualmente antes de ejecutar.
DECLARE @db_origem SYSNAME = 'db_origem';
DECLARE @db_destino SYSNAME = 'db_destino';
SELECT
'ALTER TABLE [' + c.TABLE_SCHEMA + '].[' + c.TABLE_NAME + '] ADD [' + c.COLUMN_NAME + '] ' +
UPPER(c.DATA_TYPE) +
CASE WHEN c.CHARACTER_MAXIMUM_LENGTH IS NOT NULL AND c.DATA_TYPE LIKE '%char%' THEN '(' +
CASE WHEN c.CHARACTER_MAXIMUM_LENGTH = -1 THEN 'MAX' ELSE CAST(c.CHARACTER_MAXIMUM_LENGTH AS VARCHAR(10)) END +
')' ELSE '' END +
CASE WHEN c.COLUMN_DEFAULT IS NOT NULL THEN ' DEFAULT ' + c.COLUMN_DEFAULT ELSE '' END +
CASE WHEN c.IS_NULLABLE = 'NO' THEN ' NOT NULL' ELSE ' NULL' END AS add_column_sql
FROM
[db_origem].INFORMATION_SCHEMA.COLUMNS c
LEFT JOIN
[db_destino].INFORMATION_SCHEMA.COLUMNS d
ON c.TABLE_SCHEMA = d.TABLE_SCHEMA AND c.TABLE_NAME = d.TABLE_NAME AND c.COLUMN_NAME = d.COLUMN_NAME
WHERE d.COLUMN_NAME IS NULL
ORDER BY c.TABLE_SCHEMA, c.TABLE_NAME, c.ORDINAL_POSITION;
Paso 5: Tratar tipos incompatibles y NULL/NOT NULL
Para diferencias de tipo o nulabilidad, no automatice a ciegas. Genere un informe y luego planifique cambios seguros: crear una columna nueva con el tipo correcto, copiar datos con CAST/CONVERT, probar, luego eliminar la antigua y renombrar.
-- Exemplo de abordagem para mudar tipo: criar nova coluna, copiar e substituir
ALTER TABLE [schema].[tabela] ADD [col_nova] VARCHAR(100) NULL;
UPDATE [schema].[tabela] SET [col_nova] = CAST([col_antiga] AS VARCHAR(100));
-- Verificar integridade
ALTER TABLE [schema].[tabela] DROP COLUMN [col_antiga];
EXEC sp_rename '[schema].[tabela].[col_nova]', 'col_antiga', 'COLUMN';
Paso 6: Automatizar verificación regular con job
Creé un SQL Server Agent Job que ejecute la consulta de comparación y envíe resultados por correo electrónico o registre en una tabla de auditoría. Así detecta divergencias antes de que se conviertan en problemas en producción.
-- Exemplo simplificado: inserir diferenças numa tabela de auditoria
IF OBJECT_ID('dbo.SchemaDiffAudit') IS NULL
CREATE TABLE dbo.SchemaDiffAudit (
AuditDate DATETIME2, TableSchema SYSNAME, TableName SYSNAME, ColumnName SYSNAME, Issue NVARCHAR(200)
);
INSERT INTO dbo.SchemaDiffAudit (AuditDate, TableSchema, TableName, ColumnName, Issue)
SELECT GETDATE(), COALESCE(o.TABLE_SCHEMA,d.TABLE_SCHEMA), COALESCE(o.TABLE_NAME,d.TABLE_NAME),
COALESCE(o.COLUMN_NAME,d.COLUMN_NAME),
CASE
WHEN o.COLUMN_NAME IS NULL THEN 'Only in dest'
WHEN d.COLUMN_NAME IS NULL THEN 'Only in origin'
WHEN o.DATA_TYPE <> d.DATA_TYPE THEN 'Type mismatch: ' + o.DATA_TYPE + ' vs ' + d.DATA_TYPE
WHEN o.IS_NULLABLE <> d.IS_NULLABLE THEN 'Nullability mismatch'
ELSE 'Other'
END
FROM [db_origem].INFORMATION_SCHEMA.COLUMNS o
FULL OUTER JOIN [db_destino].INFORMATION_SCHEMA.COLUMNS d
ON o.TABLE_SCHEMA = d.TABLE_SCHEMA AND o.TABLE_NAME = d.TABLE_NAME AND o.COLUMN_NAME = d.COLUMN_NAME
WHERE o.COLUMN_NAME IS NULL OR d.COLUMN_NAME IS NULL OR o.DATA_TYPE <> d.DATA_TYPE OR o.IS_NULLABLE <> d.IS_NULLABLE;
Verificar el resultado
Revise la salida de las consultas: la lista debe mostrar solo diferencias reales. Tras ejecutar scripts de sincronización, vuelva a ejecutar la comparación —el número de discrepancias debería bajar a cero. Pruebe las aplicaciones dependientes para garantizar que no hay regresiones.
Conclusión
Comparar y sincronizar esquemas en SQL Server reduce riesgos en despliegues y mantiene la cohesión entre entornos. Próximos pasos: crear copias de seguridad antes de cambios, probar en entorno de staging e integrar la verificación en el proceso CI/CD. Consejo: validar siempre manualmente los scripts generados automáticamente antes de ejecutarlos en producción.