Zanim cokolwiek zrobisz, rozważ pytania postawione przez @RDFozz w komentarzu do pytania, a mianowicie:
Czy istnieją jakieś inne źródła oprócz [Q].[G]
wypełniania tej tabeli?
Jeśli odpowiedź jest inna niż „Jestem w 100% pewien, że jest to jedyne źródło danych dla tej docelowej tabeli”, nie wprowadzaj żadnych zmian, niezależnie od tego, czy dane znajdujące się obecnie w tabeli mogą zostać przekonwertowane bez utrata danych.
Czy są jakieś plany / dyskusje związane z dodawaniem dodatkowych źródeł w celu zapełnienia tych danych w najbliższej przyszłości?
I chciałbym dodać powiązane pytanie: Czy była jakakolwiek dyskusja wokół obsługi wielu języków w tabeli źródła prądu (tj [Q].[G]
) poprzez przekształcenie go do NVARCHAR
?
Będziesz musiał zapytać, aby poznać te możliwości. Zakładam, że obecnie nie powiedziano ci niczego, co wskazywałoby w tym kierunku, inaczej nie zadawałbyś tego pytania, ale jeśli założono, że pytania te brzmią „nie”, należy je zadać i zadać wystarczająco szeroka publiczność, aby uzyskać najbardziej dokładną / kompletną odpowiedź.
Głównym problemem tutaj jest nie tyle posiadanie punktów kodowych Unicode, których nie można przekonwertować (kiedykolwiek), ale przede wszystkim posiadanie punktów kodowych, które nie wszystkie pasują do jednej strony kodowej. To miła rzecz w Unicode: może przechowywać znaki ze WSZYSTKICH stron kodowych. Jeśli konwertujesz z NVARCHAR
- gdzie nie musisz się martwić o strony kodowe - na VARCHAR
, to musisz upewnić się, że sortowanie w docelowej kolumnie używa tej samej strony kodowej, co w kolumnie źródłowej. Zakłada się, że ma ono jedno źródło lub wiele źródeł korzystających z tej samej strony kodowej (choć niekoniecznie tego samego sortowania). Ale jeśli istnieje wiele źródeł z wieloma stronami kodowymi, możesz potencjalnie napotkać następujący problem:
DECLARE @Reporting TABLE
(
ID INT IDENTITY(1, 1) PRIMARY KEY,
SourceSlovak VARCHAR(50) COLLATE Slovak_CI_AS,
SourceHebrew VARCHAR(50) COLLATE Hebrew_CI_AS,
Destination NVARCHAR(50) COLLATE Latin1_General_CI_AS,
DestinationS VARCHAR(50) COLLATE Slovak_CI_AS,
DestinationH VARCHAR(50) COLLATE Hebrew_CI_AS
);
INSERT INTO @Reporting ([SourceSlovak]) VALUES (0xDE20FA);
INSERT INTO @Reporting ([SourceHebrew]) VALUES (0xE820FA);
UPDATE @Reporting
SET [Destination] = [SourceSlovak]
WHERE [SourceSlovak] IS NOT NULL;
UPDATE @Reporting
SET [Destination] = [SourceHebrew]
WHERE [SourceHebrew] IS NOT NULL;
SELECT * FROM @Reporting;
UPDATE @Reporting
SET [DestinationS] = [Destination],
[DestinationH] = [Destination]
SELECT * FROM @Reporting;
Zwraca (2. zestaw wyników):
ID SourceSlovak SourceHebrew Destination DestinationS DestinationH
1 Ţ ú NULL Ţ ú Ţ ú ? ?
2 NULL ט ת ? ? ט ת ט ת
Jak widać, wszystkie z tych znaków można przekonwertować VARCHAR
, ale nie w tej samej VARCHAR
kolumnie.
Użyj następującego zapytania, aby ustalić, jaka jest strona kodowa dla każdej kolumny tabeli źródłowej:
SELECT OBJECT_NAME(sc.[object_id]) AS [TableName],
COLLATIONPROPERTY(sc.[collation_name], 'CodePage') AS [CodePage],
sc.*
FROM sys.columns sc
WHERE OBJECT_NAME(sc.[object_id]) = N'source_table_name';
TO POWIEDZIAŁO ....
Wspomniałeś, że jesteś na SQL Server 2008 R2, ALE, nie powiedziałeś, która edycja. JEŚLI akurat korzystasz z wersji Enterprise Edition, zapomnij o tych wszystkich rzeczach związanych z konwersją (ponieważ prawdopodobnie robisz to tylko w celu zaoszczędzenia miejsca) i włącz kompresję danych:
Implementacja kompresji Unicode
Jeśli używasz Wersji standardowej (a teraz wydaje się, że masz 😞), istnieje jeszcze jedna długa szansa: uaktualnienie do SQL Server 2016, ponieważ dodatek SP1 umożliwia wszystkim wersjom korzystanie z kompresji danych (pamiętaj, powiedziałem „dalekie ujęcie” „😉).
Oczywiście teraz, gdy zostało już wyjaśnione, że istnieje tylko jedno źródło danych, nie masz się czym martwić, ponieważ źródło nie może zawierać żadnych znaków tylko Unicode lub znaków poza określonym kodem strona. W takim przypadku jedyną rzeczą, na którą powinieneś zwrócić uwagę, jest użycie tego samego sortowania co kolumny źródłowej lub przynajmniej takiego, który używa tej samej strony kodowej. Oznacza to, że jeśli używasz kolumny źródłowej SQL_Latin1_General_CP1_CI_AS
, możesz użyć jej Latin1_General_100_CI_AS
w miejscu docelowym.
Gdy już wiesz, z którego sortowania korzystać, możesz:
ALTER TABLE ... ALTER COLUMN ...
być VARCHAR
(należy podać bieżące NULL
/ NOT NULL
ustawienie), co wymaga trochę czasu i dużo miejsca w dzienniku transakcji dla 87 milionów wierszy, LUB
Utwórz nowe kolumny „ColumnName_tmp” dla każdej z nich i powoli wypełniaj poprzez UPDATE
wykonanie TOP (1000) ... WHERE new_column IS NULL
. Po wypełnieniu wszystkich wierszy (i sprawdzeniu, czy wszystkie zostały poprawnie skopiowane! Może być potrzebny wyzwalacz do obsługi UPDATE, jeśli istnieją), w jawnej transakcji, użyj sp_rename
do zamiany nazw kolumn „bieżących” kolumn na „ _Old ”, a następnie nowe kolumny„ _tmp ”, aby po prostu usunąć„ _tmp ”z nazw. Następnie wywołaj sp_reconfigure
tabelę, aby unieważnić wszelkie buforowane plany odwołujące się do tabeli, a jeśli są jakieś widoki odwołujące się do tabeli, musisz zadzwonić sp_refreshview
(lub coś w tym rodzaju). Po sprawdzeniu poprawności aplikacji i ETL działa z nią poprawnie, możesz upuścić kolumny.
[G]
są przesyłane do ETL[P]
. Jeśli[G]
takvarchar
, a proces ETL jest jedynym sposobem na wejście danych[P]
, to chyba że proces doda prawdziwe znaki Unicode, nie powinno być żadnych. Jeśli inne procesy dodają lub modyfikują dane[P]
, musisz być bardziej ostrożny - tylko dlatego, że wszystkie obecne danevarchar
nie oznaczają, żenvarchar
nie można dodać danych jutro. Podobnie możliwe jest, że cokolwiek konsumuje dane w[P]
potrzebujenvarchar
danych.