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
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];