Classements de base de données à relation contenant-contenuContained Database Collations

Diverses propriétés affectent l'ordre de tri et la sémantique d'égalité des données textuelles, notamment le respect de la casse, le respect des accents et la langue de base utilisée.Various properties affect the sort order and equality semantics of textual data, including case sensitivity, accent sensitivity, and the base language being used. Ces qualités sont exprimées à SQL ServerSQL Server par le choix du classement des données.These qualities are expressed to SQL ServerSQL Server through the choice of collation for the data. Pour une explication plus approfondie des classements eux-mêmes, consultez Prise en charge d’Unicode et du classement.For a more in-depth discussion of collations themselves, see Collation and Unicode Support.

Les classements ne s'appliquent pas seulement aux données stockées dans les tables utilisateur, mais à tout le texte géré par SQL ServerSQL Server, notamment les métadonnées, les objets temporaires, les noms de variable, etc. Leur gestion est différente dans une base de données à relation contenant-contenu et dans une base de données sans relation contenant-contenu.Collations apply not only to data stored in user tables, but to all text handled by SQL ServerSQL Server, including metadata, temporary objects, variable names, etc. The handling of these differs in contained and non-contained databases. Cette modification n'affecte pas de nombreux utilisateurs, mais permet l'indépendance et l'uniformité des instances.This change will not affect many users, but helps provide instance independence and uniformity. Cependant, elle peut provoquer également quelques confusions, ainsi que des problèmes pour les sessions qui accèdent à la fois à des bases de données à relation contenant-contenu et à des bases de données sans relation contenant-contenu.But this may also cause some confusion, as well as problems for sessions that access both contained and non-contained databases.

Cette rubrique apporte des éclaircissements sur le contenu de la modification et indique où celle-ci peut entraîner des problèmes.This topic clarifies the content of the change, and examines areas where the change may cause problems.

Bases de données sans relation contenant-contenuNon-Contained Databases

