SQL Server'da İki Farklı Veritabanındaki Aynı Tabloyu Kolon Bazında Karşılaştırmak;
SQL Server’da İki Farklı Veritabanındaki Aynı Tabloyu Kolon Bazında Karşılaştırma
Bu sorgu neyi çözer?
- Prod / Test / Dev veritabanları arasındaki kolon uyumsuzluklarını tespit eder.
- Eksik kolonları (yalnızca DB1 veya yalnızca DB2) listeler.
- Kolon veri tipi veya uzunluğu farklı olan alanları tek satırda gösterir.
- Migration / versiyon kontrolü öncesi riskli farkları netleştirir.
Genel çalışma mantığı
- Her iki veritabanındaki tablo kolonları ayrı geçici tablolara alınır.
- Bu geçici tablolar FULL OUTER JOIN ile kolon adına göre eşleştirilir.
- Kolon yokluğu, veri tipi veya uzunluk farkları CASE yapısı ile işaretlenir.
Adım adım açıklama
1) Geçici tabloların oluşturulması
Öncelikle her iki veritabanından okunacak kolon bilgilerini tutmak için iki adet geçici tablo oluşturulur. Bu tablolar; kolon adı, veri tipi ve karakter uzunluğu bilgilerini saklar.
IF OBJECT_ID('tempdb..#DB1Columns') IS NOT NULL DROP TABLE #DB1Columns
IF OBJECT_ID('tempdb..#DB2Columns') IS NOT NULL DROP TABLE #DB2Columns
CREATE TABLE #DB1Columns (
COLUMN_NAME NVARCHAR(128),
DATA_TYPE NVARCHAR(128),
CHARACTER_MAXIMUM_LENGTH INT
)
CREATE TABLE #DB2Columns (
COLUMN_NAME NVARCHAR(128),
DATA_TYPE NVARCHAR(128),
CHARACTER_MAXIMUM_LENGTH INT
)
2) İlk veritabanından kolon bilgisini alma
INFORMATION_SCHEMA.COLUMNS görünümü kullanılarak
ilk veritabanındaki ilgili tablonun kolon bilgileri alınır.
Veritabanı adı dinamik olduğu için dinamik SQL tercih edilmiştir.
DECLARE @SQL1 NVARCHAR(MAX) = ' INSERT INTO #DB1Columns (COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH) SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM [1.ci DB ADI].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''TABLO ADI'' ' EXEC sp_executesql @SQL1
3) İkinci veritabanından kolon bilgisini alma
Aynı işlem ikinci veritabanı için de yapılır ve kolon bilgileri ikinci geçici tabloya aktarılır.
DECLARE @SQL2 NVARCHAR(MAX) = ' INSERT INTO #DB2Columns (COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH) SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM [2.ci DB ADI].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''TABLO ADI'' ' EXEC sp_executesql @SQL2
4) Kolon bazında karşılaştırma
Son aşamada iki geçici tablo FULL OUTER JOIN ile birleştirilir. Böylece yalnızca bir veritabanında olan kolonlar da görünür hale gelir.
SELECT
COALESCE(a.COLUMN_NAME, b.COLUMN_NAME) AS Column_Name,
a.DATA_TYPE AS DB1_DataType,
a.CHARACTER_MAXIMUM_LENGTH AS DB1_Length,
b.DATA_TYPE AS DB2_DataType,
b.CHARACTER_MAXIMUM_LENGTH AS DB2_Length,
CASE
WHEN a.COLUMN_NAME IS NULL THEN 'Yalnızca DB2'
WHEN b.COLUMN_NAME IS NULL THEN 'Yalnızca DB1'
WHEN a.DATA_TYPE <> b.DATA_TYPE
OR ISNULL(a.CHARACTER_MAXIMUM_LENGTH, -1) <> ISNULL(b.CHARACTER_MAXIMUM_LENGTH, -1)
THEN 'Farklı'
ELSE 'Aynı'
END AS Durum
FROM #DB1Columns a
FULL OUTER JOIN #DB2Columns b
ON a.COLUMN_NAME = b.COLUMN_NAME
ORDER BY Column_Name;
Sonuç nasıl okunmalı?
- Yalnızca DB1: Kolon sadece birinci veritabanında var.
- Yalnızca DB2: Kolon sadece ikinci veritabanında var.
- Farklı: Kolon adı aynı ancak veri tipi veya uzunluğu farklı.
- Aynı: Kolon adı, veri tipi ve uzunluğu birebir aynı.
NUMERIC_PRECISION, NUMERIC_SCALE veya
IS_NULLABLE alanlarını da geçici tablolara ekleyerek
çok daha detaylı bir şema karşılaştırması yapabilirsiniz.