Régler les problèmes de collation sur une base de données

Comment régler les problèmes de conflit de collation.

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 ou VARCHAR, 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 :

  1. 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.

  2. 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