Regole di confronto dei database indipendentiContained Database Collations

Varie proprietà incidono sull'ordinamento e sulla semantica di uguaglianza dei dati testuali, ad esempio distinzione maiuscole/minuscole, distinzione caratteri accentati/non accentati e linguaggio di base utilizzato.Various properties affect the sort order and equality semantics of textual data, including case sensitivity, accent sensitivity, and the base language being used. Queste qualità vengono espresse in SQL ServerSQL Server tramite la scelta di regole di confronto per i dati.These qualities are expressed to SQL ServerSQL Server through the choice of collation for the data. Per informazioni dettagliate sulle regole di confronto, vedere Regole di confronto e supporto Unicode.For a more in-depth discussion of collations themselves, see Collation and Unicode Support.

Le regole di confronto si applicano non solo ai dati archiviati nelle tabelle utente, ma a tutto il testo gestito da SQL ServerSQL Server, inclusi metadati, oggetti temporanei, nomi di variabili e così via. La gestione di tali elementi risulta diversa nei database indipendenti rispetto a quelli non indipendenti.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. Questa modifica non interesserà molti utenti, ma contribuirà ad assicurare uniformità e indipendenza dell'istanza.This change will not affect many users, but helps provide instance independence and uniformity. È tuttavia possibile che sia anche causa di qualche confusione, nonché di problemi per le sessioni che accedono sia a database indipendenti che non indipendenti.But this may also cause some confusion, as well as problems for sessions that access both contained and non-contained databases.

In questo argomento si illustra il contenuto della modifica e si esaminano alcune aree in cui tale modifica potrebbe causare problemi.This topic clarifies the content of the change, and examines areas where the change may cause problems.

Database non indipendentiNon-Contained Databases

