Resolver conflictos de intercalación en SQL Server
Diagnostica intercalaciones de columnas, bases y tempdb sin cambiar coincidencias, introducir claves duplicadas ni perjudicar el acceso mediante índices.
Una unión puede funcionar en una instancia SQL Server y fallar después de restaurar la base en otra porque los textos comparados tienen intercalaciones diferentes. Añadir COLLATE hasta que desaparece el error puede recuperar la ejecución y, a la vez, cambiar qué filas coinciden. Mayúsculas, acentos y ordenación forman parte del contrato de los datos.
Primero aclara el significado del identificador. ¿Los códigos abc y ABC pertenecen al mismo cliente? ¿Una búsqueda de nombres debe ignorar acentos sin modificar la escritura presentada? La solución técnica depende de estas decisiones.
Inspeccionar los niveles implicados
La configuración del servidor, la base y cada columna no es intercambiable.
SELECT SERVERPROPERTY('Collation') AS ServerCollation,
DATABASEPROPERTYEX(DB_NAME(), 'Collation') AS DatabaseCollation,
DATABASEPROPERTYEX(N'tempdb', 'Collation') AS TempdbCollation;
SELECT name AS ColumnName, collation_name
FROM sys.columns
WHERE object_id = OBJECT_ID(N'dbo.Customers')
AND collation_name IS NOT NULL;
Sustituye dbo.Customers por la tabla afectada. Las columnas de texto pueden diferir del valor predeterminado de la base. Una base restaurada conserva su configuración, mientras que columnas temporales normales suelen heredar la de tempdb en instalaciones convencionales. Por eso un procedimiento puede fallar únicamente tras cambiar de servidor.
Los tipos Unicode no eliminan la intercalación. nvarchar cambia la representación de caracteres, pero las comparaciones todavía necesitan reglas. El ejemplo muestra cómo cambia el resultado.
SELECT
CASE WHEN N'Cafe' COLLATE Latin1_General_100_CI_AI = N'café'
THEN 1 ELSE 0 END AS InsensitiveMatch,
CASE WHEN N'Cafe' COLLATE Latin1_General_100_CS_AS = N'café'
THEN 1 ELSE 0 END AS SensitiveMatch;
InsensitiveMatch vale 1 y SensitiveMatch vale 0. La primera comparación ignora mayúsculas y acentos; la segunda distingue ambos. Ninguna es siempre correcta. Una búsqueda comercial y una restricción de unicidad pueden necesitar políticas diferentes.
Utiliza literales Unicode y parámetros correctamente tipados para entradas multilingües. COLLATE no recupera caracteres perdidos anteriormente al convertirlos mediante una página de códigos incompatible. Repara primero la entrada y el contrato de parámetros.
Alinear la frontera de preparación
Si la columna permanente utiliza el valor predeterminado de la base actual, una columna temporal puede adoptarlo explícitamente.
-- Suitable when the target column uses the current database default.
CREATE TABLE #Incoming (
CustomerCode nvarchar(50) COLLATE DATABASE_DEFAULT NOT NULL
);
CREATE INDEX IX_Incoming_Code ON #Incoming(CustomerCode);
Así evita heredar accidentalmente una configuración distinta de tempdb. No es una solución universal: cuando la columna objetivo tiene una intercalación explícita diferente, la temporal debe coincidir con ella. Comprueba además en qué contexto de base se crea el objeto.
En una consulta ocasional entre bases, aplicar COLLATE a una expresión puede ser razonable. Elige la regla conscientemente y revisa el plan real. Cambiar la intercalación de una columna grande indexada puede exigir conversión y dificultar el uso de su orden existente. Alinear e indexar una entrada temporal más pequeña puede ofrecer una frontera repetible mejor.
Envolver todo en LOWER o UPPER tampoco sustituye la decisión. Puede añadir trabajo por fila, complicar índices y seguir sin expresar correctamente el comportamiento de acentos e idioma. Si el diseño necesita claves normalizadas, deben generarse bajo una regla explícita compartida.
Tratar el cambio como una migración de datos
Cambiar la intercalación predeterminada de la base no modifica automáticamente las columnas existentes. La migración debe inventariar columnas, índices, restricciones, expresiones calculadas y consumidores entre bases. Los scripts de despliegue y los nuevos objetos también deben ser coherentes.
Busca valores que pasarán a ser iguales antes de reconstruir índices únicos. Dos códigos separados solo por mayúsculas o acentos pueden colisionar. Resuélvelos mediante una correspondencia aprobada, sin conservar arbitrariamente la primera fila y perder relaciones de otro cliente.
La ordenación también afecta a paginación y exportaciones. Añade un desempate único y prueba valores multilingües representativos, no solo ASCII. Incluye combinaciones de mayúsculas, acentos, cadenas vacías y los formatos reales admitidos.
Por último, valida resultados y coste. Compara identificadores relacionados, filas de entrada sin coincidencia y duplicados, y después examina lecturas y plan de ejecución. Que la consulta vuelva a funcionar solo demuestra que desapareció el error; todavía deben comprobarse las relaciones del negocio y el rendimiento.
Referencias técnicas: Microsoft Learn: Collation and Unicode · Microsoft Learn: COLLATE.