Yazılım 07 Temmuz 2026 53 okunma

SQL Server'da Collation Değiştirme: Güvenli Adım Adım Rehber

SQL Server'da Collation Değiştirme: Güvenli Adım Adım Rehber

 

SQL Server'da Collation (Karşılaştırma Seti) Sorunu ve Çözümü

Projelerinizde metinsel verileri sıralarken, ararken veya iki tabloyu birleştirirken (JOIN) karakter uyumsuzluğu hataları alıyorsanız, veritabanınızın Collation ayarı projenizin dil kurallarıyla uyuşmuyor demektir.

Genelde SQL Server kurulurken varsayılan olarak bırakılan ayarlar, veritabanı büyüdükçe bu tarz kronik sorunlara yol açar. Çözüm ise veritabanını güvenle Turkish_CI_AS (büyük/küçük harf duyarsız, aksan duyarlı) formatına geçirmektir.

Peki, canlıdaki bir veritabanını patlatmadan ve veri kaybı yaşamadan bu değişiklik en pratik yoldan nasıl yapılır?

Sadece Veritabanı Ayarını Değiştirmek Yetmez

En sık yapılan hata, sadece tek satırlık bir ALTER DATABASE ... COLLATE komutu çalıştırıp her şeyin çözüldüğünü sanmaktır.

Bu komut sadece veritabanının genel ayarını değiştirir; içerideki mevcut tabloların ve sütunların (NVARCHAR, VARCHAR vb.) ayarları eski haliyle kalır. Gerçek bir çözüm için hem veritabanı seviyesini hem de tüm sütunları tek tek güncellemek gerekir.

Güvenli Geçiş İçin Pratik Yol Haritası

İşlemi canlı ortamda yapacaksanız, sıfır riskle ilerlemek için şu basit adımları izleyin:

  • 1. Tam Yedek Alın: Bu tarz yapısal değişikliklerde ilk kural her zaman arkamızı sağlama almaktır. İşleme başlamadan önce veritabanınızın temiz bir yedeğini mutlaka kenara koyun.

  • 2. Canlı Bağlantıları Kesin: Veritabanı üzerinde bu kadar köklü bir değişiklik yaparken dışarıdan sorgu gelmemesi gerekir. Bu yüzden uygulamayı kısa süreliğine bakım moduna alın ve veritabanını SINGLE_USER (Tek Kullanıcı) moduna çekerek dış dünyaya kapatın.

  • 3. Ana Ayarı Güncelleyin: Bağlantıları kestiyseniz, ilk olarak veritabanının genel collation ayarını Turkish_CI_AS olarak güncelleyin.

  • 4. Sütunları Dönüştürün: Veritabanındaki tüm tabloları tarayıp, metin içeren sütunları yeni collation ayarına geçirmeniz gerekir. Eğer sütun üzerinde bir Foreign Key (ilişki) veya yardımcı indeks varsa, SQL Server hata verecektir. Bu yüzden güvenli bir script önce bu ilişkileri ve indeksleri geçici olarak kaldırır, sütunu günceller ve ardından otomatik olarak geri yükler.

  • 5. Dünyayı Yeniden Açın: Tüm sütunlar güncellenikten sonra veritabanını tekrar MULTI_USER moduna alıp uygulamanızı ayağa kaldırabilirsiniz.


    Dikkat Edilmesi Gereken İstisnalar

    • Primary Key ve Formüllü Sütunlar: Eğer metin tabanlı bir sütun aynı zamanda bir Primary Key (Birincil Anahtar) ise veya hesaplanmış (Computed) bir sütunsa, bunları otomatik scriptlerle değiştirmek yerine elle (manuel) müdahale etmek daha güvenlidir.

    • Performans Kontrolü: İşlem sırasında metin sütunlarındaki yardımcı indeksler kaldırılacağı için, geçiş sonrasında performans düşüşü yaşamamak adına bu indeksleri tekrar kontrol edip oluşturmayı unutmayın.


      -- Değiştirilecek collation'ı tanımlayın

      DECLARE @NewCollation NVARCHAR(128) = 'Turkish_CI_AS'; -- Örnek: Turkish_CI_AS (istediğiniz collation'ı buraya yazın)


      -- 1. Veritabanı collation'ını değiştir

      DECLARE @DatabaseName NVARCHAR(128) = DB_NAME(); -- Mevcut veritabanı adını al

      DECLARE @SQL NVARCHAR(MAX);


      SET @SQL = 'ALTER DATABASE [' + @DatabaseName + '] COLLATE ' + @NewCollation;

      EXEC sp_executesql @SQL;


      -- Veritabanını single-user moda al (isteğe bağlı, değişikliklerin uygulanması için)

      SET @SQL = 'ALTER DATABASE [' + @DatabaseName + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE';

      EXEC sp_executesql @SQL;


      SET @SQL = 'ALTER DATABASE [' + @DatabaseName + '] SET MULTI_USER';

      EXEC sp_executesql @SQL;


      -- 2. Tüm tabloların metin sütunlarının collation'larını değiştir

      SET @SQL = '';


      SELECT 

          @SQL = @SQL + 

          'ALTER TABLE [' + s.name + '].[' + t.name + '] ' +

          'ALTER COLUMN [' + c.name + '] ' + 

          TYPE_NAME(c.system_type_id) + 

          CASE 

              WHEN c.max_length = -1 THEN '(MAX)'

              WHEN TYPE_NAME(c.system_type_id) IN ('NVARCHAR', 'NCHAR') THEN '(' + CAST(c.max_length / 2 AS NVARCHAR(10)) + ')'

              WHEN TYPE_NAME(c.system_type_id) IN ('VARCHAR', 'CHAR') THEN '(' + CAST(c.max_length AS NVARCHAR(10)) + ')'

              ELSE ''

          END +

          ' COLLATE ' + @NewCollation + ' ' +

          CASE WHEN c.is_nullable = 1 THEN 'NULL' ELSE 'NOT NULL' END + ';' + CHAR(13)

      FROM 

          sys.tables t

          JOIN sys.schemas s ON t.schema_id = s.schema_id

          JOIN sys.columns c ON t.object_id = c.object_id

          JOIN sys.types tp ON c.system_type_id = tp.system_type_id

      WHERE 

          tp.name IN ('CHAR', 'VARCHAR', 'NCHAR', 'NVARCHAR') -- Metin tabanlı sütunlar

          AND c.collation_name IS NOT NULL

          AND c.collation_name != @NewCollation; -- Zaten hedef collation değilse


      -- Oluşturulan SQL komutlarını çalıştır

      IF @SQL != ''

      BEGIN

          PRINT @SQL; -- Önce komutları görmek için yazdır

          EXEC sp_executesql @SQL; -- Komutları çalıştır

      END

      ELSE

      BEGIN

          PRINT 'Değiştirilecek sütun bulunamadı.';

      END

0 Yorum

Henüz yorum yapılmamış. İlk yorumu siz yapın!

Bir Yorum Bırakın