A tutti i database sono associate regole di confronto predefinite, che possono essere impostate quando si crea o si modifica un database.All databases have a default collation (which can be set when creating or altering a database. Queste regole di confronto vengono utilizzate per tutti i metadati presenti nel database e come impostazione predefinita per tutte le colonne stringa all'interno del database.This collation is used for all metadata in the database, as well as the default for all string columns within the database. Gli utenti possono scegliere regole di confronto diverse per qualsiasi colonna specifica usando la clausola COLLATE .Users can choose a different collation for any particular column by using the COLLATE clause.

Esempio 1Example 1

Se si lavora ad esempio a Pechino, è possibile che venga utilizzata una regola di confronto cinese:For example, if we were working in Beijing, we might use a Chinese collation:

ALTER DATABASE MyDB COLLATE Chinese_Simplified_Pinyin_100_CI_AS;  

Se ora si crea una colonna, le relative regole di confronto predefinite saranno quelle cinesi, ma è possibile sceglierne altre, se lo si desidera: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  

Set di risultati:Here is the result set.

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

Questo approccio sembra relativamente semplice, ma insorgono vari problemi.This appears relatively simple, but several problems arise. Poiché le regole di confronto per una colonna sono dipendenti dal database nel quale viene creata la tabella, i problemi insorgono se si usano tabelle temporanee archiviate in 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 regole di confronto di tempdb corrispondono solitamente a quelle dell'istanza, che non devono corrispondere alle regole di confronto del database.The collation of tempdb usually matches the collation for the instance, which does not have to match the database collation.

Esempio 2Example 2

Si consideri, ad esempio, il database precedente (cinese) usato in un'istanza con regole di confronto 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  

A prima vista queste due tabelle hanno apparentemente lo stesso schema, ma poiché le regole di confronto dei database sono diverse, i valori sono in effetti incompatibili: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  

Set di risultati:Here is the result set.

Messaggio 468, livello 16, stato 9, riga 2Msg 468, Level 16, State 9, Line 2

Impossibile risolvere il conflitto tra le regole di confronto "Latin1_General_100_CI_AS_KS_WS_SC" e "Chinese_Simplified_Pinyin_100_CI_AS" nell'operazione uguale a.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.

Per correggere questo problema è necessario confrontare esplicitamente la tabella temporanea.We can fix this by explicitly collating the temporary table. SQL ServerSQL Server questa operazione è resa più semplice perché viene fornita la parola chiave DATABASE_DEFAULT per la clausola 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 ;  

A questo punto l'esecuzione avviene senza errori.This now runs without error.

Il comportamento dipendente dalle regole di confronto è rilevabile anche con le variabili.We can also see collation-dependent behavior with variables. Si consideri la funzione seguente:Consider the following function:

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

Si tratta di una funzione piuttosto particolare.This is a rather peculiar function. Nelle regole di confronto con distinzione tra maiuscole e minuscole, @i nella clausola RETURN non può essere associato a @I o @İ.In a case-sensitive collation, the @i in the return clause cannot bind to either @I or @İ. Nelle regole di confronto Latin1_General senza distinzione tra maiuscole e minuscole, @i viene associato a @I e la funzione restituisce 1.In a case-insensitive Latin1_General collation, @i binds to @I, and the function returns 1. Tuttavia, nelle regole di confronto Turkish senza distinzione tra maiuscole e minuscole, @i viene associato a @I e la funzione restituisce 2.But in a case-insensitive Turkish collation, @i binds to @İ, and the function returns 2. Questa funzione può causare seri problemi in un database che passa da un'istanza all'altra con regole di confronto diverse.This can wreak havoc on a database that moves between instances with different collations.

Database indipendentiContained Databases

Poiché uno degli obiettivi di progettazione dei database indipendenti è di renderli autosufficienti, è necessario eliminare la dipendenza dalle regole di confronto di istanza e tempdb .Since a design objective of contained databases is to make them self-contained, the dependence on the instance and tempdb collations must be severed. A questo scopo, nei database indipendenti viene introdotto il concetto di regole di confronto del catalogo.To do this, contained databases introduce the concept of the catalog collation. Tali regole vengono utilizzate per metadati di sistema e oggetti temporanei.The catalog collation is used for system metadata and transient objects. Di seguito vengono illustrati i dettagli.Details are provided below.

In un database indipendente vengono usate le regole di confronto del catalogo Latin1_General_100_CI_AS_WS_KS_SC.In a contained database, the catalog collation Latin1_General_100_CI_AS_WS_KS_SC. Si tratta delle stesse regole di confronto per tutti i database indipendenti in tutte le istanze di SQL ServerSQL Server e non è possibile modificarle.This collation is the same for all contained databases on all instances of SQL ServerSQL Server and cannot be changed.

Le regole di confronto del database vengono mantenute, ma utilizzate solo come regole di confronto predefinite per i dati utente.The database collation is retained, but is only used as the default collation for user data. Per impostazione predefinita, le regole di confronto del database sono uguali a quelle del modello, ma possono essere modificate dall'utente tramite un comando CREATE o ALTER DATABASE come con i database non indipendenti.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.

Nella clausola COLLATEè disponibile una nuova parola chiave, CATALOG_DEFAULT .A new keyword, CATALOG_DEFAULT, is available in the COLLATE clause. che viene utilizzata come collegamento alle regole di confronto correnti per i metadati nei database indipendenti e non indipendenti.This is used as a shortcut to the current collation of metadata in both contained and non-contained databases. Vale a dire che, in un database non indipendente, la parola chiave CATALOG_DEFAULT restituirà le regole di confronto del database correnti, poiché i metadati vengono confrontati nelle regole di confronto del database.That is, in a non-contained database, CATALOG_DEFAULT will return the current database collation, since metadata is collated in the database collation. In un database indipendente questi due valori potrebbero essere diversi, in quanto l'utente può modificare le regole di confronto del database in modo che non corrispondano alle regole di confronto del catalogo.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.

Nella tabella seguente viene riepilogato il comportamento di vari oggetti sia nei database non indipendenti che in quelli indipendenti:The behavior of various objects in both non-contained and contained databases is summarized in this table:

ElementoItem Database non indipendenteNon-Contained Database Database indipendenteContained Database
Dati utente (impostazione predefinita)User Data (default) DATABASE_DEFAULTDATABASE_DEFAULT DATABASE_DEFAULTDATABASE_DEFAULT
Dati temporanei (impostazione predefinita)Temp Data (default) Regole di confronto TempDBTempDB Collation DATABASE_DEFAULTDATABASE_DEFAULT
MetadatiMetadata DATABASE_DEFAULT/CATALOG_DEFAULTDATABASE_DEFAULT / CATALOG_DEFAULT COLLATECATALOG_DEFAULT
Metadati temporaneiTemporary Metadata Regole di confronto TempDBtempdb Collation COLLATECATALOG_DEFAULT
VariabiliVariables Regole di confronto di istanzaInstance Collation COLLATECATALOG_DEFAULT
Etichette GotoGoto Labels Regole di confronto di istanzaInstance Collation COLLATECATALOG_DEFAULT
Nomi di cursoriCursor Names Regole di confronto di istanzaInstance Collation COLLATECATALOG_DEFAULT

Se si usa una tabella temporanea nell'esempio precedentemente descritto, è possibile osservare che questo comportamento delle regole di confronto elimina l'esigenza di una clausola COLLATE esplicita nella maggior parte degli usi delle tabelle temporanee.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. In un database indipendente questo codice ora viene eseguito senza errori, anche se le regole di confronto di database e istanza sono diverse: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 ;  

Il codice funziona perché il confronto di T1_txt e di T2_txt viene effettuato nelle regole di confronto del database relative al database indipendente.This works because both T1_txt and T2_txt are collated in the database collation of the contained database.

Passaggio tra contesti indipendenti e non indipendentiCrossing Between Contained and Uncontained Contexts

Finché una sessione in un database indipendente rimane indipendente, dovrà rimanere all'interno del database al quale è connessa.As long as a session in a contained database remains contained, it must remain within the database to which it connected. In questo caso il comportamento è molto chiaro.In this case the behavior is very straightforward. Se, tuttavia, avviene il passaggio di una sessione tra contesti indipendenti e non indipendenti, il comportamento diventa più complesso, poiché è necessario creare un collegamento tra i due set di regole.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. Questa condizione può verificarsi in un database parzialmente indipendente, poiché un utente può usare USE su un altro database.This can happen in a partially-contained database, since a user may USE to another database. In questo caso, la differenza nelle regole di confronto viene gestita in base al principio seguente.In this case, the difference in collation rules is handled by the following principle.

  • Il comportamento delle regole di confronto per un batch viene determinato dal database in cui inizia il batch.The collation behavior for a batch is determined by the database in which the batch begins.

    Si noti che questa decisione avviene prima dell'esecuzione di qualsiasi comando, incluso un comando USEiniziale.Note that this decision is made before any commands are issued, including an initial USE. Ciò significa che se un batch inizia in un database indipendente, ma il primo comando è USE su un database non indipendente, per il batch verrà comunque usato il comportamento delle regole di confronto indipendenti.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. In questo caso, un riferimento a una variabile, ad esempio, può avere più risultati possibili:Given this, a reference to a variable, for example, may have multiple possible outcomes:

  • Il riferimento può trovare esattamente una corrispondenza.The reference may find exactly one match. In questo caso il riferimento funzionerà senza errori.In this case, the reference will work without error.

  • Il riferimento può non trovare una corrispondenza nelle regole di confronto correnti dove in precedenza ne era presente una.The reference may not find a match in the current collation where there was one before. In questo caso verrà generato un errore nel quale è indicato che la variabile non esiste, anche se apparentemente è stata creata.This will raise an error indicating that the variable does not exist, even though it was apparently created.

  • Il riferimento più trovare più corrispondenze originariamente distinte.The reference may find multiple matches that were originally distinct. Anche in questo caso verrà generato un errore.This will also raise an error.

    Di seguito vengono utilizzati alcuni esempi per illustrare questo comportamento,We’ll illustrate this with a few examples. presupponendo l'uso di un database parzialmente indipendente, denominato MyCDB , con regole di confronto del database impostate sulle regole di confronto predefinite 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. Si supponga che le regole di confronto dell'istanza siano Latin1_General_100_CS_AS_WS_KS_SC.We assume that the instance collation is Latin1_General_100_CS_AS_WS_KS_SC. la sola differenza tra le due regole di confronto riguarda la distinzione tra maiuscole e minuscole.The two collations differ only in case sensitivity.

Esempio 1Example 1

Nell'esempio seguente viene illustrato il caso in cui il riferimento trova esattamente una corrispondenza.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:  

Set di risultati:Here is the result set.

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

In questo caso, il risultato #a identificato viene associato sia nelle regole di confronto del catalogo senza distinzione tra maiuscole e minuscole che nelle regole di confronto di istanza con distinzione tra maiuscole e minuscole e il codice funziona correttamente.In this case, the identified #a binds in both the case-insensitive catalog collation and the case-sensitive instance collation, and the code works.

Esempio 2Example 2

Nell'esempio seguente viene illustrato il caso in cui il riferimento non trova una corrispondenza nelle regole di confronto correnti dove in precedenza ne era presente una.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  

In questo caso #A viene associato ad #a nelle regole di confronto predefinite senza distinzione tra maiuscole e minuscole e l'inserimento funziona:Here, the #A binds to #a in the case-insensitive default collation, and the insert works,

Set di risultati:Here is the result set.

(1 row(s) affected)  

Se tuttavia si continua lo script...But if we continue the script...

USE master;  
GO  

SELECT * FROM #A;  
GO  

il tentativo di associazione ad #A nelle regole di confronto di istanza con distinzione tra maiuscole e minuscole restituisce un errore:We get an error trying to bind to #A in the case-sensitive instance collation;

Set di risultati:Here is the result set.

Messaggio 208, livello 16, stato 0, riga 2Msg 208, Level 16, State 0, Line 2

Il nome di oggetto '#A' non è valido.Invalid object name '#A'.

Esempio 3Example 3

Nell'esempio seguente viene illustrato il caso in cui il riferimento trova più corrispondenze originariamente distinte.The following example illustrates the case where the reference finds multiple matches that were originally distinct. Si inizierà innanzitutto in tempdb (per cui sono valide le stesse regole di confronto con distinzione tra maiuscole e minuscole dell'istanza) e verranno eseguite le istruzioni seguenti.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  

