Condividi tramite


Collationi e pagine di codice

In-Memory OLTP presenta restrizioni sulle pagine codici supportate per le colonne di tipo char o varchar nelle tabelle ottimizzate per l'uso della memoria e sulle regole di confronto supportate usate negli indici e nelle stored procedure compilate in modo nativo.

La pagina dei codici per un valore (var)char determina il mapping tra i caratteri e la rappresentazione in byte archiviata nella tabella. Ad esempio, con la tabella codici di Windows Latin 1 (1252; l'impostazione predefinita di SQL Server), il carattere 'a' corrisponde al byte 0x61.

La tabella codici di un valore (var)char è determinata dalla collazione associata al valore. Ad esempio, le regole di confronto SQL_Latin1_General_CP1_CI_AS hanno la pagina codice associata 1252.

Le regole di confronto di un valore vengono ereditate dalle regole di confronto del database oppure possono essere specificate in modo esplicito usando la parola chiave COLLATE. Le regole di confronto del database non possono essere modificate se il database contiene tabelle ottimizzate per la memoria o stored procedure compilate in modo nativo. Nell'esempio seguente vengono impostate le regole di confronto del database e viene creata una tabella con una colonna con regole di confronto diverse. Il database usa regole di confronto senza distinzione tra maiuscole e minuscole latine.

Gli indici possono essere creati solo nelle colonne stringa se usano regole di confronto BIN2. La variabile LastName usa le regole di confronto BIN2. FirstName usa l'impostazione predefinita del database, che è CI_AS (senza distinzione tra maiuscole e minuscole e distinzione tra caratteri accentati).

Importante

Non è possibile utilizzare order by o group by nelle colonne di stringa di indice che non usano regole di confronto BIN2.

CREATE DATABASE IMOLTP  
  
ALTER DATABASE IMOLTP ADD FILEGROUP IMOLTP_mod CONTAINS MEMORY_OPTIMIZED_DATA  
ALTER DATABASE IMOLTP ADD FILE( NAME = 'IMOLTP_mod' , FILENAME = 'c:\data\IMOLTP_mod') TO FILEGROUP IMOLTP_mod;  
--GO  
  
--  set the database collations  
ALTER DATABASE IMOLTP COLLATE Latin1_General_100_CI_AS  
GO  
  
--  
USE IMOLTP   
GO  
  
-- create a table with collation  
CREATE TABLE Employees (  
  EmployeeID int NOT NULL ,   
  LastName nvarchar(20) COLLATE Latin1_General_100_BIN2 NOT NULL INDEX IX_LastName NONCLUSTERED,   
  FirstName nvarchar(10) NOT NULL ,  
  CONSTRAINT PK_Employees PRIMARY KEY NONCLUSTERED HASH(EmployeeID)  WITH (BUCKET_COUNT=1024)  
) WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_AND_DATA)  
GO  

