N'Șc ', Latin1_General_CI_AS harmanlamasını kullanarak N'C'nin yinelenen anahtarı olarak kabul edildi


11

Bir NVARCHAR(50)sütun (doğru ya da değil, ama orada) içeren benzersiz bir anahtar içeren bir tablo var. Bu nedenle, ekleme yapmaya çalışırken Șcveya C( eklemenin sırası önemli değil) harmanlama sorunları nedeniyle 2. ekte kırılır. İşte hata:

(Etkilenen 1 satır) Msg 2601, Seviye 14, Durum 1, Satır 16 'dbo.testT' nesnesine benzersiz dizin 'IX_TestT' ile çift anahtar satır eklenemiyor. Yinelenen anahtar değeri (C) 'dir.

İade seçin:

resim açıklamasını buraya girin

Veritabanı varsayılan harmanlama olduğunu Latin1_General_CI_AS. Mevcut yapıyı çok fazla değiştirmeden, nasıl çözüleceğine bakmak için biraz zaman harcadık, ancak çalışmaya başlamanın bir yolunu bulamıyorum. Farklı harmanlama ve kombinasyonlar denedim, her şey başarısız. Karakter genişletmeleri ve benzerleri hakkında ( burada ve burada ) okuyun , hala sıkışmış. İşte sorunu çoğaltmak, değiştirmek ve bunu çözmeye yardımcı olabilecek bir şey tavsiye çekinmeyin için kullandığım örnek bir kod.

CREATE TABLE testT (
    [Default_Collation]     [NVARCHAR] (50) COLLATE DATABASE_DEFAULT,
    [Latin1_General_CI_AS]  [NVARCHAR] (50) COLLATE Latin1_General_CI_AS,
    [Latin1_General_CI_AI]  [NVARCHAR] (50) COLLATE Latin1_General_CI_AI,
    [SQL_Collation]         [NVARCHAR] (50) COLLATE SQL_Latin1_General_CP1_CI_AS);
CREATE UNIQUE CLUSTERED INDEX [IX_TestT] ON [dbo].[testT] ([Default_Collation])
ON [PRIMARY]
GO

INSERT INTO testT
SELECT  N'Șc',  --COLLATE Latin1_General_CI_AS
        N'Șc',  --COLLATE Latin1_General_CI_AS
        N'Șc',  --COLLATE Latin1_General_CI_AS
        N'Șc'   --COLLATE Latin1_General_CI_AS

INSERT INTO testT
SELECT  N'C'    --COLLATE Latin1_General_CI_AS 
        ,N'C'   --COLLATE Latin1_General_CI_AS
        ,N'C'   --COLLATE Latin1_General_CI_AS
        ,N'C'   --COLLATE SQL_Latin1_General_CP1_CI_AS

SELECT * FROM testT;

DROP TABLE testT;

Yanıtlar:


10

Sorun olduğunu eski SQL Server Harmanlamalar (yani adları ile başlayan olanlar SQL_) ve Windows Harmanlamalar ilk iki sürümü ( 80SQL Server 2000 ile birlikte gelen ve adına bir sürüm numarası yok serisi ve 90serinin hangi SQL Server 2005 ile geldi) çok fazla karakter için sıralama ağırlıkları eksik. Bu çoğunlukla 100SQL Server 2008 ile birlikte gelen Harmanlama serisinden başlayarak düzeltildi .

Aşağıdaki örneklerde de görebileceğiniz gibi, Șikili olmayan, sürüm 80 veya 90 Harmanlama (ve SQL Server Harmanlama) kullanırken karakter her ikisi de aynı sıralama ağırlığına sahip olduğu için boş bir dize ile eşleşir: 0. Hiçbir şey. Nada. Bu N'Șc', N'C'(100 öncesi seri Harmanlamalarını kullanarak) N'c'ile karşılaştırırken gerçekten N'C'(test # 1) ile karşılaştırdığınız anlamına gelir :

SELECT 1 WHERE N'Șc' = N'C' COLLATE Latin1_General_CS_AS;
-- no result (due to "c" and "C" being different case)

SELECT 2 WHERE N'Ș' = N'' COLLATE SQL_Latin1_General_CP1_CI_AS;
SELECT 3 WHERE N'Ș' = N'' COLLATE Latin1_General_CI_AS;

SELECT 4 WHERE N'Ș' = N'' COLLATE Latin1_General_BIN2;
-- no result (due to "Ș" still being a code point and empty string has no code points)

SELECT 5 WHERE N'Ș' = N'' COLLATE Latin1_General_100_CI_AS;
-- no result (due to "Ș" finally having a sort weight in 100 series Collations)

SELECT 6 WHERE N'Ș' = N'' COLLATE Chinese_PRC_CI_AI;
SELECT 7 WHERE N'Ș' = N'' COLLATE Chinese_PRC_90_CI_AI;

SELECT 8 WHERE N'Ș' = N'' COLLATE Indic_General_90_CI_AI;
SELECT 9 WHERE N'Ș' = N'' COLLATE Indic_General_100_CI_AI;
-- no result (due to "Ș" finally having a sort weight in 100 series Collations)

Bu nedenle, maalesef PK'yi bırakmanız, 100 düzeyli bir Harmanlama (örneğin Latin1_General_100_CI_AS_SC) için sütunu değiştirmeniz ve ardından PK'yi yeniden oluşturmanız gerekir. Bu fark akımı Harmanlama dan Harmanlama önerdiği notu hem Lütfen 100 ve_SC düzgün tamamlayıcı karakterleri işlemesine olanak tanır sonunda.

Bu mu değil size gerektiği anlamına:

  1. diğer tabloların Harmanlamalarını değiştirin (PK'da aynı kurulumları yoksa NVARCHAR)
  2. Veritabanının varsayılan Harmanlamasını değiştirin. DB'nin harmanlama değişmiyor ile ana konu yapıyor arasında bir davranış farkı olacak olmasıdır table.column = N'Ș've @variable = N'Ș'değişkenler ve dize hazır veritabanı'nın varsayılan Harmanlama kullandığından.

Bu davranışla ilgili daha fazla örnek için lütfen aşağıdaki blog yayınımın "Tamamlayıcı Karakterler" bölümüne bakın:

Uni-Code: T-SQL Tanımlayıcıları için Geçerli Geçerli Karakterlerin Listesinin Araştırılması, Bölüm 3/2 (Sınırlı Tanımlayıcılar)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.