Partekatu honen bidez:


Intercalaciones y páginas de códigos

In-Memory OLTP tiene restricciones en las páginas de códigos compatibles para las columnas (var)char en las tablas optimizadas para memoria y las intercalaciones compatibles usadas en los índices y los procedimientos almacenados compilados nativamente.

La página de códigos de un valor (var)char determina la asignación entre caracteres y la representación de bytes almacenada en la tabla. Por ejemplo, en la página de códigos de Windows Latin 1 (1252), que es el valor predeterminado de SQL Server, el carácter 'a' corresponde al byte 0x61.

La página de códigos de un valor (var)char se determina por la colación asociada al valor. Por ejemplo, la ordenación SQL_Latin1_General_CP1_CI_AS tiene la página de código asociada 1252.

La intercalación de un valor se hereda de la intercalación de la base de datos o se puede especificar explícitamente mediante la palabra clave COLLATE. No se puede cambiar la intercalación de la base de datos si contiene tablas optimizadas para memoria o procedimientos almacenados compilados de forma nativa. En el ejemplo siguiente se establece la intercalación de la base de datos y se crea una tabla, que tiene una columna con una intercalación diferente. La base de datos usa una ordenación latina que no distingue entre mayúsculas y minúsculas.

Los índices solo se pueden crear en columnas de texto si usan una intercalación BIN2. La variable LastName usa la intercalación BIN2. FirstName usa el valor predeterminado de la base de datos, que es CI_AS (no distingue entre mayúsculas y minúsculas y es sensible a acentos).

Importante

No puede usar 'order by' ni 'group by' en columnas de cadena de índice que no usen la intercalación 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  

Las restricciones siguientes se aplican a las tablas optimizadas para memoria y a los procedimientos almacenados compilados de forma nativa:

  • Las columnas (var)char de las tablas optimizadas para memoria deben usar la intercalación de código de página 1252. Esta restricción no se aplica a las columnas n(var)char. El siguiente código recupera todas las collaciones 1252:

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

    Si necesita almacenar caracteres no latinos, use las columnas n(var)char.

  • Los índices de las columnas (n)(var)char solo se pueden especificar usando intercalaciones BIN2 (vea el primer ejemplo). La consulta siguiente recupera todas las intercalaciones BIN2 admitidas:

    -- 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'  
    

    Si accede a la tabla mediante Transact-SQL interpretado, puede usar la palabra clave COLLATE para cambiar la intercalación con expresiones u operaciones de ordenación. Consulte el último ejemplo para obtener un ejemplo de esto.

  • Los procedimientos almacenados compilados de forma nativa no pueden usar parámetros, variables locales ni constantes de cadena de tipo (var)char si la intercalación de la base de datos no es una intercalación del código de página 1252.

  • Todas las expresiones y operaciones de ordenación dentro de procedimientos almacenados compilados de forma nativa deben usar intercalaciones BIN2. La implicación es que todas las operaciones de comparación y ordenación se basan en los puntos de código Unicode de los caracteres (representaciones binarias). Por ejemplo, toda ordenación distingue mayúsculas de minúsculas ("Z" viene antes de "a"). Si es necesario, use Transact-SQL interpretado para la ordenación y comparación sin distinción de mayúsculas y minúsculas.

  • No se admite el truncamiento de datos UTF-16 dentro de procedimientos almacenados compilados de forma nativa. Esto significa que los valores n(var)char(n) no se pueden convertir al tipo n(var)char(i), si i<n, si la intercalación tiene _SC propiedad. Por ejemplo, no se admite lo siguiente:

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

    Las funciones de manipulación de cadenas, como LEN, SUBSTRING, LTRIM y RTRIM con datos UTF-16 no se admiten en procedimientos almacenados compilados de forma nativa. No puede usar estas funciones de manipulación de cadenas para los valores n(var)char que tienen una intercalación de _SC.

    Declare variables con tipos lo suficientemente grandes como para evitar el truncamiento.

En el ejemplo siguiente se muestran algunas de las implicancias y soluciones alternativas para las limitaciones de ordenación en In-Memory OLTP. En el ejemplo se usa la tabla Employees especificada anteriormente. En este ejemplo se enumeran todos los empleados . Observe que para LastName, debido a la intercalación binaria, los nombres en mayúsculas se ordenan antes de minúsculas. Por lo tanto, "Thomas" viene antes de "nolan" porque los caracteres en mayúsculas tienen puntos de código inferiores. FirstName tiene una ordenación que no distingue mayúsculas de minúsculas. Por lo tanto, la ordenación es por letra del alfabeto, no por punto de código de los caracteres.

-- 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'  

Véase también

In-Memory OLTP ( optimización deIn-Memory)