Прежде чем что-то делать, рассмотрите вопросы, заданные @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данных.