Перш ніж робити щось, будь ласка, врахуйте питання, які поставив @RDFozz в коментарі до цього питання, а саме:
Чи існують якісь - або інші джерела , крім[Q].[G]
заповнення цієї таблиці?
Якщо у відповіді є щось, що не стосується "Я на 100% впевнений, що це єдине джерело даних для цієї таблиці призначення", то не вносити жодних змін, незалежно від того, можна перетворити дані, які зараз перебувають у таблиці, без втрата даних.
Чи є такі плани / обговорення , пов'язане з додаванням додаткових джерел для заповнення цих даних в найближчому майбутньому?
І я би додав відповідне запитання: Чи було обговорення щодо підтримки декількох мов у поточній таблиці джерел (тобто [Q].[G]
) шляхом її перетворення. в NVARCHAR
?
Вам потрібно буде поцікавитися, щоб зрозуміти ці можливості. Я припускаю, що вам зараз не сказали нічого, що вказувало б у цьому напрямку, ви б не ставили цього питання, але якщо ці питання вважатимуться "ні", то їх потрібно задати і запитати достатньо широка аудиторія, щоб отримати найбільш точну / повну відповідь.
Основна проблема тут полягає не стільки в тому, щоб мати кодові точки Unicode, які не можуть конвертувати (ніколи), а тим більше мати кодові точки, які не всі вмістяться на одній кодовій сторінці. Це приємна річ про Unicode: він може містити символи з ВСІХ кодових сторінок. Якщо ви конвертуєте з NVARCHAR
- там, де вам не потрібно турбуватися про кодові сторінки - VARCHAR
, тоді вам потрібно буде переконатися, що для зіставлення стовпця пункту призначення використовується та сама сторінка коду, що і джерельна колонка. Це передбачає наявність одного джерела або декількох джерел з використанням однієї і тієї ж кодової сторінки (не обов'язково однакову Збірку, хоча). Але якщо є кілька джерел з декількома кодовими сторінками, ви потенційно можете зіткнутися з такою проблемою:
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;
Повернення (2-й набір результатів):
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, АЛЕ, ви не сказали, що таке Видання. Якщо ви трапляєте в Enterprise Edition, то забудьте про всі ці матеріали конверсії (оскільки ви, ймовірно, робите це просто для економії місця), і ввімкніть стиснення даних:
Реалізація стиснення Unicode
Якщо ви використовуєте Standard Edition (а тепер здається, що ви 😞), є ще одна можливість looooong-shot: оновлення до 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
для заміни імен стовпців "поточних" стовпців, які мають бути " _Старий ", а потім нові" _tmp "стовпці, щоб просто видалити" _tmp "з імен. Потім зателефонуйте sp_reconfigure
на таблицю, щоб визнати недійсними будь-які кешовані плани з посиланням на таблицю, і якщо є перегляди, на які посилається таблиця, вам потрібно буде зателефонувати sp_refreshview
(або щось подібне). Після того, як ви перевірили додаток і ETL правильно працює з ним, ви можете скидати стовпці.
[G]
ETLed передаються в[P]
. Якщо[G]
єvarchar
, і процес ETL - єдиний спосіб надходження даних[P]
, то, якщо процес додає справжні символи Unicode, їх не повинно бути. Якщо в інші процеси додаються або змінюються дані[P]
, вам потрібно бути більш уважними - лише тому, що всі поточні дані можуть бутиvarchar
не означає, щоnvarchar
дані не можуть бути додані завтра. Так само можливо, що все, що споживає дані,[P]
потребуєnvarchar
даних.