2014-10-01 23 views
6

Alter SortowanieZmiana sortowania SQL Server 2012 bazy danych

muszę zmienić sortowanie jednej z naszych baz danych na określonym serwerze od Latin1_General_CI_AS do SQL_Latin1_General_CP1_CI_AI tak, że pasuje do reszty naszych baz danych.

Alter Collation Dialog - SQL Server 2012 R2

Problem

Jednak gdy próbuję to zrobić, pojawia się następujący błąd:

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

Moja Badania

My googlowania na temat ujawnił szereg artykułów, które Ich wskazują, że muszę wyeksportować wszystkie dane, usunąć bazę danych, odtworzyć ją z prawidłowym sortowaniem, a następnie ponownie zaimportować dane.

Na przykład: Problem with database collation change (SQL Server 2008)

Oczywiście jest to znaczące zadanie, zwłaszcza, że ​​pierwotne-foreign key relacje muszą być zachowane, a nasza baza jest dość duży (ponad dziesięć milionów wierszy danych).

Moje pytanie

Czy istnieje sposób, aby zmienić sortowanie istniejącej bazy danych SQL Server 2012, który nie wymaga ponownego wywozu i importowanie wszystkich danych?

Czy istnieje jakieś narzędzie lub skrypty, które mogą automatyzować ten proces w niezawodny sposób?

Odpowiedz

3

następujące prace dla mnie na SQL Server 2012:

ALTER DATABASE CURRENT COLLATE SQL_Latin1_General_CP1_CI_AI; 

Zaakceptowanych odpowiedź na pytanie powiązanego nie jest do końca poprawne, przynajmniej nie dla SQL Server 2012. Jest napisane:

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...).

Ale byłem w stanie zmienić domyślne sortowanie i mam tabele, które są wypełnione. Na stronie MSDN dla ALTER DATABASE państw w sekcji „Uwagi”, w punkcie „Zmiana Sortowanie bazy danych”:

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.

Tak, chciałbym zaproponować upewniając się, że baza danych jest w trybie pojedynczego użytkownika, a jeśli masz każda z tych czterech elementów, które:

  • upuść
  • zmianę sortowanie
  • a następnie ponownie dodać je

ALE, w tym momencie wszystko, co zostało zmienione, to domyślna układanka bazy danych. Sortowanie dowolnych istniejących kolumn w tabelach użytkowników (tj. Tabelach niesystemowych) będzie nadal zawierać oryginalną układanie.Jeśli chcesz, aby istniejące kolumny kolumn - CHAR, , NCHAR, NVARCHAR i wycofane TEXT i NTEXT - w celu podjęcia nowej sortowania, musisz zmienić każdą z tych kolumn osobno. Jeśli istnieją indeksy zdefiniowane w tych kolumnach, te indeksy będą musiały być najpierw usunięte (wyłączenie nie wystarcza) i utworzone ponownie po ALTER COLUMN (inne zależności, które uniemożliwiłyby ALTER COLUMN, gdyby zostały już upuszczone, aby uzyskać ALTER DATABASE do pracy). Poniższy przykład ilustruje ten problem:

test konfiguracji

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; 

Badanie 1: Zmiany kolumna sortowaniem bez zależności

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; 

W ALTER COLUMN Powyższe zakończył się pomyślnie.

Test 2: Zmiana kolumna Sortowanie z zależnościami

-- 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; 

Tym razem zestawienie ALTER COLUMN otrzymała następujący błąd:

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.

RÓWNIEŻ, Należy pamiętać, że sortowanie niektóre kolumny tekstowe w widokach katalogu systemowego w bazie danych (np. sys.objects, sys.columns, sys.indexes itd.) Zostanie zmieniona na nową. Jeśli twój kod ma powiązania JOIN z jedną z tych kolumn (tj. name), możesz zacząć otrzymywać błędy niezgodności sortowania, dopóki nie zmienisz sortowania na kolumnach łączenia w tabelach użytkowników.

+0

Bardzo dziękuję za zbadaną odpowiedź śrutzky. Spróbuję tego. –

+0

Ta metoda nie działa, jeśli cokolwiek w bazie danych używa którejkolwiek z kolumn, o których mowa. Na przykład, jeśli masz SP, który ma coś takiego jak "WHERE x = y", a xiy są varcharami, nie możesz zmienić sortowania z powodu problemu (2). Zasadniczo działa w przypadku baz danych, których nie obchodzi, i nie udaje się niczego w świecie rzeczywistym. –

+0

@MauryMarkowitz odnośnie "_ jeśli masz SP, który ma coś takiego jak" WHERE x = y ", a x i y są varcharami, nie możesz zmienić sortowania z powodu problemu (2) _": czy próbowałeś tego i stwierdziłeś, że zrobił to nie działa, czy idziesz w oparciu o to, co napisałem w cytowanej przeze mnie dokumentacji? Ponieważ próbowałem go i rzeczywiście działa. Źle odczytujesz punkt # 2. Nie ma nic wspólnego z przechowywanymi procami, a kolumny (N) VARCHAR mają zdefiniowaną układankę. To literały łańcuchowe, parametry i niektóre kolumny w tabelach katalogu systemowego, których dotyczy, ponieważ są one kontrolowane przez domyślne sortowanie db. –

Powiązane problemy