Comment se débarrasser du conflit de collation dans une requête SQL Server?
je travaille sur une vue, où j'utilise une jointure interne sur deux tables qui sont de deux serveurs différents. Nous utilisons un serveur lié. Lors de l'exécution de la requête je reçois ce message:
ne peut pas résoudre le conflit de collation entre "SQL_Latin1_General_CP1_CI_AS" et "Arabic_CI_AS" dans l'equal to operation.
Je ne sais pas grand chose à propos de la collation. Rechercher par internet je trouve des solutions à utiliser COLLATE
, mais le concept de COLLATE
n'est pas clair pour moi. Cela changera-t-il quelque chose pour l'une des bases de données? Je cherche une solution sans rien changer pour les bases de données.
tout bon matériel d'apprentissage pour ces concepts est le bienvenu.
3 réponses
vous pouvez résoudre le problème en forçant la collation utilisée dans une requête à être une collation particulière, par exemple SQL_Latin1_General_CP1_CI_AS
ou DATABASE_DEFAULT
. Par exemple:
SELECT MyColumn
FROM FirstTable a
INNER JOIN SecondTable b
ON a.MyID COLLATE SQL_Latin1_General_CP1_CI_AS =
b.YourID COLLATE SQL_Latin1_General_CP1_CI_AS
dans la requête ci-dessus, A. MyID et B. YourID serait des colonnes avec un type de données basé sur le texte. En utilisant COLLATE
va forcer la requête à ignorer la collation par défaut sur la base de données et utiliser à la place la collation fournie, dans ce cas SQL_Latin1_General_CP1_CI_AS
.
En Gros, ce qui se passe ici, c'est que chaque base de données a sa propre collation qui "fournit des règles de tri, des propriétés de sensibilité de cas et d'accent pour vos données" (de http://technet.microsoft.com/en-us/library/ms143726.aspx) et s'applique aux colonnes avec des types de données textuelles, e.g. VARCHAR
,CHAR
,NVARCHAR
, etc. Lorsque deux bases de données ont des collations différentes, vous ne pouvez pas comparer des colonnes de texte avec un opérateur comme égal (=) sans résoudre le conflit entre les deux collations disparates.
j'ai résolu un problème similaire en enveloppant la requête dans une autre requête...
la requête initiale fonctionnait avec find donnant des colonnes individuelles de sortie, avec certaines des colonnes provenant de requêtes secondaires avec la fonction Max ou Sum, et d'autres avec des substitutions "distinctes" ou de cas et ainsi de suite.
j'ai rencontré l'erreur de collation après avoir essayé de créer un seul champ de sortie avec...
select
rtrim(field1)+','+rtrim(field2)+','+...
la requête s'exécuterait comme je l'ai écrit, mais l'erreur se produirait après avoir enregistré le sql et l'avoir rechargé.
J'ai fini par le réparer avec quelque chose comme ça...
select z.field1+','+z.field2+','+... as OUTPUT_REC
from (select rtrim(field1), rtrim(field2), ... ) z
certains champs sont " max " d'un sous-jeu, avec une substitution de cas si null et d'autres sont des champs de date, et certains sont des jointures de gauche (peuvent être NULL)...en d'autres termes, des types de champs mixtes. Je pense que c'est la raison pour laquelle le problème est causé par OS collation et base de données collation étant légèrement différent, mais en convertissant tous les chaînes tronquées avant la sélection finale, il trie hors, tous dans le SQL.
si la base de données est maintenue par vous, créez simplement une nouvelle base de données et importez les données de l'ancienne. le classement problème est résolu!!!!!