Collation avec union et tempdb

J'ai une table temporaire dans tempdb, et une table dans la database. Quand je construis une requête avec union de cette table. Il y a une erreur:

Impossible de résoudre le conflit de classment entre "Cyrillic_General_CI_AI" et "Cyrillic_General_CI_AS" dans l'opération UNION.

drop table [sysdb].[##temp table]; create table [sysdb].[##temp table](a varchar); insert into [sysdb].[##temp table] (a) values ('a'),('b'); select grade_name from [mybase].[DDS].[testtable] union select * from [sysdb].[##temp table]; 

J'ai testé mes parameters de collation dans les bases de données avec cette requête:

 SELECT DATABASEPROPERTYEX('mybase', 'Collation') as collation_dwh,DATABASEPROPERTYEX('tempdb', 'Collation') as collation_tempdb 

Le résultat est que le classment des bases de données est le même:

collation_dwh | collation_tempdb

Cyrillic_General_CI_AI | Cyrillic_General_CI_AI

Comment résoudre ce problème ?

Si vous définissez explicitement le classment dans l' union cela devrait fonctionner:

 select grade_name collate Cyrillic_General_CI_AI from [mybase].[DDS].[testtable] union select a collate Cyrillic_General_CI_AI from [sysdb].[##temp table]; 

Notez que les colonnes peuvent avoir un classment différent de la database.

Collation dans Sql Server:

Le classment est un set de règles qui déterminent la manière dont datatables sont sortingées et comparées. Actuellement, sql dispose de quatre niveaux de collation ( server, database, table et colonne ).

Raison du conflit de classment:

Vous avez fait face à des discordances dans les niveaux de collation entre les tables.

Corrections:

Selon le changement de Microsoft le classment au niveau du server n'est pas une solution facile. Source: Avant cela, vous devez adresser toutes les collations non par défaut sur les colonnes pour toutes les tables dans SQL Server

 DECLARE @DatabaseCollation VARCHAR(100) SELECT @DatabaseCollation = collation_name FROM sys.databases WHERE database_id = DB_ID() SELECT @DatabaseCollation 'Default database collation' SELECT t.Name 'Table Name', c.name 'Col Name', ty.name 'Type Name', c.max_length, c.collation_name, c.is_nullable FROM sys.columns c INNER JOIN sys.tables t ON c.object_id = t.object_id INNER JOIN sys.types ty ON c.system_type_id = ty.system_type_id WHERE t.is_ms_shipped = 0 AND c.collation_name <> @DatabaseCollation 
  • Rebuild SQL Server l'une des meilleures solutions.

Pour l'utilisation de correctif temporaire ci-dessous la requête.

 SELECT grade_name COLLATE DATABASE_DEFAULT from [mybase].[DDS].[testtable] UNION SELECT a COLLATE DATABASE_DEFAULT from [sysdb].[##temp table];