Régler les problèmes de collation sur une base de données
Si vous restaurez une base de données sur un serveur dont la collation par défaut est différente, vous risquez deux problèmes :
- Des conflits de collation entre des requêtes interbase où on compare des colonnes de type
CHAR
ouVARCHAR
, par exemple dans une clause de jointure ; - Des conflits de collation dans du code qui travaille avec des tables temporaires.
Régler les problèmes de tables temporaires
Lorsque vous créez une table temporaire (table avec le symbole #
), la collation des colonnes de type CHAR
et VARCHAR
est définie par la collation par défaut de la base de données tempdb
.
Ensuite, si vous effectuez des comparaisons avec des colonnes de la base de données courante, vous obtiendrez l’erreur 468 : Cannot resolve the collation conflict between...
.
Vous avez deux solutions pour régler ce problème :
-
Créer vos tables temporaires avec une collation explicite, en utilisant la clause
COLLATE
et le mot-cléDATABASE_DEFAULT
:CREATE TABLE #TempTable ( Id INT, Name VARCHAR(50) COLLATE DATABASE_DEFAULT );
Cela applique la collation par défaut de la base de données courante à la colonne
Name
. -
Utiliser la fonctionnalité Partially Contained Database. Quand une base de données est marquée contained, ou autonome, la collation des tables temporaires créées dans son contexte est celle de la base de données.
Activer la fonctionnalité Partially Contained Database
Vous devez d’abord autoriser la fonctionnalité Partially Contained Database au niveau du serveur :
EXEC sys.sp_configure N'contained database authentication', N'1';
RECONFIGURE WITH OVERRIDE;
GO
Il faut ensuite activer la fonctionnalité sur la base de données. Cette action nécessite d’obtenir l’accès exclusif à la base de données. Nous utilisons donc la clause SINGLE_USER
avec l’option ROLLBACK IMMEDIATE
pour forcer la déconnexion de tous les utilisateurs et annuler toutes les transactions en cours :
USE Master
GO
ALTER DATABASE [MyDatabase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
ALTER DATABASE [MyDatabase] SET CONTAINMENT = PARTIAL;
GO