Bu makalede veritabanı collation değiştirdikten sonra tablolarımız eski collation üzerinde kalmaktadır. Bunun için tablolarımızın yeni collation üzerine taşınması gerekmektedir. Tüm tablolarımızı yeni collation üzerine geçirdikten sonra tablo üzerinde herhangi bir kısıtlama varsa ilgili collation değişikliğine izin vermez. Bunun için tablo üzerinde collation yapısının ilgili kısıtlamaların kaldırılarak değiştirilmesi gerekmektedir.
Aşağıdaki komut ile veritabanı altında bulunan tabloların collation yapısını belirlemiş olduğumuz yeni collation yapısına göre değiştirebiliriz.
declare @NewCollation sysname
set @NewCollation = 'Turkish_CI_AS'
select
'ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(stable.schema_id)) + '.' + QUOTENAME(stable.name) +
' ALTER COLUMN ' + QUOTENAME(scol.name) + ' ' + stype.name + '(' +
CASE WHEN scol.max_length = -1 THEN 'max' ELSE CONVERT(varchar(10),scol.max_length) END +
') collate ' + @NewCollation + '
go
'
from sys.columns scol inner join sys.tables stable on scol.object_id = stable.object_id
inner join sys.types stype on scol.user_type_id = stype.user_type_id
where scol.collation_name is not null and OBJECTPROPERTY(stable.object_id,N'IsMSShipped')=0
Dikkat ederseniz sadece collation değişim olabilecek kolonlarını script’ini vermektedir.

Yukarıdaki script’i çalıştırdığımızda bazı bazı collation değişimlerinde yukarıda belirttiğimiz gibi hata mesajı almaktayız.
Msg 5074, Level 16, State 1, Line 25
The index ‘IX_Address_AddressLine1_AddressLine2_City_StateProvinceID_PostalCode’ is dependent on column ‘AddressLine1’.
Msg 4922, Level 16, State 9, Line 25
ALTER TABLE ALTER COLUMN AddressLine1 failed because one or more objects access this column.
Bu hata, AddressLine1 sütununun, IX_Address_AddressLine1_AddressLine2_City_StateProvinceID_PostalCode gibi bir indeks tarafından kullanıldığını ve dolayısıyla bu sütun üzerinde bir değişiklik yapmanın indeksin bozulmasına yol açabileceği anlamına gelir. Hata mesajına göre, AddressLine1 sütununda bir değişiklik yapılmaya çalışıldığında, bu indeksin varlığı nedeniyle işlem başarısız oluyor.
Bu durumu çözmek için aşağıdaki adımları takip edebilirsiniz:
1. İndeksi Geçici Olarak Kaldırmak
İlk olarak, AddressLine1 sütununu değiştirmeden önce, bu sütunu kullanan indeksi geçici olarak kaldırabilirsiniz. İndeksi kaldırmak için şu SQL komutunu kullanabilirsiniz:
DROP INDEX IX_Address_AddressLine1_AddressLine2_City_StateProvinceID_PostalCode ON Address;
2.Sütunda Değişiklik Yapmak
İndeksi kaldırdıktan sonra, AddressLine1 sütununda yapmak istediğiniz değişikliği gerçekleştirebilirsiniz:
ALTER TABLE [Person].[Address] ALTER COLUMN [AddressLine1] nvarchar(120) collate Turkish_CI_AS
İlgili kolon üzerinde collation değişikliği yapılır.
3. İndeksi Yeniden Oluşturmak
Değişiklik işlemini tamamladıktan sonra, sildiğimiz indeksinizi tekrar oluşturmanız gerekecektir. İndeksi yeniden oluşturmak için şu komutu kullanabilirsiniz:
CREATE INDEX IX_Address_AddressLine1_AddressLine2_City_StateProvinceID_PostalCode ON [Person].[Address] (AddressLine1, AddressLine2, City, StateProvinceID, PostalCode);
Başarılı bir şekilde index yapımızı oluşturduk artık tablomuz yeni collation yapısıyla oluşmuş oldu.
Yukarıdaki scripti çalıştırdıktan sonra aşağıdaki hatayı almış olsaydık. Kullanıcının index üzerinde gerekli izni var mı yok mu kontrol edilmesi gerekmektedir. Ya da index yapımızın hala olup olmadığı kontrol edilmesi gerekmektedir.
Msg 3701, Level 11, State 6, Line 35
Cannot drop the index ‘Address.IX_Address_AddressLine1_AddressLine2_City_StateProvinceID_PostalCode’, because it does not exist or you do not have permission.
Bu makalede tablo altında kolonların collation değişikliği sırasında karşılaşacağı hataya değinmiş olduk. Başka bir makalede görüşmek dileğiyle..
Sabır ve namazla yardım dileyin. Bu, şüphesiz, huşû duyanların dışındakiler için ağır (bir yük)dır. Bakara Suresi, 45. Ayet
1 thought on “MSSQL Server Tablo Collation Değişimi Sırasında Karşılaşılan Hata”