Bei der Installation einer SQL Server Instanz schlägt der Installationassistent die Sortierung Latin1_General_CI_AS vor. Hat man keine anderen Vorgaben, so übernimmt man diese Einstellung und der SQL Server wird mit dieser Sortierung installiert. Soweit so gut. In den meisten Fällen wir es zu keinen Problemen mit der Sortierung kommen. Es sei den man möchte einen eindeutigen Index für eine Spalte mit einem Zeichendatentyp erstellen. Der SQL Server interpretiert nämlich 'ß' gleich 'ss'. Da kann zum Problem werden, wenn man in die entsprechende Spalten die Werte 'Claußen' und 'Claussen' einfügen will. Beide Werte sind zwei verschieden Nachnamen und somit eindeutig. Abhilfe schafft da, die Änderung der Sortierung für die entsprechende Spalte.
-- ß=ss
-- Datenbank mit Standardsortierung erstellen-- Latin1_General_CI_AS war jene sortierung die bei der Installation der Instanz agegeben wurde
USE [master]GOCREATE DATABASE [demo]GOALTER DATABASE [demo] COLLATE Latin1_General_CI_ASGO
-- Tabelle test erstellenUSE [demo]GOCREATE TABLE [test] ([Nachname] char(20) NOT NULL, [stadt] char(20) NULL)GO-- Tabelle mit Testdatensätzen füllenINSERT [test] VALUES (N'Claussen', N'BGH')INSERT [test] VALUES (N'Claußen', N'MUC')GO
-- 1. Versuch einen UNIQUE-Index zu erstellenCREATE UNIQUE CLUSTERED INDEX [ix_name] ON [dbo].[test] ([Nachname] ASC)GO
-- Ergebnis/*Meldung 1505, Ebene 16, Status 1, Zeile 2Die CREATE UNIQUE INDEX-Anweisung wurde beendet, weil ein doppelter Schlüssel für den Objektnamen 'dbo.test' und den Indexnamen 'ix_name' gefunden wurde. Der doppelte Schlüsselwert ist (Claußen ).Die Anweisung wurde beendet.*/
-- Warum?/*Laut DIN, SQL ANSI-92 und ISO Normen wird 'ß' wie 'ss' behandelt.*/
-- Überprüfung!SELECT CASE WHEN 'ss' = 'ß' THEN 'ss = ß!' ELSE 'ok' END AS 'Test ss=ß', CASE WHEN 'ss' = 's' THEN 'ss = s!' ELSE 'ok' END AS 'Test ss=s', CASE WHEN 'ae' = 'ä' THEN 'ae = ä!' ELSE 'ok' END AS 'Test ae=ä', CASE WHEN 'oe' = 'ö' THEN 'oe = ö!' ELSE 'ok' END AS 'Test oe=ö', CASE WHEN 'ue' = 'ü' THEN 'ue = ü!' ELSE 'ok' END AS 'Test ue=ü'
-- Ergebnis/*Test ss=ß Test ss=s Test ae=ä Test oe=ö Test ue=ü --------- --------- --------- --------- --------- ss = ß! ok ok ok ok*/
-- Sortierung ändernUSE [master]GOALTER DATABASE [demo] COLLATE SQL_Latin1_General_CP1_CI_ASGO
-- Wieder überprüfenUSE [demo]GOSELECT CASE WHEN 'ss' = 'ß' THEN 'ss = ß!' ELSE 'ok' END AS 'Test ss=ß', CASE WHEN 'ss' = 's' THEN 'ss = s!' ELSE 'ok' END AS 'Test ss=s', CASE WHEN 'ae' = 'ä' THEN 'ae = ä!' ELSE 'ok' END AS 'Test ae=ä', CASE WHEN 'oe' = 'ö' THEN 'oe = ö!' ELSE 'ok' END AS 'Test oe=ö', CASE WHEN 'ue' = 'ü' THEN 'ue = ü!' ELSE 'ok' END AS 'Test ue=ü'
-- Ergebnis/*Test ss=ß Test ss=s Test ae=ä Test oe=ö Test ue=ü --------- --------- --------- --------- --------- ok ok ok ok ok
Die Sortierung SQL_Latin1_General_CP1_CI_AS würde dieses Problem beheben.*/
-- 2. Versuch einen UNIQUE-Index zu erstellenCREATE UNIQUE CLUSTERED INDEX [ix_name] ON [dbo].[test] ([Nachname] ASC)GO
-- Was nun?
-- Sortierung der Spalte 'Nachname' überprüfen SELECT [name], [collation_name] FROM sys.columns WHERE [name] = N'Nachname'
-- Ergebnis/*name collation_name-------- --------------------Nachname Latin1_General_CI_AS
Jetzt ist alles klar! Die bestehende Sortierung der Spalte 'Nachname' wurde nicht geändert.*/
-- Sortierung der Spalte 'Nachname' ändernALTER TABLE [test] ALTER COLUMN [Nachname] char(20) COLLATE SQL_Latin1_General_CP1_CI_ASGO
-- Sortierung der Spalte 'Nachname' wieder überprüfenSELECT [name], [collation_name] FROM sys.columns WHERE [name] = N'Nachname'
-- Ergebnis/*name collation_name-------- ----------------------------Nachname SQL_Latin1_General_CP1_CI_AS*/
-- 3. Versuch einen UNIQUE-Index zu erstellenCREATE UNIQUE CLUSTERED INDEX [ix_name] ON [dbo].[test] ([Nachname] ASC)GO
-- Ergebnis/*Befehl(e) wurde(n) erfolgreich abgeschlossen.*/
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.