Bir kolonu tablodan kaldırmak, uygulama artık o kolonu kullanmıyorsa basit görünür: ALTER TABLE ... DROP COLUMN. Ama kolon bir default constraint’e, bir check constraint’e, bir foreign key’e, bir index’e ya da elle oluşturulmuş bir istatistiğe bağlıysa komut hata verir. Daha da önemlisi, kolonu gerçekten kimsenin kullanmadığından emin olmadan silmek, bir raporun ya da gece job’ının aniden bozulması demektir.
Bu yazıda kolonları güvenle emekliye ayırmak için iki aşamalı bir yöntemi ve silme script’ini, bağımlı nesneleriyle birlikte otomatik üreten bir sorguyu paylaşıyoruz.
Veritabanınızda kullanılmayan yapılar mı birikti?
Aryasoft, kullanılmayan tablo, kolon ve index'leri bağımlılıklarıyla birlikte çıkarır ve güvenli bir temizlik planı hazırlar.
İki Aşamalı Yöntem: Önce İşaretle, Sonra Sil
Kullanılmadığını düşündüğünüz bir kolonu doğrudan silmek yerine önce yeniden adlandırarak “emekliye ayrıldı” olarak işaretleyin. Örneğin kolonun adına dep_ öneki ekleyin:
EXEC sys.sp_rename N'dbo.Musteri.FaksNo', N'dep_FaksNo', N'COLUMN';
Kolonu hâlâ kullanan bir sorgu, procedure ya da rapor varsa, ad değişikliğinden sonra “Invalid column name” hatası verir ve kendini gösterir. Bu hata geri alınması kolay bir hatadır: kolonu eski adına döndürmek yeterlidir; veri kaybolmamıştır. Belirli bir bekleme süresi boyunca (örneğin bir tam iş döngüsü, ay sonu kapanışı dahil) hata gelmezse, kolon gerçekten kullanılmıyordur.
Uyarı
sp_rename, kolona başvuran stored procedure, view ve fonksiyonları otomatik güncellemez; bu nesneler yeni adla derlenemediği için çalıştıklarında hata verir. Bu, yöntemin amacıdır; ama yeniden adlandırmadan önce bağımlılıkları kontrol edin ve değişikliği uygulama ekipleriyle paylaşın.
Bazı bağımlılıklar yeniden adlandırmanın kendisini engeller: Kolonu bir CHECK constraint, bir computed column, filtered index’in WHERE koşulu ya da schema-bound bir view veya fonksiyon kullanıyorsa sp_rename Msg 15336 ya da Msg 5074 hatası verir. Testlerimizde default constraint, index, istatistik ve foreign key’ler adlandırmayı engellemedi. Bu hatayı alırsanız bağımlı nesnenin script’ini alın, nesneyi kaldırın, kolonu yeniden adlandırın ve nesneye hâlâ ihtiyaç varsa yeni adla yeniden oluşturun.
Bağımlılıkları bulmak için bir tabloyu kullanan nesneleri bulma rehberimizdeki kolon düzeyindeki sorguyu kullanın.
Silme Script’ini Üretmek
Bekleme süresi dolduktan sonra, aşağıdaki sorgu adı dep_ ile başlayan tüm kolonlar için gereken komutları doğru sırayla üretir: önce kolona bağlı constraint’ler, index’ler ve istatistikler, sonra kolonun kendisi. Sorgu yalnızca script üretir, hiçbir şeyi silmez.
DECLARE @prefix sysname = N'dep[_]%'; -- alt çizgi LIKE'ta joker olduğu için kaçırıldı
WITH hedef AS (
SELECT c.object_id, c.column_id,
QUOTENAME(OBJECT_SCHEMA_NAME(c.object_id)) + N'.' + QUOTENAME(OBJECT_NAME(c.object_id)) AS tablo,
QUOTENAME(c.name) AS kolon
FROM sys.columns AS c
JOIN sys.tables AS t ON t.object_id = c.object_id
WHERE c.name LIKE @prefix
)
SELECT adim, komut
FROM (
-- 1. Default constraint'ler
SELECT 1 AS adim, N'ALTER TABLE ' + h.tablo + N' DROP CONSTRAINT ' + QUOTENAME(dc.name) + N';' AS komut
FROM hedef AS h
JOIN sys.default_constraints AS dc ON dc.parent_object_id = h.object_id AND dc.parent_column_id = h.column_id
UNION ALL
-- 2. Kolon düzeyindeki check constraint'ler
SELECT 2, N'ALTER TABLE ' + h.tablo + N' DROP CONSTRAINT ' + QUOTENAME(cc.name) + N';'
FROM hedef AS h
JOIN sys.check_constraints AS cc ON cc.parent_object_id = h.object_id AND cc.parent_column_id = h.column_id
UNION ALL
-- 3. Kolonu içeren foreign key'ler
SELECT DISTINCT 3, N'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fk.parent_object_id)) + N'.'
+ QUOTENAME(OBJECT_NAME(fk.parent_object_id)) + N' DROP CONSTRAINT ' + QUOTENAME(fk.name) + N';'
FROM hedef AS h
JOIN sys.foreign_key_columns AS fkc
ON (fkc.parent_object_id = h.object_id AND fkc.parent_column_id = h.column_id)
OR (fkc.referenced_object_id = h.object_id AND fkc.referenced_column_id = h.column_id)
JOIN sys.foreign_keys AS fk ON fk.object_id = fkc.constraint_object_id
UNION ALL
-- 4. Kolonu içeren index'ler (gözden geçirin: index başka kolonları da içerebilir)
SELECT DISTINCT 4, N'DROP INDEX ' + QUOTENAME(i.name) + N' ON ' + h.tablo + N'; -- gözden geçirin'
FROM hedef AS h
JOIN sys.index_columns AS ic ON ic.object_id = h.object_id AND ic.column_id = h.column_id
JOIN sys.indexes AS i ON i.object_id = ic.object_id AND i.index_id = ic.index_id
WHERE i.is_primary_key = 0 AND i.is_unique_constraint = 0
UNION ALL
-- 5. Elle oluşturulmuş istatistikler
SELECT DISTINCT 5, N'DROP STATISTICS ' + h.tablo + N'.' + QUOTENAME(s.name) + N';'
FROM hedef AS h
JOIN sys.stats_columns AS sc ON sc.object_id = h.object_id AND sc.column_id = h.column_id
JOIN sys.stats AS s ON s.object_id = sc.object_id AND s.stats_id = sc.stats_id
WHERE s.user_created = 1
UNION ALL
-- 6. Kolonun kendisi
SELECT 6, N'ALTER TABLE ' + h.tablo + N' DROP COLUMN ' + h.kolon + N';'
FROM hedef AS h
) AS s
ORDER BY adim, komut;
Kritik
Üretilen script’i doğrudan çalıştırmayın. Özellikle 4. adımdaki index’ler başka kolonları da içerebilir ve başka sorgular tarafından kullanılıyor olabilir; bir index’i silmek o sorguları yavaşlatabilir. Kolon primary key ya da unique constraint’in parçasıysa script onu silmez; bu durum ayrıca değerlendirilmelidir. Script’i gözden geçirin, test ortamında çalıştırın ve üretimde çalıştırmadan hemen önce bir yedek alın.
Alan Neden Hemen Geri Gelmiyor?
DROP COLUMN çoğunlukla bir meta veri işlemidir: kolon tanımdan kalkar ama verinin kapladığı alan sayfalarda kalır. Alanı geri kazanmak için tabloyu yeniden oluşturun:
-- Clustered index'i olan tablolarda
ALTER INDEX ALL ON dbo.Musteri REBUILD;
-- Heap tablolarda
ALTER TABLE dbo.Musteri REBUILD;
Büyük tablolarda bu işlem kaynak tüketir ve log üretir; bakım penceresinde yapın. Tablo boyutlarını önce ve sonra ölçmek için tablo boyutu rehberimize bakın.
Kontrol Listesi
- Kolonun bağımlılıkları kontrol edildi ve uygulama ekipleriyle paylaşıldı.
- Kolon önce dep_ önekiyle yeniden adlandırıldı ve bir iş döngüsü boyunca beklendi.
- Silme script’i üretildi, gözden geçirildi ve test ortamında çalıştırıldı.
- Silinecek index’lerin başka sorgulara etkisi değerlendirildi.
- Üretimde çalıştırmadan önce yedek alındı; ardından alan geri kazanıldı.
İlgili Yazılar
SQL Server Danışmanlığı
Veritabanınızı güvenle sadeleştirin
Aryasoft’un kıdemli DBA ekibi kullanılmayan tablo, kolon ve index’leri bağımlılıklarıyla birlikte çıkarır; iki aşamalı, geri alınabilir bir temizlik planıyla veritabanınızı sadeleştirir.