Das Ändern der Sortierung einer Datenbank wirkt sich nicht auf vorhandene Spalten aus. Dies betrifft neue Nicht-XML-Zeichenfolgenspalten, die keine COLLATE
Klausel (einschließlich Tabellenvariablen), Zeichenfolgenliterale und Variablenwerte angeben (keine Auflösung von Variablennamen, die durch die Sortierung auf Instanzebene bestimmt wird). Dies bedeutet, dass Folgendes betroffen ist:
IF (@Variable = 'string')
BEGIN
...
END;
Diese Änderung wirkt sich auch auf Metadaten auf Datenbankebene aus, z. B. Namen von Schemas, Objekten, Spalten, Indizes usw. Dies bedeutet, dass die folgenden zwei Szenarien betroffen sind:
SELECT ...
FROM sys.indexes si
WHERE si.[name] = N'somename'; -- real name = SomeName
und:
SELECT ...
FROM dbo.sometable st -- real name = SomeTable
In beiden Beispielen würden sie in einer Sortierung ohne Berücksichtigung der Groß- und Kleinschreibung arbeiten, in einer Sortierung ohne Berücksichtigung der Groß- und Kleinschreibung jedoch nichts oder Fehler zurückgeben.
Schließlich, wie @JonathanFite war so freundlich, mich daran zu erinnern, die Änderung der DB Sortierungs kann Abfragen auswirken temporäre Tabellen beteiligt sind . Die Standardkollatierung für Zeichenfolgenspalten in temporären Tabellen (keine Tabellenvariablen) ist die Standardkollatierung für [tempdb]
(die [model]
mit der Standardeinstellung der Instanz identisch sein sollte, es sei denn, jemand hat sie wiederhergestellt[model]
von einem Server mit einer anderen Standardkollatierung), nicht der Kollatierung der lokalen Datenbank. Das heißt, obwohl die temporären Tabellen jedes Mal erstellt werden und Sie daher erwarten können, dass sie sich mit der neuen Sortierung wie "neu erstellte Tabellen" verhalten, verhalten sie sich tatsächlich wie "vorhandene Tabellen" und verhalten sich weiterhin wie zuvor die Sortieränderung. Wenn Sie Zeichenfolgenspalten in temporären Tabellen benötigen, um die neue Kollatierung zu verwenden, müssen Sie deren Kollatierung COLLATE DATABASE_DEFAULT
in den CREATE TABLE
Anweisungen explizit festlegen .
Daher müssen Sie wirklich viele Tests durchführen!
Wenn Sie vorhandene Spalten ändern möchten, müssen Sie vorhandene Einschränkungen löschen, eine ausgeben ALTER TABLE ... ALTER COLUMN
und dann die Einschränkungen neu erstellen. Sie müssen auch Indizes neu erstellen, die eine Spalte verwenden, deren Sortierung geändert wurde, da die Sortierreihenfolge möglicherweise unterschiedlich ist.
Es ist auch am besten, keine Kollatierungen zu verwenden, die mit beginnen SQL_
. Verwenden Sie stattdessen Latin1_General_100_CS_AS
. Die Kollatierungen, die mit beginnen, SQL_
sind seit der Veröffentlichung von SQL Server 2000 veraltet (auch wenn sie nicht offiziell veraltet sind) . Ihr Umgang mit VARCHAR
/ 8-Bit-Daten ist veraltet und entspricht nicht dem neueren Verhalten. Aus Gründen der Abwärtskompatibilität war die Standardkollatierung für Installationen in US-Englisch leider die SQL_Latin1
Kollatierung, wie auf der Seite MSDN für SQL Server-Kollatierungen verwenden angegeben :
Aus Gründen der Abwärtskompatibilität lautet die Standardkollatierung in englischer Sprache (US) SQL_Latin1_General *.
Dies wird auch im Standardkollatierungsdiagramm auf der Seite Kollatierungseinstellungen im Setup- MSDN vermerkt ( drücken Sie Strg-F und fügen Sie es ein sql_latin
). Ich glaube, diese Standardeinstellung wurde ab SQL Server 2014 in eine Windows-Sortierung geändert, aber die Dokumentation verweist auch für das SQL Server 2016-Setup weiterhin auf die 2008 R2-Setup-Seite für Kollatierungen.
Unten finden Sie ein Skript, um einige der Verhaltensunterschiede beim Ändern der Sortierung einer Datenbank anzuzeigen:
USE [master];
GO
IF (DB_ID(N'ChangeDatabaseCollationTest') IS NULL)
BEGIN
CREATE DATABASE [ChangeDatabaseCollationTest] COLLATE Latin1_General_100_CI_AS;
END;
GO
USE [ChangeDatabaseCollationTest];
GO
-- Current DB Collation: Latin1_General_100_CI_AS
EXEC sp_help 'sys.objects';
-- Collation for [name] = Latin1_General_100_CI_AS
IF ('A' = 'a')
BEGIN
SELECT 'Case INsensitive comparison works.';
END;
ELSE
BEGIN
SELECT 'Case INsensitive comparison did NOT work.';
END;
-- Case INsensitive comparison works.
CREATE TABLE dbo.CaseTest_a (ID INT); -- success
SELECT * FROM dbo.CaseTest_A; -- success
CREATE TABLE dbo.CaseTest_A (ID INT); -- error:
-- Msg 2714, Level 16, State 6, Line 5
-- There is already an object named 'CaseTest_A' in the database.
ALTER DATABASE [ChangeCollationTest] COLLATE Latin1_General_100_CS_AS; -- success
IF ('A' = 'a')
BEGIN
SELECT 'Case INsensitive comparison works.';
END;
ELSE
BEGIN
SELECT 'Case INsensitive comparison did NOT work.';
END;
-- Case INsensitive comparison did NOT work.
SELECT * FROM dbo.CaseTest_A; -- error:
-- Msg 208, Level 16, State 1, Line 56
-- Invalid object name 'dbo.CaseTest_A'.
CREATE TABLE dbo.CaseTest_A (ID INT); -- success
EXEC sp_help 'sys.objects';
-- Collation for [name] = Latin1_General_100_CS_AS
ALTER DATABASE [ChangeCollationTest] COLLATE Latin1_General_100_CI_AS; -- error:
-- Msg 1505, Level 16, State 1, Line 23
-- The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for
-- the object name 'dbo.sysschobjs' and the index name 'nc1'. The duplicate key
-- value is (0, 1, CaseTest_A).
-- Msg 5072, Level 16, State 1, Line 23
-- ALTER DATABASE failed. The default collation of database 'ChangeCollationTest'
-- cannot be set to Latin1_General_100_CI_AS.
Zunächst wird nichts passieren. Die Sortierung der Datenbank ist nur eine Standardeinstellung, die beim Erstellen in neue Spalten kopiert wird. Einmal erstellt, behalten sie diese Sortierung bei. Siehe sys.columns.collation_name .
Wenn Sie die Datenbankkollatierung ändern und dann neue Spalten erstellen, haben diese Spalten die neue Kollatierung. Dies kann eine Kollatierung sein, die mit den bereits vorhandenen Spalten kompatibel ist.
Wenn Sie eine Sortierung mit Groß- und Kleinschreibung für die Datenbank übernehmen, wird bei SQL zwischen Groß- und Kleinschreibung unterschieden. Objektnamen müssen genau mit den deklarierten Zeichenfolgen übereinstimmen. Dies kann die Anwendung beschädigen.
Ich habe diesen Prozess vor vielen Jahren durchlaufen. Ich scheine mich zu erinnern, dass ich jede Zeichenspalte in der Datenbank explizit auf die neue Sortierung ändern und dann die Daten für die Kollatierungsänderung aktualisieren musste (Aktualisierungstabelle set charcol1 = charcol1, charcol2 = charcol2 ...; Nicht-Zeichenfolge) Spalten wurden nicht benötigt). Dies war vor vielen Versionen, daher können die Dinge jetzt einfacher sein. Würde ich es je nach Größe und Komplexität erneut tun, wäre ich versucht, alle Objekte zu skripten, die Datei zu bearbeiten, um Kollatierungen zu entfernen, dann eine neue Datenbank von Grund auf neu zu erstellen und die Daten und Berechtigungen usw. zu übertragen.
Viel Glück.
quelle
UPDATE
Aussage nicht machen müssen, da das wirklich nichts an der Tabelle selbst ändern würde, da die Kollatierung nur Metadaten sind. Dies würde sich nur auswirken, wenn die DatenVARCHAR
/CHAR
und die neue Sortierung einer anderen Codepage zugeordnet wären . Ich vermute, dasUPDATE
war ein umständlicher Weg, um die Indizes neu zu erstellen.