Impossible de résoudre le conflit de classement entre "SQL Latin1 General CP1 CI AS" et "Latin1 General CI AS" dans l'opération égale à

J'ai le code suivant

SELECT tA.FieldName As [Field Name],
       COALESCE(tO_A.[desc], tO_B.[desc], tO_C.Name, tA.OldVAlue) AS [Old Value],
       COALESCE(tN_A.[desc], tN_B.[desc], tN_C.Name, tA.NewValue) AS [New Value],
       U.UserName AS [User Name],
       CONVERT(varchar, tA.ChangeDate) AS [Change Date] 
  FROM D tA
       JOIN 
       [DRTS].[dbo].[User] U 
         ON tA.UserID = U.UserID
       LEFT JOIN 
       A tO_A 
         on tA.FieldName = 'AID' 
        AND tA.oldValue = CONVERT(VARCHAR, tO_A.ID)
       LEFT JOIN 
       A tN_A 
         on tA.FieldName = 'AID' 
        AND tA.newValue = CONVERT(VARCHAR, tN_A.ID)
       LEFT JOIN 
       B tO_B 
         on tA.FieldName = 'BID' 
        AND tA.oldValue = CONVERT(VARCHAR, tO_B.ID)
       LEFT JOIN 
       B tN_B 
         on tA.FieldName = 'BID' 
        AND tA.newValue = CONVERT(VARCHAR, tN_B.ID)
       LEFT JOIN 
       C tO_C 
         on tA.FieldName = 'CID' 
        AND tA.oldValue = tO_C.Name
       LEFT JOIN 
       C tN_C 
         on tA.FieldName = 'CID' 
        AND tA.newValue = tN_C.Name
 WHERE U.Fullname = @SearchTerm
ORDER BY tA.ChangeDate

Lors de l'exécution du code, je reçois l'erreur collée dans le titre après avoir ajouté les deux jointures pour la table C. je pense que cela peut avoir quelque chose à voir avec le fait que J'utilise SQL Server 2008 et que j'ai restauré une copie de cette base de données sur ma machine qui est 2005.

257
demandé sur halfer 2009-10-22 18:20:13

22 réponses

Vous avez une discordance de deux collations différentes dans votre table. Vous pouvez vérifier les collations de chaque colonne de votre(vos) table (s) en utilisant cette requête:

SELECT
    col.name, col.collation_name
FROM 
    sys.columns col
WHERE
    object_id = OBJECT_ID('YourTableName')

Les Collations sont nécessaires et utilisées lors de la commande et de la comparaison de chaînes. C'est généralement une bonne idée d'avoir un seul classement unique utilisé dans votre base de données - n'utilisez pas de classement différent dans une seule table ou base de données - vous ne demandez que des problèmes....

Une fois que vous avez réglé pour une seule collation, vous peut changer les tables / colonnes qui ne correspondent pas encore en utilisant cette commande:

ALTER TABLE YourTableName
  ALTER COLUMN OffendingColumn
    VARCHAR(100) COLLATE Latin1_General_CI_AS NOT NULL

Marc

UPDATE: pour trouver les index fulltext dans votre base de données, utilisez cette requête ici:

SELECT
    fti.object_Id,
    OBJECT_NAME(fti.object_id) 'Fulltext index',
    fti.is_enabled,
    i.name 'Index name',
    OBJECT_NAME(i.object_id) 'Table name'
FROM 
    sys.fulltext_indexes fti
INNER JOIN 
    sys.indexes i ON fti.unique_index_id = i.index_id

Vous pouvez alors supprimer l'index fulltext en utilisant:

DROP FULLTEXT INDEX ON (tablename)
247
répondu marc_s 2009-10-22 15:33:43

Je fais ce qui suit:

...WHERE 
    fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT

Fonctionne à chaque fois. :)

666
répondu Valkyrie 2015-03-24 11:39:38

Utilisez la clause collate dans votre requête:

LEFT JOIN C tO_C on tA.FieldName = 'CID' AND tA.oldValue COLLATE Latin1_General_CI_AS = tO_C.Name  

Je n'ai peut-être pas la bonne syntaxe (Vérifiez BOL), mais vous pouvez le faire pour changer le classement à la volée pour la requête-vous devrez peut - être ajouter la clause pour chaque jointure.