Le restrizioni seguenti si applicano alle tabelle ottimizzate per la memoria e alle stored procedure compilate in modo nativo:

  • Le colonne (var)char nelle tabelle ottimizzate per la memoria devono usare la collazione pagina codice 1252. Questa restrizione non si applica alle colonne n(var)char. Il codice seguente recupera tutte le 1252 regole di confronto:

    -- all supported collations for (var)char columns in memory-optimized tables  
    select * from sys.fn_helpcollations()  
    where collationproperty(name, 'codepage') = 1252;  
    

    Se è necessario archiviare caratteri non latini, usare le colonne n(var)char.

  • Gli indici nelle colonne (n)(var)char possono essere specificati solo con regole di confronto BIN2 (vedere il primo esempio). La query seguente recupera tutte le regole di confronto BIN2 supportate:

    -- all supported collations for indexes on memory-optimized tables and   
    -- comparison/sorting in natively compiled stored procedures  
    select * from sys.fn_helpcollations() where name like '%BIN2'  
    

    Se si accede alla tabella tramite Transact-SQL interpretato, è possibile usare la COLLATE parola chiave per modificare le regole di confronto con espressioni o operazioni di ordinamento. Per un esempio di questo esempio, vedere l'ultimo esempio.

  • Le stored procedure compilate in modo nativo non possono usare parametri, variabili locali o costanti stringa di tipo (var)char se la collatione del database non è di codice pagina 1252.

  • Tutte le espressioni e le operazioni di ordinamento all'interno di stored procedure compilate in modo nativo devono usare regole di confronto BIN2. L'implicazione è che tutti i confronti e le operazioni di ordinamento si basano sui punti di codice Unicode dei caratteri (rappresentazioni binarie). Ad esempio, l'ordinamento fa distinzione tra maiuscole e minuscole ('Z' precede 'a'). Se necessario, utilizzare Transact-SQL interpretato per confronto e ordinamento senza distinzione tra maiuscole e minuscole.

  • Il troncamento dei dati UTF-16 non è supportato all'interno di stored procedure compilate in modo nativo. Ciò significa che i valori n(var)char(n) non possono essere convertiti in tipo n(var)char(i), se i<n, se le regole di confronto hanno _SC proprietà. Ad esempio, il codice seguente non è supportato:

    -- column definition using an _SC collation  
     c2 nvarchar(200) collate Latin1_General_100_CS_AS_SC not null   
    -- assignment to a smaller variable, requiring truncation  
     declare @c2 nvarchar(100) = '';  
     select @c2 = c2  
    

    Le funzioni di manipolazione delle stringhe, ad esempio LEN, SUBSTRING, LTRIM e RTRIM con dati UTF-16, non sono supportate all'interno di stored procedure compilate in modo nativo. Non è possibile usare queste funzioni di manipolazione delle stringhe per i valori n(var)char con regole di confronto _SC.

    Dichiarare le variabili usando tipi di dimensioni sufficienti per evitare il troncamento.

L'esempio seguente illustra alcune implicazioni e soluzioni alternative per le limitazioni delle regole di confronto in In-Memory OLTP. Nell'esempio viene utilizzata la tabella Employees specificata in precedenza. Questo esempio elenca tutti i dipendenti . Si noti che per LastName, a causa delle regole di confronto binarie, i nomi maiuscoli vengono ordinati prima delle lettere minuscole. Pertanto, 'Thomas' precede 'nolan' perché i caratteri maiuscoli hanno punti di codice inferiori. Il campo FirstName utilizza una collation senza distinzione tra maiuscole e minuscole. Quindi, l'ordinamento è in base alla lettera dell'alfabeto, non al punto di codice dei caratteri.

-- insert a number of values  
INSERT Employees VALUES (1,'thomas', 'john')  
INSERT Employees VALUES (2,'Thomas', 'rupert')  
INSERT Employees VALUES (3,'Thomas', 'Jack')  
INSERT Employees VALUES (4,'Thomas', 'annie')  
INSERT Employees VALUES (5,'nolan', 'John')  
GO  
  
-- ===========  
SELECT EmployeeID, LastName, FirstName FROM Employees  
ORDER BY LastName, FirstName  
GO  
  
-- ===========  
-- specify collation: sorting uses case-insensitive collation, thus 'nolan' comes before 'Thomas'  
SELECT * FROM Employees  
ORDER BY LastName COLLATE Latin1_General_100_CI_AS, FirstName  
GO  
  
-- ===========  
-- retrieve employee by Name  
-- must use BIN2 collation for comparison in natively compiled stored procedures  
CREATE PROCEDURE usp_EmployeeByName @LastName nvarchar(20), @FirstName nvarchar(10)  
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER  
AS BEGIN ATOMIC WITH   
(  TRANSACTION ISOLATION LEVEL = SNAPSHOT,  
  LANGUAGE = N'us_english'  
)  
  SELECT EmployeeID, LastName, FirstName FROM dbo.Employees  
  WHERE   
    LastName = @LastName AND  
    FirstName COLLATE Latin1_General_100_BIN2 = @FirstName  
  
END  
GO  
  
-- this does not return any rows, as EmployeeID 1 has first name 'john', which is not equal to 'John' in a binary collation  
EXEC usp_EmployeeByName 'thomas', 'John'  
  
-- this retrieves EmployeeID 1  
EXEC usp_EmployeeByName 'thomas', 'john'  

Vedere anche

OLTP in memoria (ottimizzazione in memoria)