simplify your business RSS 2.0
# Wednesday, February 20, 2008
# Tuesday, February 19, 2008

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]
GO

CREATE DATABASE [demo]
GO

ALTER DATABASE [demo] COLLATE Latin1_General_CI_AS
GO

-- Tabelle test erstellen
USE [demo]
GO

CREATE TABLE [test] ([Nachname] char(20) NOT NULL, [stadt] char(20) NULL)
GO

-- Tabelle mit Testdatensätzen füllen
INSERT [test] VALUES (N'Claussen', N'BGH')
INSERT [test] VALUES (N'Claußen', N'MUC')
GO


-- 1. Versuch einen UNIQUE-Index zu erstellen
CREATE UNIQUE CLUSTERED INDEX [ix_name] ON [dbo].[test] ([Nachname] ASC)
GO


-- Ergebnis
/*
Meldung 1505, Ebene 16, Status 1, Zeile 2
Die 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 ändern
USE [master]
GO
ALTER DATABASE [demo] COLLATE SQL_Latin1_General_CP1_CI_AS
GO


-- Wieder überprüfen
USE [demo]
GO
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=ü
--------- --------- --------- --------- ---------
ok        ok        ok        ok        ok

Die Sortierung SQL_Latin1_General_CP1_CI_AS würde dieses Problem beheben.
*/


-- 2. Versuch einen UNIQUE-Index zu erstellen
CREATE UNIQUE CLUSTERED INDEX [ix_name] ON [dbo].[test] ([Nachname] ASC)
GO


-- Ergebnis
/*
Meldung 1505, Ebene 16, Status 1, Zeile 2
Die 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.
*/


-- 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' ändern
ALTER TABLE [test]
    ALTER COLUMN [Nachname] char(20)
    COLLATE SQL_Latin1_General_CP1_CI_AS
GO


-- Sortierung der Spalte 'Nachname' wieder überprüfen
SELECT [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 erstellen
CREATE UNIQUE CLUSTERED INDEX [ix_name] ON [dbo].[test] ([Nachname] ASC)
GO


-- Ergebnis
/*
Befehl(e) wurde(n) erfolgreich abgeschlossen.
*/

Tuesday, February 19, 2008 8:08:13 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
SQL
# Monday, June 11, 2007

Für den Inhalt des Blogs http://blog.gidanet.net ist verantwortlich:

Georg Gamsjäger
Peter-Tunner-Straße 22
A-8700 Leoben
Österreich
Gerichtsstand: LG Leoben
georg AT gamsjaeger.at

© 2007-2010 Georg Gamsjäger
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.

Imprint as required by Austrian media law.

Monday, June 11, 2007 8:22:18 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Impressum
Archive
<February 2008>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
2425262728291
2345678
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2012
Georg Gamsjäger
Sign In
Statistics
Total Posts: 5
This Year: 0
This Month: 0
This Week: 0
Comments: 0
Themes
Pick a theme:
All Content © 2012, Georg Gamsjäger
DasBlog theme 'Business' created by Christoph De Baene (delarou)