Edit: j'ai réalisé que ce n'était pas tout à fait correct - la clause collate va après le champ que vous devez changer - dans cet exemple, j'ai changé le classement sur le Champ tA.oldValue.

60
répondu Ray 2013-11-02 10:19:38

Identifiez les champs pour lesquels il lance cette erreur et ajoutez les suivants: COLLATE DATABASE_DEFAULT

Il y a deux tables jointes sur le champ de Code:

...
and table1.Code = table2.Code
...

Mettez à jour votre requête vers:

...
and table1.Code COLLATE DATABASE_DEFAULT = table2.Code COLLATE DATABASE_DEFAULT
...
21
répondu Palak.Maheria 2014-11-08 05:23:52

@ Valkyrie réponse impressionnante. Je pensais que je mettais ici un cas en effectuant la même chose avec une sous-requête à l'intérieur d'une procédure stockée, car je me demandais si votre réponse fonctionnait dans ce cas, et c'était génial.

...WHERE fieldname COLLATE DATABASE_DEFAULT in ( select distinct otherfieldname COLLATE DATABASE_DEFAULT from ... where ... )

11
répondu Ikram M. 2016-01-21 19:48:09

Cela peut facilement se produire lorsque vous avez 2 bases de données différentes et spécialement 2 bases de données différentes de 2 serveurs différents. La meilleure option est de le changer en une collection commune et de faire la jointure ou la comparaison.

select 
   *
from sd
inner join pd on sd.SCaseflowID collate  Latin1_General_CS_AS = pd.PDebt_code collate  Latin1_General_CS_AS
8
répondu Bazzzzzzz 2015-02-03 16:15:27

La cause principale est que la base de données sql server à partir de laquelle vous avez pris le schéma a un classement qui diffère de votre installation locale. Si vous ne voulez pas vous soucier du classement, réinstallez SQL Server localement en utilisant le même classement que la base de données SQL Server 2008.

6
répondu Robert 2009-10-22 14:48:45

Dans le critère where ajouter collate SQL_Latin1_General_CP1_CI_AS

Cela fonctionne pour moi.

WHERE U.Fullname = @SearchTerm  collate SQL_Latin1_General_CP1_CI_AS
5
répondu Carlos de Jesus Baez 2018-06-08 17:58:56

J'ai déjà eu quelque chose comme ça, et ce que nous avons trouvé, c'est que le classement entre 2 tables était différent.

Vérifiez que ce sont les mêmes.

4
répondu Adriaan Stander 2009-10-22 14:28:25

Erreur (Impossible de résoudre le conflit de classement entre .... ) se produit généralement lors de la comparaison des données de plusieurs bases de données.

Puisque vous ne pouvez pas modifier le classement des bases de données maintenant, utilisez COLLATE DATABASE_DEFAULT.

----------
AND db1.tbl1.fiel1 COLLATE DATABASE_DEFAULT =db2.tbl2.field2 COLLATE DATABASE_DEFAULT 
4
répondu chaminda welgamage 2017-12-15 14:09:29

Grâce à la réponse de marc_s, j'ai résolu mon problème original-inspiré pour aller plus loin et poster une approche pour transformer une table entière à la fois - script tsql pour générer les instructions ALTER column:

DECLARE @tableName VARCHAR(MAX)
SET @tableName = 'affiliate'
--EXEC sp_columns @tableName
SELECT  'Alter table ' + @tableName + ' alter column ' + col.name
        + CASE ( col.user_type_id )
            WHEN 231
            THEN ' nvarchar(' + CAST(col.max_length / 2 AS VARCHAR) + ') '
          END + 'collate Latin1_General_CI_AS ' + CASE ( col.is_nullable )
                                                    WHEN 0 THEN ' not null'
                                                    WHEN 1 THEN ' null'
                                                  END
FROM    sys.columns col
WHERE   object_id = OBJECT_ID(@tableName)

Obtient: ALTER TABLE Affiliate ALTER COLUMN myTable NVARCHAR (4000) COLLATE Latin1_General_CI_AS NOT NULL

J'admets être perplexe par la nécessité de col. max_length / 2 -

3
répondu justSteve 2014-12-04 13:26:26

