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
.
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;
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
)
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.
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.