Прежде чем что-то делать, рассмотрите вопросы, заданные @RDFozz в комментарии к вопросу, а именно:
Существуют ли какие - либо другие источники , кроме [Q].[G]
заполнения этой таблицы?
Если ответ не соответствует «Я на 100% уверен, что это единственный источник данных для этой таблицы назначения», то не вносите никаких изменений, независимо от того, могут ли данные, находящиеся в настоящий момент в таблице, быть преобразованы без потеря данных.
Есть ли какие- либо планы / обсуждения, связанные с добавлением дополнительных источников для заполнения этих данных в ближайшем будущем?
И я хотел бы добавить , связанный с этим вопрос: Был ли какой - либо дискуссия вокруг поддержки нескольких языков в источнике тока таблице (то есть [Q].[G]
) путем преобразования его в NVARCHAR
?
Вам нужно будет спросить вокруг, чтобы получить представление об этих возможностях. Я предполагаю, что в настоящее время вам не сказали ничего, что указывало бы в этом направлении, иначе вы бы не задавали этот вопрос, но если предполагается, что эти вопросы - «нет», то их нужно задать и попросить достаточно широкая аудитория, чтобы получить максимально точный / полный ответ.
Основной проблемой здесь является не столько наличие кодовых точек Unicode, которые не могут быть преобразованы (когда-либо), но еще и наличие кодовых точек, которые не все помещаются на одной кодовой странице. Это хорошая вещь в Unicode: он может содержать символы из ВСЕХ кодовых страниц. Если вы конвертируете из NVARCHAR
- где вам не нужно беспокоиться о кодовых страницах - в VARCHAR
, то вам нужно будет убедиться, что в столбце Сортировка назначения используется та же кодовая страница, что и в исходном столбце. Это предполагает наличие либо одного источника, либо нескольких источников, использующих одну и ту же кодовую страницу (хотя не обязательно один и тот же Collation). Но если есть несколько источников с несколькими кодовыми страницами, вы можете столкнуться со следующей проблемой:
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;
Возвращает (второй набор результатов):
ID SourceSlovak SourceHebrew Destination DestinationS DestinationH
1 Ţ ú NULL Ţ ú Ţ ú ? ?
2 NULL ט ת ? ? ט ת ט ת
Как видите, все эти символы можно преобразовать VARCHAR
, но не в одном VARCHAR
столбце.
Используйте следующий запрос, чтобы определить кодовую страницу для каждого столбца исходной таблицы:
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';
ЧТО, КАК ГОВОРИТСЯ....
Вы упомянули, что находитесь на SQL Server 2008 R2, НО, вы не сказали, что такое Edition. Если вы оказались в Enterprise Edition, то забудьте обо всех этих вещах (поскольку вы, вероятно, делаете это просто для экономии места) и включите сжатие данных:
Реализация сжатия Unicode
Если вы используете Standard Edition (а теперь кажется, что вы 😞), то есть еще одна возможность: «Обновление до SQL Server 2016, поскольку SP1 включает в себя возможность для всех выпусков использовать сжатие данных (помните, я уже говорил« долгосрочный »). "😉).
Конечно, теперь, когда только что было разъяснено, что существует только один источник данных, вам не о чем беспокоиться, так как источник не может содержать символы только для Unicode или символы вне своего конкретного кода. стр. В этом случае единственное, о чем вам следует помнить, - это использовать тот же Collation, что и в исходном столбце, или хотя бы тот, который использует ту же кодовую страницу. Это означает, что если исходный столбец использует SQL_Latin1_General_CP1_CI_AS
, то вы можете использовать Latin1_General_100_CI_AS
в месте назначения.
Как только вы узнаете, какой Collation использовать, вы можете:
ALTER TABLE ... ALTER COLUMN ...
быть VARCHAR
(обязательно укажите текущий NULL
/ NOT NULL
параметр), который требует немного времени и много места в журнале транзакций для 87 миллионов строк, ИЛИ
Создайте новые столбцы «ColumnName_tmp» для каждого и медленно заполняйте, UPDATE
делая TOP (1000) ... WHERE new_column IS NULL
. После того, как все строки заполнены (и проверено, что все они скопированы правильно! Вам может понадобиться триггер для обработки UPDATE, если они есть), в явной транзакции используйте sp_rename
для замены имен столбцов «текущих» столбцов на « _Old ", а затем новые столбцы" _tmp ", чтобы просто удалить" _tmp "из имен. Затем вызовите sp_reconfigure
таблицу, чтобы сделать недействительными любые кэшированные планы, ссылающиеся на таблицу, и, если есть какие-либо представления, ссылающиеся на таблицу, вам нужно будет вызвать sp_refreshview
(или что-то в этом роде). После того, как вы проверили приложение и ETL правильно работает с ним, вы можете удалить столбцы.
[G]
ETLed для[P]
. Если[G]
это такvarchar
, и процесс ETL является единственным способом ввода данных[P]
, то, если процесс не добавляет истинные символы Юникода, их не должно быть. Если другие процессы добавляют или изменяют данные[P]
, вам нужно быть более осторожными - просто потому, что все текущие данные могут бытьvarchar
, не означает, чтоnvarchar
данные не могут быть добавлены завтра. Точно так же возможно, что все, что потребляет данные,[P]
нуждается вnvarchar
данных.