Antes de hacer nada, considere las preguntas planteadas por @RDFozz en un comentario sobre la pregunta, a saber:
¿Hay alguna otras fuentes además de [Q].[G]
poblar esta tabla?
Si la respuesta es algo fuera de "Estoy 100% seguro de que esta es la única fuente de datos para esta tabla de destino", no realice ningún cambio, independientemente de si los datos actualmente en la tabla se pueden convertir o no sin pérdida de datos.
¿Hay alguna planes / discusiones relacionadas con la adición de fuentes adicionales para rellenar estos datos en un futuro próximo?
Y yo añadiría una pregunta relacionada: ¿Ha habido alguna discusión en torno a soportar múltiples idiomas en la tabla de fuente de corriente (es decir [Q].[G]
) mediante la conversión es a NVARCHAR
?
Tendrá que preguntar para tener una idea de estas posibilidades. Supongo que actualmente no le han dicho nada que apunte en esta dirección; de lo contrario, no estaría haciendo esta pregunta, pero si se supone que estas preguntas son "no", entonces deben formularse, y se les debe hacer una pregunta. audiencia lo suficientemente amplia como para obtener la respuesta más precisa / completa.
El problema principal aquí no es tanto tener puntos de código Unicode que no se pueden convertir (nunca), sino más bien tener puntos de código que no encajen en una sola página de códigos. Eso es lo bueno de Unicode: puede contener caracteres de TODAS las páginas de códigos. Si realiza la conversión desde NVARCHAR
, donde no necesita preocuparse por las páginas de códigos, a VARCHAR
, deberá asegurarse de que la Clasificación de la columna de destino esté utilizando la misma página de códigos que la columna de origen. Esto supone tener una sola fuente o múltiples fuentes usando la misma página de códigos (aunque no necesariamente la misma Clasificación). Pero si hay varias fuentes con varias páginas de códigos, entonces puede encontrarse con el siguiente problema:
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;
Devoluciones (segundo conjunto de resultados):
ID SourceSlovak SourceHebrew Destination DestinationS DestinationH
1 Ţ ú NULL Ţ ú Ţ ú ? ?
2 NULL ט ת ? ? ט ת ט ת
Como puede ver, todos esos caracteres se pueden convertir VARCHAR
, pero no en la misma VARCHAR
columna.
Use la siguiente consulta para determinar cuál es la página de códigos para cada columna de su tabla de origen:
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';
HABIENDO DICHO ESO....
Usted mencionó estar en SQL Server 2008 R2, PERO, no dijo qué edición. Si se encuentra en Enterprise Edition, olvídese de todas estas cosas de conversión (ya que probablemente lo esté haciendo solo para ahorrar espacio) y habilite la compresión de datos:
Implementación de compresión Unicode
Si usa Standard Edition (y ahora parece que usted es then), entonces hay otra posibilidad muy remota: la actualización a SQL Server 2016 ya que SP1 incluye la capacidad de todas las ediciones para usar Compresión de datos (recuerde, dije "posibilidad remota "😉).
Por supuesto, ahora que se acaba de aclarar que solo hay una fuente para los datos, entonces no tiene nada de qué preocuparse, ya que la fuente no puede contener caracteres exclusivos de Unicode o caracteres fuera de su código específico. página. En ese caso, lo único que debe tener en cuenta es usar la misma Clasificación que la columna de origen, o al menos una que use la misma Página de códigos. Es decir, si la columna de origen está usando SQL_Latin1_General_CP1_CI_AS
, entonces podría usar Latin1_General_100_CI_AS
en el destino.
Una vez que sepa qué colación usar, puede:
ALTER TABLE ... ALTER COLUMN ...
ser VARCHAR
(asegúrese de especificar la corriente NULL
/ NOT NULL
ajuste), lo que requiere un poco de tiempo y una gran cantidad de espacio de registro de transacciones de 87 millones de filas, OR
Cree nuevas columnas "ColumnName_tmp" para cada una y complete lentamente UPDATE
haciendo TOP (1000) ... WHERE new_column IS NULL
. Una vez que todas las filas están pobladas (¡y validado que todas se copiaron correctamente! Es posible que necesite un activador para manejar ACTUALIZACIONES, si las hay), en una transacción explícita, use sp_rename
para intercambiar los nombres de columna de las columnas "actuales" por " _Old "y luego las nuevas columnas" _tmp "para simplemente eliminar el" _tmp "de los nombres. Luego llame sp_reconfigure
a la tabla para invalidar cualquier plan en caché que haga referencia a la tabla, y si hay Vistas que hagan referencia a la tabla, deberá llamar sp_refreshview
(o algo así). Una vez que haya validado la aplicación y ETL esté funcionando correctamente con ella, puede soltar las columnas.
[G]
ETL se transfieren a[P]
. Si[G]
es asívarchar
, y el proceso ETL es la única forma en que entran los datos[P]
, a menos que el proceso agregue verdaderos caracteres Unicode, no debería haber ninguno. Si otros procesos agregan o modifican datos[P]
, debe ser más cuidadoso, solo porque todos los datos actuales pueden servarchar
, no significa que losnvarchar
datos no puedan agregarse mañana. Del mismo modo, es posible que lo que sea que esté consumiendo los datos en datos de[P]
necesidadesnvarchar
.