Sunucumun varsayılan harmanlaması şu sorgu tarafından belirlendiği şekliyle Latin1_General_CI_AS:
SELECT SERVERPROPERTY('Collation') AS Collation;
Bu harmanlama ile yüklemi kullanarak dizelerdeki rakam olmayan karakterlerle eşleşebildiğimi keşfetmekten şaşırdım LIKE '[0-9]'
.
Neden varsayılan harmanlamada bu oluyor? Bunun yararlı olacağı bir durum düşünemiyorum. İkili bir harmanlama kullanarak davranışa çalışabileceğimi biliyorum, ancak varsayılan harmanlamayı uygulamak için garip bir yol gibi görünüyor.
Rakamları filtrelemek rakam içermeyen karakterler oluşturur
Tüm olası tek baytlık karakter değerlerini içeren bir sütun oluşturarak ve değerleri basamak eşleme yüklemiyle filtreleyerek davranışı gösterebilirim.
Aşağıdaki ifade, geçerli kod sayfasındaki her kod noktası için bir tane olmak üzere 256 satırlı geçici bir tablo oluşturur:
WITH P0(_) AS (SELECT 0 UNION ALL SELECT 0),
P1(_) AS (SELECT 0 FROM P0 AS L CROSS JOIN P0 AS R),
P2(_) AS (SELECT 0 FROM P1 AS L CROSS JOIN P1 AS R),
P3(_) AS (SELECT 0 FROM P2 AS L CROSS JOIN P2 AS R),
Tally(Number) AS (
SELECT -1 + ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM P3
)
SELECT Number AS CodePoint, CHAR(Number) AS Symbol
INTO #CodePage
FROM Tally
WHERE Number >= 0 AND Number <= 255;
Her satır, kod noktasının tamsayı değerini ve kod noktasının karakter değerini içerir. Karakter değerlerinin tümü görüntülenebilir değildir - bazı kod noktaları kesinlikle kontrol karakteridir. İşte çıktısının seçici bir örneği SELECT CodePoint, Symbol FROM #CodePage
:
0
1
2
...
32
33 !
34 "
35 #
...
48 0
49 1
50 2
...
65 A
66 B
67 C
...
253 ý
254 þ
255 ÿ
LIKE yüklemini kullanarak ve '0' ila '9' karakter aralığını belirterek rakam karakterleri bulmak için Sembol sütununda filtre yapabilmeyi bekleyebilirim:
SELECT CodePoint, Symbol
FROM #CodePage
WHERE Symbol LIKE '[0-9]';
Şaşırtıcı bir çıktı üretir:
CodePoint Symbol
48 0
49 1
50 2
51 3
52 4
53 5
54 6
55 7
56 8
57 9
178 ²
179 ³
185 ¹
188 ¼
189 ½
190 ¾
48'den 57'ye kadar kod noktaları kümesi beklediğimdir. Beni şaşırtan şey, üst simgeler ve kesirler için sembollerin de sonuç kümesine dahil edilmesidir!
Üsleri ve kesirleri sayı olarak düşünmek için matematiksel bir neden olabilir, ancak onlara rakam demek yanlış görünüyor.
İkili harmanlamayı geçici çözüm olarak kullanma
Beklediğim sonucu elde etmek için, karşılık gelen ikili harmanlama Latin1_General_BIN zorlayabilir anlıyorum:
SELECT CodePoint, Symbol
FROM #CodePage
WHERE Symbol LIKE '[0-9]' COLLATE Latin1_General_BIN;
Sonuç kümesi yalnızca 48 ile 57 arasındaki kod noktalarını içerir:
CodePoint Symbol
48 0
49 1
50 2
51 3
52 4
53 5
54 6
55 7
56 8
57 9