2014-10-01 11 views
6

Alter SortierungsÄndern der Sortierung einer SQL Server 2012 Datenbank

Ich brauche die Sortierung von einem unserer Datenbanken auf einem bestimmten Server von Latin1_General_CI_AS zu SQL_Latin1_General_CP1_CI_AI so zu ändern, dass es passt den Rest unserer Datenbanken.

Alter Collation Dialog - SQL Server 2012 R2

Das Problem

Allerdings, wenn ich versuchen, dies zu tun, bekomme ich folgende Fehlermeldung:

ALTER DATABASE failed. The default collation of database 'XxxxxXxxxxx' cannot be set to SQL_Latin1_General_CP1_CI_AI. (Microsoft SQL Server, Error: 5075)

Meine Forschung

Mein googeln auf Das Thema hat eine Anzahl von Artikeln offenbart, wh Ich gebe an, dass ich alle Daten exportieren muss, die Datenbank löschen, sie mit der richtigen Sortierung neu erstellen und dann die Daten erneut importieren muss.

Zum Beispiel: Problem with database collation change (SQL Server 2008)

Offensichtlich ist dies eine wichtige Aufgabe, vor allem, da Primärfremdschlüsselbeziehungen erhalten werden müssen, und unsere Datenbank ist recht groß (mehr als zehn Millionen Datenzeilen).

Meine Frage

Gibt es eine Möglichkeit die Sortierung einer vorhandenen SQL Server 2012-Datenbank zu ändern, die nicht den Export benötigt und erneut importieren alle Daten?

Oder gibt es ein Tool oder Skript (e), das diesen Prozess auf zuverlässige Weise automatisieren kann?

Antwort

3

Die folgenden Werke für mich auf SQL Server 2012:

ALTER DATABASE CURRENT COLLATE SQL_Latin1_General_CP1_CI_AI; 

Die akzeptierte Antwort in der verknüpften Frage ist nicht ganz korrekt, zumindest nicht für SQL Server 2012. Dort heißt es:

Ahh, this is one of the worst problems in SQL Server: you cannot change the collation once an object is created (this is true both for tables and databases...).

Aber ich konnte nur die Standardsortierung ändern und ich habe Tabellen, die ausgefüllt werden. Die MSDN-Seite für ALTER DATABASE Zustände im Abschnitt „Hinweise“, unter „Ändern des Datenbankkollatierung“:

Before you apply a different collation to a database, make sure that the following conditions are in place:

  1. You are the only one currently using the database.

  2. No schema-bound object depends on the collation of the database.

    If the following objects, which depend on the database collation, exist in the database, the ALTER DATABASE database_name COLLATE statement will fail. SQL Server will return an error message for each object blocking the ALTER action:

    • User-defined functions and views created with SCHEMABINDING.

    • Computed columns.

    • CHECK constraints.

    • Table-valued functions that return tables with character columns with collations inherited from the default database collation.

Also, ich würde dafür sorgen, lassen vermuten, dass sich die Datenbank im Single-User-Modus ist, und dass, wenn Sie jede dieser vier Elemente, die Sie:

  • sie
  • Änderung der Vergleich
  • fallen und dann wieder hinzufügen sie

ABER, An diesem Punkt wurde nur die Standardsortierung der Datenbank geändert. Die Sortierung aller vorhandenen Spalten in Benutzertabellen (d. H. Nicht-Systemtabellen) hat immer noch die ursprüngliche Sortierung.Wenn Sie die vorhandenen Zeichenfolgespalten - CHAR, VARCHAR, NCHAR, NVARCHAR und die veralteten Versionen TEXT und NTEXT - für die neue Sortierung übernehmen möchten, müssen Sie jede dieser Spalten einzeln ändern. Und wenn für diese Spalten Indizes definiert sind, müssen diese Indizes zuerst gelöscht werden (das Deaktivieren ist nicht genug) und nach dem ALTER COLUMN erneut erstellt (andere Abhängigkeiten, die verhindern würden, dass die ALTER COLUMN bereits gelöscht wurde, um zu erhalten die ALTER DATABASE zu arbeiten). Das folgende Beispiel zeigt dieses Verhalten:

Test Setup

USE [tempdb]; 
SET NOCOUNT ON; 

CREATE TABLE dbo.ChangeCollationParent 
(
    [ChangeCollationParentID] INT NOT NULL IDENTITY(1, 1) 
        CONSTRAINT [PK_ChangeCollationParent] PRIMARY KEY, 
    ExtendedASCIIString VARCHAR(50) COLLATE Latin1_General_CI_AS NULL, 
    UnicodeString NVARCHAR(50) COLLATE Latin1_General_CI_AS NULL 
); 

