Cambia la secuencia de intercalación de todos los campos en una base de datos
Cuando tienes servidores SQL Server con la configuración de intercalación diferente, tus bases de datos pueden ser diferentes en estos servidores, cuando no se especifique la intercalación de manera explícita. Para solucionar esto, es necesario modificar todos los campos con una secuencia de intercalación diferente. Tienes que hacer esto manualmente, mediante la apertura de cada tabla en el Administrador corporativo del SQL, revisar cada columna, y cambiar la secuencia de intercalación. Es innecesario decir que esta es una tarea tediosa.
El mensaje de error
Voy a describir lo que sucede si no utilizas la misma secuencia de intercalación en una base de datos. Cuando se comparan dos campos con una configuración de intercalación diferente (SELECT * FROM MyTable WHERE FieldA = FieldB), SQL Server le dará un error similar al siguiente:
Mens 468, Nivel 16, Estado 9, Procedimiento itu_detalle, Línea 43
Cannot resolve the collation conflict between «Modern_Spanish_CI_AS» and «SQL_Latin1_General_CP1_CI_AS» in the equal to operation.
Recibirás este error sólo en tiempo de ejecución, por lo que no se puede ver hasta que se ejecuten los procedimientos almacenados, tareas DTS, o consultas SELECT. En el peor de los casos, no te enteraras, pero si los usuarios. Si este es el caso, entonces ¡tienes un problema grande!
La solución
He escrito un poco de código T-SQL para generar las sentencias ALTER TABLE. Cada sentencia fija la secuencia de intercalación con el mismo nombre. Después de ejecutar esta instrucción de selección, es necesario revisar el resultado, y ejecutarlo en el Analizador de consultas.
Aquí está el código T-SQL:
SELECT 'Alter Table [' + table_catalog + '].[' + table_schema + '].[' + table_name + '] alter column [' + column_name + '] ' + CASE data_type WHEN 'char' THEN 'char' WHEN 'varchar' THEN 'varchar' WHEN 'text' THEN 'text' END + CASE WHEN data_type <>'text' THEN '(' + CONVERT(VARCHAR,character_maximum_length) + ')' ELSE '' END + ' collate SQL_Latin1_General_CP1_CI_AS ' + CASE WHEN is_nullable='YES' THEN 'NULL ' ELSE 'NOT NULL' END FROM INFORMATION_SCHEMA.COLUMNS WHERE collation_name <> 'SQL_Latin1_General_CP1_CI_AS' AND data_type IN ('char' , 'varchar', 'text') AND table_name IN (SELECT table_name FROM INFORMATION_SCHEMA.tables WHERE table_type = 'BASE TABLE' )
Aquí otro script para las versiones mas recientes de Sql Server:
SELECT 'alter table [' + s.name + '].[' + t.name + '] alter column [' + c.name + '] ' + ty.name + CASE WHEN ty.name NOT IN ('text', 'sysname') THEN '(' + CASE WHEN c.max_length > 0 THEN CASE WHEN ty.name NOT IN ('nchar', 'nvarchar') THEN CONVERT(VARCHAR, c.max_length) ELSE CONVERT(VARCHAR, c.max_length/2) END ELSE 'max' END + ')' ELSE '' END + ' collate SQL_Latin1_General_CP1_CI_AS ' + CASE WHEN c.is_nullable = 0 THEN 'NOT ' ELSE '' END + 'NULL' FROM (sys.columns c INNER JOIN sys.types ty ON c.system_type_id = ty.system_type_id) INNER JOIN (sys.objects t INNER JOIN sys.schemas s ON t.schema_id = s.schema_id) ON c.object_id = t.object_id WHERE t.type ='U' AND c.collation_name IS NOT NULL AND ty.name <> 'sysname' ORDER BY s.name, t.name, c.column_id
Notas
Antes de utilizar este código, leer las siguientes notas:
- Ejecutar este script en una base de datos específica (primero ejecuta USE [nombre de la base de datos] desde Analizador de consultas).
- Cambia «SQL_Latin1_General_CP1_CI_AS» con el nombre de intercalación deseada.
- Ajuste el tipo de salida del Analizador de consultas a texto, de esta manera podrás copiar el resultado.
- Primero, prueba la salida de este script en una copia de tu base de datos.
- Haz siempre una copia de seguridad de su base de datos, antes de utilizar ALTER TABLE.
Entradas relacionadas