Toutes les bases de données ont un classement par défaut (qui peut être défini lors de la création ou de la modification d'une base de données).All databases have a default collation (which can be set when creating or altering a database. Ce classement est utilisé pour toutes les métadonnées de la base de données, et comme valeur par défaut de toutes les colonnes de chaîne dans la base de données.This collation is used for all metadata in the database, as well as the default for all string columns within the database. Les utilisateurs peuvent choisir un classement différent pour une colonne particulière à l’aide de la clause COLLATE .Users can choose a different collation for any particular column by using the COLLATE clause.

Exemple 1Example 1

Par exemple, supposons que nous travaillons à Beijing et que nous utilisons un classement chinois :For example, if we were working in Beijing, we might use a Chinese collation:

ALTER DATABASE MyDB COLLATE Chinese_Simplified_Pinyin_100_CI_AS;  

Si nous créons une colonne, son classement par défaut sera ce classement chinois, mais nous pouvons en choisir un autre si nous le voulons :Now if we create a column, its default collation will be this Chinese collation, but we can choose another one if we want:

CREATE TABLE MyTable  
      (mycolumn1 nvarchar,  
      mycolumn2 nvarchar COLLATE Frisian_100_CS_AS);  
GO  
SELECT name, collation_name  
FROM sys.columns  
WHERE name LIKE 'mycolumn%' ;  
GO  

Voici l'ensemble des résultats.Here is the result set.

name            collation_name  
--------------- ----------------------------------  
mycolumn1       Chinese_Simplified_Pinyin_100_CI_AS  
mycolumn2       Frisian_100_CS_AS  

Cela semble relativement simple, mais plusieurs problèmes se posent.This appears relatively simple, but several problems arise. Étant donné que le classement d’une colonne dépend de la base de données dans laquelle la table est créée, des problèmes se posent pour l’utilisation des tables temporaires stockées dans tempdb.Because the collation for a column is dependent on the database in which the table is created, problems arise with the use of temporary tables which are stored in tempdb. Le classement de tempdb correspond généralement au classement de l’instance, qui n’est pas obligatoirement celui de la base de données.The collation of tempdb usually matches the collation for the instance, which does not have to match the database collation.

Exemple 2Example 2

Par exemple, examinez la base de données (chinoise) ci-dessus utilisée sur une instance avec un classement Latin1_General :For example, consider the (Chinese) database above when used on an instance with a Latin1_General collation:

CREATE TABLE T1 (T1_txt nvarchar(max)) ;  
GO  
CREATE TABLE #T2 (T2_txt nvarchar(max)) ;  
GO  

À première vue, ces deux tables semblent avoir le même schéma, mais comme les classements des bases de données diffèrent, les valeurs sont en fait incompatibles :At first glance, these two tables look like they have the same schema, but since the collations of the databases differ, the values are actually incompatible:

SELECT T1_txt, T2_txt  
FROM T1   
JOIN #T2   
    ON T1.T1_txt = #T2.T2_txt  

Voici l'ensemble des résultats.Here is the result set.

Msg 468, Niveau 16, État 9, Ligne 2Msg 468, Level 16, State 9, Line 2

Impossible de résoudre le conflit de classement entre « Latin1_General_100_CI_AS_KS_WS_SC » et « Chinese_Simplified_Pinyin_100_CI_AS » dans l'opération égal à.Cannot resolve the collation conflict between "Latin1_General_100_CI_AS_KS_WS_SC" and Chinese_Simplified_Pinyin_100_CI_AS" in the equal to operation.

Nous pouvons résoudre ce problème en classant la table temporaire de façon explicite.We can fix this by explicitly collating the temporary table. SQL ServerSQL Server simplifie quelque peu cette opération en fournissant le mot clé DATABASE_DEFAULT pour la clause COLLATE . makes this somewhat easier by providing the DATABASE_DEFAULT keyword for the COLLATE clause.

CREATE TABLE T1 (T1_txt nvarchar(max)) ;  
GO  
CREATE TABLE #T2 (T2_txt nvarchar(max) COLLATE DATABASE_DEFAULT);  
GO  
SELECT T1_txt, T2_txt  
FROM T1   
JOIN #T2   
    ON T1.T1_txt = #T2.T2_txt ;  

Ce code s'exécute maintenant sans erreur.This now runs without error.

Nous pouvons également consulter le comportement dépendant du classement avec des variables.We can also see collation-dependent behavior with variables. Observez la fonction suivante :Consider the following function:

CREATE FUNCTION f(@x INT) RETURNS INT  
AS BEGIN   
      DECLARE @I INT = 1  
      DECLARE @İ INT = 2  
      RETURN @x * @i  
END;  

C'est une fonction assez particulière.This is a rather peculiar function. Dans un classement respectant la casse, le @i dans la clause return ne peut pas être lié un autre @I ni à @İ.</span><span class="sxs-lookup">In a case-sensitive collation, the @i in the return clause cannot bind to either @I or @İ.</span></span> Dans un classement Latin1_General sans respect de la casse, @i est lié à @I, et la fonction retourne 1.In a case-insensitive Latin1_General collation, @i binds to @I, and the function returns 1. Mais dans un classement turc sans respect de la casse, @i est lié à @İ et la fonction retourne 2.But in a case-insensitive Turkish collation, @i binds to @İ, and the function returns 2. Cela peut causer des dégâts dans une base de données qui se déplace entre des instances aux classements différents.This can wreak havoc on a database that moves between instances with different collations.

Bases de données à relation contenant-contenuContained Databases

Comme un objectif de la conception de bases de données à relation contenant-contenu est de les rendre autonomes, la dépendance de l’instance et des classements de tempdb doit être supprimée.Since a design objective of contained databases is to make them self-contained, the dependence on the instance and tempdb collations must be severed. Pour cela, les bases de données à relation contenant-contenu présentent le concept de classement de catalogue.To do this, contained databases introduce the concept of the catalog collation. Le classement de catalogue est utilisé pour les métadonnées système et les objets transitoires.The catalog collation is used for system metadata and transient objects. Des informations complémentaires sont fournies ci-dessous.Details are provided below.

Dans une base de données à relation contenant-contenu, le classement de catalogue est Latin1_General_100_CI_AS_WS_KS_SC.In a contained database, the catalog collation Latin1_General_100_CI_AS_WS_KS_SC. Ce classement est le même pour toutes les bases de données à relation contenant-contenu sur toutes les instances de SQL ServerSQL Server et ne peut pas être changé.This collation is the same for all contained databases on all instances of SQL ServerSQL Server and cannot be changed.

Le classement de base de données est conservé, mais est utilisé uniquement comme classement par défaut des données utilisateur.The database collation is retained, but is only used as the default collation for user data. Par défaut, le classement de base de données est égal au classement de base de données model, mais peut être modifié par l’utilisateur via une commande CREATE ou ALTER DATABASE comme avec les bases de données sans relation contenant-contenu.By default, the database collation is equal to the model database collation, but can be changed by the user through a CREATE or ALTER DATABASE command as with non-contained databases.

Un nouveau mot clé, CATALOG_DEFAULT, est disponible dans la clause COLLATE .A new keyword, CATALOG_DEFAULT, is available in the COLLATE clause. Il est utilisé comme un raccourci du classement actuel de métadonnées à la fois dans les bases de données avec et sans relation contenant-contenu.This is used as a shortcut to the current collation of metadata in both contained and non-contained databases. Autrement dit, dans une base de données sans relation contenant-contenu, CATALOG_DEFAULT retourne le classement de base de données actuel, puisque les métadonnées sont assemblées dans le classement de base de données.That is, in a non-contained database, CATALOG_DEFAULT will return the current database collation, since metadata is collated in the database collation. Dans une base de données à relation contenant-contenu, ces deux valeurs peuvent être différentes, puisque l'utilisateur peut modifier le classement de base de données afin qu'il ne corresponde pas au classement de catalogue.In a contained database, these two values may be different, since the user can change the database collation so that it does not match the catalog collation.

Le comportement de différents objets dans les bases de données avec ou sans relation contenant-contenu est résumé dans ce tableau :The behavior of various objects in both non-contained and contained databases is summarized in this table:

ÉlémentItem Base de données sans relation contenant-contenuNon-Contained Database Base de données à relation contenant-contenuContained Database
Données utilisateur (valeur par défaut)User Data (default) DATABASE_DEFAULTDATABASE_DEFAULT DATABASE_DEFAULTDATABASE_DEFAULT
Données Temp (valeur par défaut)Temp Data (default) Classement TempDBTempDB Collation DATABASE_DEFAULTDATABASE_DEFAULT
MétadonnéesMetadata DATABASE_DEFAULT / CATALOG_DEFAULTDATABASE_DEFAULT / CATALOG_DEFAULT CATALOG_DEFAULTCATALOG_DEFAULT
Métadonnées temporairesTemporary Metadata Classement TempDBtempdb Collation CATALOG_DEFAULTCATALOG_DEFAULT
VariablesVariables Classement d'instanceInstance Collation CATALOG_DEFAULTCATALOG_DEFAULT
Étiquettes gotoGoto Labels Classement d'instanceInstance Collation CATALOG_DEFAULTCATALOG_DEFAULT
Noms de curseurCursor Names Classement d'instanceInstance Collation CATALOG_DEFAULTCATALOG_DEFAULT

Si nous examinons l’exemple de table temp décrit précédemment, nous pouvons voir que ce comportement de classement rend la clause COLLATE explicite inutile dans la plupart des utilisations de table temp.If we temp table example previously described, we can see that this collation behavior eliminates the need for an explicit COLLATE clause in most temp table uses. Dans une base de données à relation contenant-contenu, ce code s'exécute désormais sans erreur, même si les classements d'instance et de base de données diffèrent :In a contained database, this code now runs without error, even if the database and instance collations differ:

CREATE TABLE T1 (T1_txt nvarchar(max)) ;  
GO  
CREATE TABLE #T2 (T2_txt nvarchar(max));  
GO  
SELECT T1_txt, T2_txt  
FROM T1   
JOIN #T2   
    ON T1.T1_txt = #T2.T2_txt ;  

Cela fonctionne parce que T1_txt et T2_txt sont assemblés dans le classement de base de données de la base de données à relation contenant-contenu.This works because both T1_txt and T2_txt are collated in the database collation of the contained database.

Passer d'un contexte à relation contenant-contenu à un contexte sans relation contenant-contenuCrossing Between Contained and Uncontained Contexts

Tant qu'une session dans une base de données à relation contenant-contenu reste contenue, elle doit rester dans la base de données à laquelle elle s'est connectée.As long as a session in a contained database remains contained, it must remain within the database to which it connected. Dans ce cas, le comportement est très simple.In this case the behavior is very straightforward. Mais si une session passe d'un contexte à relation contenant-contenu à un contexte sans relation contenant-contenu, le comportement devient plus complexe, puisque deux ensembles de règles doivent être liés.But if a session crosses between contained and non-contained contexts, the behavior becomes more complex, since the two sets of rules must be bridged. Cela peut arriver dans une base de données partiellement à relation contenant-contenu, puisqu’un utilisateur peut exécuter une opération USE sur une autre base de données.This can happen in a partially-contained database, since a user may USE to another database. Dans ce cas, la différence des règles de classement est gérée selon le principe suivant.In this case, the difference in collation rules is handled by the following principle.

  • Le comportement du classement d'un lot est déterminé par la base de données dans laquelle commence le lot.The collation behavior for a batch is determined by the database in which the batch begins.

    Notez que cette décision est prise avant l’émission d’une commande, notamment la commande USEinitiale.Note that this decision is made before any commands are issued, including an initial USE. Autrement dit, si un lot commence dans une base de données à relation contenant-contenu, mais que la première commande est une opération USE sur une base de données sans relation contenant-contenu, le comportement du classement à relation contenant-contenu sera toujours utilisé pour le lot.That is, if a batch begins in a contained database, but the first command is a USE to a non-contained database, the contained collation behavior will still be used for the batch. En conséquence, une référence à une variable, par exemple, peut donner plusieurs résultats possibles :Given this, a reference to a variable, for example, may have multiple possible outcomes:

  • La référence peut trouver exactement une correspondance.The reference may find exactly one match. Dans ce cas, la référence fonctionnera sans erreur.In this case, the reference will work without error.

  • La référence peut pas trouver de correspondance dans le classement actuel alors qu'il en existait une auparavant.The reference may not find a match in the current collation where there was one before. Cela génère une erreur indiquant que la variable n'existe pas, bien qu'elle ait été apparemment créée.This will raise an error indicating that the variable does not exist, even though it was apparently created.

  • La référence peut trouver plusieurs correspondances qui étaient distinctes à l'origine.The reference may find multiple matches that were originally distinct. Cela génère également une erreur.This will also raise an error.

    Illustrons ceci par quelques exemples.We’ll illustrate this with a few examples. Pour ces exemples, nous supposons une base de données partiellement à relation contenant-contenu, nommée MyCDB , dont le classement de base de données est défini sur le classement par défaut, Latin1_General_100_CI_AS_WS_KS_SC.For these we assume there is a partially-contained database named MyCDB with its database collation set to the default collation, Latin1_General_100_CI_AS_WS_KS_SC. Nous supposons que le classement d’instance est Latin1_General_100_CS_AS_WS_KS_SC.We assume that the instance collation is Latin1_General_100_CS_AS_WS_KS_SC. Les deux classements diffèrent uniquement en fonction du respect de la casse.The two collations differ only in case sensitivity.

Exemple 1Example 1

L'exemple suivant illustre le cas où la référence trouve exactement une correspondance.The following example illustrates the case where the reference finds exactly one match.

USE MyCDB;  
GO  

CREATE TABLE #a(x int);  
INSERT INTO #a VALUES(1);  
GO  

USE master;  
GO  

SELECT * FROM #a;  
GO  

Results:  

Voici l'ensemble des résultats.Here is the result set.

x  
-----------  
1  

Dans ce cas, le #a identifié est lié à la fois au classement de catalogue qui ne respecte pas la casse et au classement d'instance qui respecte la casse ; donc le code fonctionne.In this case, the identified #a binds in both the case-insensitive catalog collation and the case-sensitive instance collation, and the code works.

Exemple 2Example 2

L'exemple suivant illustre le cas où la référence ne trouve pas de correspondance dans le classement actuel alors qu'il en existait une auparavant.The following example illustrates the case where the reference does not find a match in the current collation where there was one before.

USE MyCDB;  
GO  

CREATE TABLE #a(x int);  
INSERT INTO #A VALUES(1);  
GO  

Ici, le #A est lié à #a dans le classement par défaut qui ne respecte pas la casse, et l'insertion fonctionne,Here, the #A binds to #a in the case-insensitive default collation, and the insert works,

Voici l'ensemble des résultats.Here is the result set.

(1 row(s) affected)  

mais si nous continuons le script...But if we continue the script...

USE master;  
GO  

SELECT * FROM #A;  
GO  

Nous obtenons une erreur lors de la tentative de lier #A dans le classement d'instance qui respecte la casse ;We get an error trying to bind to #A in the case-sensitive instance collation;

Voici l'ensemble des résultats.Here is the result set.

Msg 208, Niveau 16, État 0, Ligne 2Msg 208, Level 16, State 0, Line 2

Nom d'objet '#A' non valide.Invalid object name '#A'.

Exemple 3Example 3

L'exemple suivant illustre le cas où la référence trouve plusieurs correspondances qui étaient distinctes à l'origine.The following example illustrates the case where the reference finds multiple matches that were originally distinct. D’abord, nous démarrons dans tempdb (dont le classement qui respecte la casse est le même que celui de notre instance) et nous exécutons les instructions suivantes.First, we start in tempdb (which has the same case-sensitive collation as our instance) and execute the following statements.

USE tempdb;  
GO  

CREATE TABLE #a(x int);  
GO  
CREATE TABLE #A(x int);  
GO  
INSERT INTO #a VALUES(1);  
GO  
INSERT INTO #A VALUES(2);  
GO  

Ce code réussit, puisque les tables sont distinctes dans ce classement :This succeeds, since the tables are distinct in this collation:

Voici l'ensemble des résultats.Here is the result set.

(1 row(s) affected)  
(1 row(s) affected)  

Si nous nous déplaçons dans notre base de données à relation contenant-contenu, toutefois, nous constatons que nous ne pouvons plus créer de liaison avec ces tables.If we move into our contained database, however, we find that we can no longer bind to these tables.

USE MyCDB;  
GO  
SELECT * FROM #a;  
GO  

Voici l'ensemble des résultats.Here is the result set.

Msg 12800, Niveau 16, État 1, Ligne 2Msg 12800, Level 16, State 1, Line 2

La référence au nom de table temporaire '#a' est ambiguë et ne peut pas être résolue.The reference to temp table name '#a' is ambiguous and cannot be resolved. Les candidats possibles sont '#a' et '#A.'Possible candidates are '#a' and '#A'.

ConclusionConclusion

Le comportement du classement des bases de données à relation contenant-contenu diffère légèrement de celui des bases de données sans relation contenant-contenu.The collation behavior of contained databases differs subtly from that in non-contained databases. Ce comportement est généralement bénéfique, car il apporte une indépendance par rapport à l'instance et de la simplicité.This behavior is generally beneficial, providing instance-independence and simplicity. Certains utilisateurs peuvent avoir des problèmes, en particulier lorsqu'une session accède à la fois à des bases de données avec et sans relation contenant-contenu.Some users may have issues, particularly when a session accesses both contained and non-contained databases.

Voir aussiSee Also

Bases de données à relation contenant-contenuContained Databases