ALTER TABLE .. ALTER COLUMN?
Giriş
Gün içinde sıkça gerçekleşen kimi DDL işlemlerinden birisi de ALTER operasyonlarıdır. ALTER ile bahsedilen objenin tanımını değiştirmek mümkündür. ALTER TABLE ise anlaşılacağı üzere tablonun tanımında değişiklik yapmak için kullanılan DDL Deyimidir. SQL Server Management Studio ile bir instance bağlanıp, bir veritabanındaki bir tabloya yeni bir kolon eklemek istediğimizde ya bu operasyonu tabloyu drop-create ederek ya da ALTER TABLE .. ALTER COLUMN cümlesi ile gerçekleştirilir. Peki hangi durumlarda tablo yeniden oluşturulur, hangi durumlarda ALTER TABLE .. ALTER COLUMN ile değiştirmek mümkündür?
PAGE Nedir?
Kabaca, Page SQL Server’ın veriyi saklamak için kullandığı en küçük birimdir ve 8K’dan oluşur. Page’lerin bir özelliği de SQL Server Storage Engine’nin manipüle edebileceği şekilde tasarlanmış olmasıdır. Storage Engine nasıl verimli kullanır page’leri gibi konuları page’lerin logical tasarımını inceledikten sonra daha da anlaşılır hale gelir. Bir tablo düşünün ve üzerinde veri tutulsun. Bu veriler, veritabanının ve tablonun dizaynına göre page’lere nasıl dağıtılacağına SQL Server Storage Engine tarafından karar verilecektir.
Tablo yaratıldığında, tanımlanan kolonların veritipine göre insert edilen kaydın bir page üzerinde nasıl tanımlanacağı belirtilmiştir.
Kayıt üzerinde Char, int gibi sabit yani 8 byte, 4 byte gibi kesin tanımlı değişkenler kullandıysa page üzerinde farklı saklanır, Varchar gibi aldığı değerin miktarı kadar veri saklanıyorsa farklı tanımlanır, tarih ve saatNULL değer içeriyorsa farklı saklanır gibi yerleşimlerle karşılaşırız. Bu saklama şekli ise Storage Engine’nin veriye istediği gibi erişmesi için tasarlanmıştır.
ALTER TABLE ve ALTER TABLE .. ALTER COLUMN?
Bir tablonun DDL’ini ALTER TABLE ile değiştirebiliriz. SQL Server Management Studio ile bir instance bağlanıp; Instance-->Database-->Tablo-->Dizayn adımlarını izleyerek: karşımıza çıkan ekrandan, bir kolonun veritipini değiştirebiliriz. Daha sonra sakla ile bu tabloyu üzerinde veri ile birlikte değiştirebiliriz. Bu Management Studio ile gereken ayarlar yapıldığında bazen çok uzun sürer, bazen de çok kısa. Eğer değişikliği yapıp, saklamadan önce Generate Script derseniz, arka planda çalışan SQL cümlelerini görebilirsiniz. Bu cümlelerde kimi zaman ALTER Komutunu, kimi zaman da DROP TABLE – CREATE TABLE şeklindedir. Kısa veya uzun sürmesi de bununla ilgilidir.
Resimde gördüğünüz gibi DateTime veritipi olan bir kolonu int veritipine çevirmek istiyorum.

Fakat bunun için Generate Script dediğimde ise aşağıdaki script’i oluşturacaktır.

ALTER TABLE .. ALTER COLUMN cümlesi ile Script’i üretmemiş, tabloyu geçici bir tablo oluşturarak recreate etmiştir.
İşte burada kimi kısıtlar görürüz ki bunlar:
- Değiştirilecek kolon text, image, ntext ve rowversion tipine dönüştürülemez.
- ROWGUIDCOL tipinde bir kolonu değiştiremeyiz.
- COMPUTED veya REPLICATE Kolonları değiştiremeyiz.
- Değiştirilecek kolon üzerinde PRIMARY KEY veya FOREIGN KEY constraint’i varsa bu kolon değiştirilemez.
- Değiştirilecek kolon bir Computed kolonda geçiyor ise değiştirilemez.
- TimeStamp Tipinde bir kolonu değiştiremeyiz.
- Eğer değiştirilecek kolon bir index’te yer alıyor ise: sadece veri tanımının uzunluğu değiştirilebilir ya da verinin NULL olacağını değiştirebiliriz.(varchar(14) à varchar(30))
- Değiştirilecek kolon üzerinde UNIQUE veya CHECK constraint tanımlı ise: sadece veri tanımının uzunluğu değiştirilebilir.
- Değiştirilecek kolon üzerinde DEFAULT Constraint var ise de: Veri tanımının uzunluğu arttırılıp azaltılabilir, NULL olması koşulu değiştirilebilir veya Ondalık, tam sayı basamakları değiştirilebilir.
- Değiştirilecek kolonun veritipinin yeni veritipine IMPLICIT çevrimine izin veriyorsa ALTER COLUMN ile değiştirilebilir.
- Son olarak da yeni veritipi her zaman ANSI_PADDING Semantiğinde olmalıdır.
Yukarıda saydığımız kısıtlar ile karşılaşılmasına tek sebep ise, SQL Server’ın veriyi sakladığı page’lerde bulunan kayıtları saklama şeklidir. NULL için bir kullanılan bir bit-ARRAY tanımlanmışken, DateTime veritipi için farklı bir kayıt sıralamasına karşılık gelen bit-ARRAY sözkonusudur.
Kaynak: SQL Server Internals 2012, Kalen Delaney