CREATE TABLE dbo.ChangeCollationChild 
(
    [ChangeCollationChildID] INT NOT NULL IDENTITY(1, 1) 
        CONSTRAINT [PK_ChangeCollationChild] PRIMARY KEY, 
    [ChangeCollationParentID] INT NULL 
        CONSTRAINT [FK_ChangeCollationChild_ChangeCollationParent] FOREIGN KEY 
         REFERENCES dbo.ChangeCollationParent([ChangeCollationParentID]), 
    ExtendedASCIIString VARCHAR(50) COLLATE Latin1_General_CI_AS NULL, 
    UnicodeString NVARCHAR(50) COLLATE Latin1_General_CI_AS NULL 
); 

INSERT INTO dbo.ChangeCollationParent ([ExtendedASCIIString], [UnicodeString]) 
VALUES ('test1' + CHAR(200), N'test1' + NCHAR(200)); 
INSERT INTO dbo.ChangeCollationParent ([ExtendedASCIIString], [UnicodeString]) 
VALUES ('test2' + CHAR(170), N'test2' + NCHAR(170)); 


INSERT INTO dbo.ChangeCollationChild 
     ([ChangeCollationParentID], [ExtendedASCIIString], [UnicodeString]) 
VALUES (1, 'testA ' + CHAR(200), N'testA ' + NCHAR(200)); 
INSERT INTO dbo.ChangeCollationChild 
     ([ChangeCollationParentID], [ExtendedASCIIString], [UnicodeString]) 
VALUES (1, 'testB ' + CHAR(170), N'testB ' + NCHAR(170)); 

SELECT * FROM dbo.ChangeCollationParent; 
SELECT * FROM dbo.ChangeCollationChild; 

Test 1: Ändern Spalte Sortierungs ohne Abhängigkeiten

ALTER TABLE dbo.ChangeCollationParent 
    ALTER COLUMN [ExtendedASCIIString] VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI NULL; 
ALTER TABLE dbo.ChangeCollationParent 
    ALTER COLUMN [UnicodeString] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI NULL; 

ALTER TABLE dbo.ChangeCollationChild 
    ALTER COLUMN [ExtendedASCIIString] VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI NULL; 
ALTER TABLE dbo.ChangeCollationChild 
    ALTER COLUMN [UnicodeString] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI NULL; 

SELECT * FROM dbo.ChangeCollationParent; 
SELECT * FROM dbo.ChangeCollationChild; 

Die ALTER COLUMN Aussagen über erfolgreich abgeschlossen.

Test 2: Ändern Spalte Sortierungs mit Abhängigkeiten

-- First, create an index: 
CREATE NONCLUSTERED INDEX [IX_ChangeCollationParent_ExtendedASCIIString] 
    ON dbo.ChangeCollationParent ([ExtendedASCIIString] ASC); 

-- Next, change the Collation back to the original setting: 
ALTER TABLE dbo.ChangeCollationParent 
    ALTER COLUMN [ExtendedASCIIString] VARCHAR(50) COLLATE Latin1_General_CI_AS NULL; 

Diese Zeit, die ALTER COLUMN Anweisung erhalten den folgenden Fehler:

Msg 5074, Level 16, State 1, Line 60
The index 'IX_ChangeCollationParent_ExtendedASCIIString' is dependent on column 'ExtendedASCIIString'.
Msg 4922, Level 16, State 9, Line 60
ALTER TABLE ALTER COLUMN ExtendedASCIIString failed because one or more objects access this column.

AUCH Sie bitte, dass die Sortierungs bewusst sein, einige Zeichenfolgenspalten in Datenbanksystem-Katalogansichten (z. B. sys.objects, sys.columns, sys.indexes usw.) wird zur neuen Sortierung gewechselt. Wenn Ihr Code JOINs zu einer dieser Zeichenfolgespalten hat (z. B. name), erhalten Sie möglicherweise Fehler bei der Sortierung, bis Sie die Sortierung für die Join-Spalten in den Benutzertabellen ändern.

+0

Vielen Dank für die recherchierte Antwort srutzky. Ich werde es versuchen. –

+0

Diese Methode funktioniert nicht, wenn irgendetwas in der Datenbank eine der fraglichen Spalten verwendet. Wenn Sie beispielsweise einen SP mit "WHERE x = y" haben und x und y Varchars sind, können Sie die Sortierung aufgrund von Problem (2) nicht ändern. Also im Grunde funktioniert es für Datenbanken, die Sie eigentlich nicht interessieren, und versagt für irgendetwas real-world. –

+0

@MauryMarkowitz in Bezug auf "_wenn Sie einen SP haben, der etwas wie" WHERE x = y "hat und x und y Varchars sind, können Sie die Sortierung nicht ändern, wegen des Problems (2) _": Haben Sie dies versucht und gefunden funktioniert nicht, oder gehst du basierend auf was die Dokumentation, die ich zitiert, sagt? Weil ich es versucht habe und es tatsächlich funktioniert. Sie verstehen Punkt 2 falsch. Es hat nichts mit gespeicherten Prozeduren zu tun, und (N) VARCHAR-Spalten haben eine definierte Sortierung. String-Literale, -Parameter und einige Spalten in Systemkatalogtabellen sind betroffen, da sie von der Standard-Sortierfolge der Datenbank gesteuert werden. –