Inicio > Base de datos > Cambia la secuencia de intercalación de todos los campos en una base de datos

Cambia la secuencia de intercalación de todos los campos en una base de datos

sábado, 13 de abril de 2024 Dejar un comentario Ir a comentarios

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.

Comparte y diviertete:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • BarraPunto
  • Bitacoras.com
  • BlinkList
  • Blogosphere
  • Live
  • Meneame
  • MSN Reporter
  • MySpace
  • RSS
  • Suggest to Techmeme via Twitter
  • Technorati
  • LinkedIn
  • email
  • FriendFeed
  • PDF
  • Reddit
  • Wikio IT
  • Add to favorites
  • blogmarks
Top Footer