Pour ceux qui ont un script CREATE DATABASE (comme c'était mon cas) pour la base de données à l'origine de ce problème, vous pouvez utiliser le script CREATE suivant pour correspondre au classement:

-- Create Case Sensitive Database
CREATE DATABASE CaseSensitiveDatabase
COLLATE SQL_Latin1_General_CP1_CS_AS -- or any collation you require
GO
USE CaseSensitiveDatabase
GO
SELECT *
FROM sys.types
GO
--rest of your script here

Ou

-- Create Case In-Sensitive Database
CREATE DATABASE CaseInSensitiveDatabase
COLLATE SQL_Latin1_General_CP1_CI_AS -- or any collation you require
GO
USE CaseInSensitiveDatabase
GO
SELECT *
FROM sys.types
GO
--rest of your script here

Ceci applique le classement souhaité à toutes les tables, ce qui était exactement ce dont j'avais besoin. Il est idéal d'essayer de garder le même classement pour toutes les bases de données sur un serveur. Espérons que cette aide.

Plus d'informations sur le lien suivant: SQL SERVER-création de base de données avec différents Classement sur le Serveur

2
répondu pechar 2013-01-18 08:51:29

J'ai utilisé le contenu de ce site pour créer le script suivant qui modifie le classement de toutes les colonnes de toutes les tables:

CREATE PROCEDURE [dbo].[sz_pipeline001_collation] 
    -- Add the parameters for the stored procedure here
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;


SELECT 'ALTER TABLE [' + SYSOBJECTS.Name + '] ALTER COLUMN [' + SYSCOLUMNS.Name + '] ' +
SYSTYPES.name + 
    CASE systypes.NAME
    WHEN 'text' THEN ' '
    ELSE
    '(' + RTRIM(CASE SYSCOLUMNS.length
    WHEN -1 THEN 'MAX'
    ELSE CONVERT(CHAR,SYSCOLUMNS.length)
    END) + ') ' 
    END

    + ' ' + ' COLLATE Latin1_General_CI_AS ' + CASE ISNULLABLE WHEN 0 THEN 'NOT NULL' ELSE 'NULL' END
    FROM SYSCOLUMNS , SYSOBJECTS , SYSTYPES
    WHERE SYSCOLUMNS.ID = SYSOBJECTS.ID
    AND SYSOBJECTS.TYPE = 'U'
    AND SYSTYPES.Xtype = SYSCOLUMNS.xtype
    AND SYSCOLUMNS.COLLATION IS NOT NULL
    AND NOT ( sysobjects.NAME LIKE 'sys%' )
    AND NOT ( SYSTYPES.name LIKE 'sys%' )

END
2
répondu Chagbert 2015-06-04 08:39:05

Si cela se produit sur l'ensemble de votre base de données, il est préférable de changer votre classement de base de données comme suit:

USE master;  
GO  
ALTER DATABASE MyOptionsTest  
COLLATE << INSERT COLATION REQUIRED >> ;  
GO  

--Verify the collation setting.  
SELECT name, collation_name  
FROM sys.databases  
WHERE name = N'<< INSERT DATABASE NAME >>';  
GO 

Référence ici

2
répondu Justin 2018-01-25 09:37:54

J'ai eu une erreur similaire (impossible de résoudre le conflit de classement entre "SQL_Latin1_General_CP1_CI_AS " et" SQL_Latin1_General_CP1250_CI_AS " dans L'opération INTERSECT), quand j'ai utilisé l'ancien pilote jdbc.

J'ai résolu cela en téléchargeant le nouveau pilote de Microsoft ou open-source project jTDS.

1
répondu krzy-wa 2014-05-12 10:46:42

Voici ce que nous avons fait, dans notre situation, nous avons besoin d'une requête ad hoc à exécuter en utilisant une restriction de date à la demande, et la requête est définie dans une table.

Notre nouvelle requête doit faire correspondre les données entre différentes bases de données et inclure les données des deux.

Il semble que le classement soit différent entre la base de données qui importe les données du système iSeries/AS400 et notre base de données de rapports - cela pourrait être dû aux types de données spécifiques (tels que les accents grecs sur les noms et ainsi de suite sur).

Nous avons donc utilisé la clause join ci-dessous:

...LEFT Outer join ImportDB..C4CTP C4 on C4.C4CTP COLLATE Latin1_General_CS_AS=CUS_Type COLLATE Latin1_General_CS_AS
1
répondu Our Man in Bananas 2014-05-12 12:15:00

ALTER DATABASE test2 -- mettez votre nom de base de données ici COLLATE Latin1_General_CS_AS -- remplacez par tout collation dont vous avez besoin

1
répondu jig's 2015-02-09 13:25:25

Vous pouvez facilement le faire en utilisant 4 étapes faciles

  1. sauvegardez votre base de données, juste au cas où
  2. modifier le classement de la base de données: cliquez avec le bouton droit sur base de données, sélectionnez Propriétés, allez dans les options et modifiez le classement pour le classement requis.
  3. générer un script pour supprimer et recréer tous vos objets de base de données: faites un clic droit sur votre base de données, sélectionnez Tâches, sélectionnez Générer un script... (assurez-vous de sélectionner Supprimer et créer dans les options avancées de L'Assistant, sélectionnez également schéma et données )
  4. Exécutez le Script généré ci-dessus
1
répondu Felix Mwiti Mugambi 2015-11-22 16:39:55

Vérifiez le niveau de classement qui ne correspond pas (Serveur,base de données,table,colonne, caractère).

Si c'est le serveur, ces étapes m'ont aidé une fois:

  1. Arrêter le serveur
  2. Trouvez votre sqlservr.outil exe
  3. Exécutez cette commande:

    sqlservr -m -T4022 -T3659 -s"name_of_insance" -q "name_of_collation"

  4. Démarrez votre serveur sql:

    net start name_of_instance

  5. Vérifiez à nouveau le classement de votre serveur.

Voici plus info:

Https://www.mssqltips.com/sqlservertip/3519/changing-sql-server-collation-after-installation/

1
répondu WholeLifeLearner 2017-04-24 11:57:19
INSERT INTO eSSLSmartOfficeSource2.[dbo].DeviceLogs  (DeviceId,UserId,LogDate,UpdateFlag) 
SELECT DL1.DeviceId ,DL1.UserId COLLATE DATABASE_DEFAULT,DL1.LogDate 
,0 FROM eSSLSmartOffice.[dbo].DeviceLogs DL1 
WHERE  NOT EXISTS 
(SELECT DL2.DeviceId ,DL2.UserId COLLATE DATABASE_DEFAULT
,DL2.LogDate ,DL2.UpdateFlag 
FROM eSSLSmartOfficeSource2.[dbo].DeviceLogs DL2    
WHERE  DL1.DeviceId =DL2.DeviceId
 and DL1.UserId collate  Latin1_General_CS_AS=DL2.UserId collate  Latin1_General_CS_AS
  and DL1.LogDate =DL2.LogDate )
1
répondu Arati 2018-03-08 08:21:28

Code ajouté à la réponse de @JustSteve pour traiter les colonnes varchar et varchar(MAX):

DECLARE @tableName VARCHAR(MAX)
SET @tableName = 'first_notes'
--EXEC sp_columns @tableName
SELECT  'Alter table ' + @tableName + ' alter column ' + col.name
        + CASE ( col.user_type_id )
            WHEN 231
            THEN ' nvarchar(' + CAST(col.max_length / 2 AS VARCHAR) + ') '
            WHEN 167
            THEN ' varchar(' + CASE col.max_length 
                                WHEN -1 
                                THEN 'MAX'
                                ELSE 
                                CAST(col.max_length AS VARCHAR)
                                end
                                 + ') '
          END + 'collate Latin1_General_CI_AS ' + CASE ( col.is_nullable )
                                                    WHEN 0 THEN ' not null'
                                                    WHEN 1 THEN ' null'
                                                  END
FROM    sys.columns col
WHERE   object_id = OBJECT_ID(@tableName)
1
répondu Goner Doug 2018-06-26 01:36:32

Vous n'avez peut-être aucun problème de classement dans votre base de données, mais si vous restaurez une copie de votre base de données à partir d'une sauvegarde sur un serveur avec un classement différent de l'origine, et que votre code crée des tables temporaires, ces tables temporaires hériteront du classement du serveur et il y aura des conflits avec

0
répondu ajeh 2018-08-21 21:04:34