L'esito è positivo poiché in queste regole di confronto le tabelle sono distinte:This succeeds, since the tables are distinct in this collation:

Set di risultati:Here is the result set.

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

Se si passa al database indipendente, si noterà tuttavia che l'associazione a queste tabelle non è più possibile.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  

Set di risultati:Here is the result set.

Messaggio 12800, livello 16, stato 1, riga 2Msg 12800, Level 16, State 1, Line 2

Il riferimento al nome della tabella temporanea '#a' è ambiguo e non può essere risolto.The reference to temp table name '#a' is ambiguous and cannot be resolved. I possibili candidati sono '#a' e '#A'.Possible candidates are '#a' and '#A'.

ConclusioniConclusion

Il comportamento delle regole di confronto dei database indipendenti è leggermente diverso da quello nei database non indipendenti.The collation behavior of contained databases differs subtly from that in non-contained databases. Questo comportamento è generalmente utile, in quanto consente l'indipendenza dell'istanza e favorisce la semplicità.This behavior is generally beneficial, providing instance-independence and simplicity. È possibile che alcuni utenti riscontrino problemi, specialmente quando una sessione accede a database indipendenti e non indipendenti.Some users may have issues, particularly when a session accesses both contained and non-contained databases.

Vedere ancheSee Also

Database indipendentiContained Databases