web-dev-qa-db-fra.com

Conflit de classement de la table temporaire - Erreur: Impossible de résoudre le conflit de classement entre Latin1 * et SQL_Latin1 *

Je ne peux pas mettre à jour la table temporaire. Ceci est ma requête

CREATE TABLE #temp_po(IndentID INT, OIndentDetailID INT, OD1 VARCHAR(50), OD2 VARCHAR(50), 
        OD3 VARCHAR(50), ORD VARCHAR(50), NIndentDetailID INT, ND1 VARCHAR(50), ND2 VARCHAR(50), 
        ND3 VARCHAR(50), NRD VARCHAR(50), Quantity DECIMAL(15,3))

        INSERT INTO #temp_po(IndentID, OIndentDetailID, OD1, OD2, OD3, ORD)
        SELECT ID.IndentID, ID.IndentDetailID, ID.D1, ID.D2, ID.D3, ID.RandomDimension 
        FROM STR_IndentDetail ID WHERE ID.IndentID = @IndentID

        UPDATE 
            t 
        SET
            t.ND1 = CASE WHEN D.D1 = '' THEN NULL ELSE D.D1 END,
            t.ND2 = CASE WHEN D.D2 = '' THEN NULL ELSE D.D2 END,
            t.ND3 = CASE WHEN D.D3 = '' THEN NULL ELSE D.D3 END,
            t.NRD = CASE WHEN D.RandomDim = '' THEN NULL ELSE D.RandomDim END,
            t.Quantity = D.PurchaseQty
        FROM
            #temp_po t INNER JOIN @detail D ON D.IndentDetailID = t.OIndentDetailID
        WHERE
            t.IndentID = @IndentID

Mais ça donne l'erreur

Impossible de résoudre le conflit de classement entre "Latin1_General_CI_AI" et "SQL_Latin1_General_CP1_CI_AS" dans l'opération égal à.

Comment résoudre ce problème?

Mon classement tempdb est Latin1_General_CI_AI et mon classement actuel dans la base de données est SQL_Latin1_General_CP1_CI_AS.

17
thevan

Cela est dû au fait que les classements sur #tempdb.temp_po.OD1 et STR_IndentDetail.D1 sont différents. 

Puisque vous avez le contrôle sur la création de la table temporaire, le moyen le plus simple de résoudre ce problème semble être de créer des colonnes * char dans la table temporaire avec le même classement que votre table STR_IndentDetail:

CREATE TABLE #temp_po(
    IndentID INT, 
    OIndentDetailID INT, 
    OD1 VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS, 
    .. Same for the other *char columns   

Dans le cas où vous n'avez pas le contrôle de la création de la table, lorsque vous joignez les colonnes, vous pouvez également ajouter des instructions COLLATE explicites dans le DML dans lesquelles des erreurs se produisent, soit via COLLATE SQL_Latin1_General_CP1_CI_AS, soit plus facilement, à l'aide de COLLATE DATABASE_DEFAULT.

SELECT * FROM #temp_po t INNER JOIN STR_IndentDetail s 
   ON t.OD1 = s.D1 COLLATE SQL_Latin1_General_CP1_CI_AS;

OU plus facile

SELECT * FROM #temp_po t INNER JOIN STR_IndentDetail s 
   ON t.OD1 = s.D1 COLLATE DATABASE_DEFAULT;

SqlFiddle ici

29
StuartLC

La modification du classement du serveur n’est pas une décision simple, il est possible que d’autres bases de données sur le serveur soient affectées. Même changer le classement de la base de données n'est pas toujours recommandé pour une base de données déjà existante. Je pense que l’utilisation de COLLATE DATABASE_DEFAULT lors de la création d’une table temporaire est l’option la plus sûre et la plus simple car elle ne code en dur aucun classement dans votre sql. Par exemple:

CREATE TABLE #temp_table1
(
    column_1    VARCHAR(2)  COLLATE database_default
)
2
Maneesh Singh

Par défaut, la table temporaire prend le classement du serveur. Par conséquent, la mise à jour de toutes les procédures stockées avec la table temporaire ne modifie que le classement du serveur.

Vérifiez ce lien pour Définir ou modifier le classement du serveur

Cela a fonctionné pour moi.

0
Munavvar

Nous avons rencontré le même problème en ce moment. Au lieu d’ajouter le classement à la création de la table temporaire (ou à chaque jointure de table temporaire), nous avons simplement modifié la création de la table temporaire en une déclaration de variable de table.

0
IngoB