Freigeben über


Sortierungen und Codeseiten

In-Memory OLTP hat Einschränkungen für unterstützte Codeseiten für (Var)Char-Spalten in speicheroptimierten Tabellen und unterstützte Sortierungen, die in Indizes und nativ kompilierten gespeicherten Prozeduren verwendet werden.

Die Codepage für einen (var)char-Wert bestimmt die Zuordnung zwischen Zeichen und der Bytedarstellung, die in der Tabelle gespeichert ist. Beispielsweise entspricht das Zeichen "a" mit der Windows-Latin-1-Codeseite (1252; der SQL Server-Standardeinstellung) dem Byte 0x61.

Die Codepage eines (var)char-Werts wird durch die Sortierung bestimmt, die dem Wert zugeordnet ist. Die Sortierung SQL_Latin1_General_CP1_CI_AS verfügt beispielsweise über die zugeordnete Codepage 1252.

Die Sortierung eines Werts wird entweder von der Datenbanksortierung geerbt oder kann explizit mithilfe des COLLATE-Schlüsselworts angegeben werden. Die Datenbanksortierung kann nicht geändert werden, wenn die Datenbank speicheroptimierte Tabellen oder nativ kompilierte gespeicherte Prozeduren enthält. Im folgenden Beispiel wird die Datenbanksortierung festgelegt und eine Tabelle erstellt, die eine Spalte mit einer anderen Sortierung aufweist. Die Datenbank verwendet eine lateinische, nicht auf Groß- und Kleinschreibung achtende Sortierung.

Indizes können nur für Zeichenfolgenspalten erstellt werden, wenn sie eine BIN2-Sortierung verwenden. Die Variable "LastName" verwendet BIN2-Sortierung. FirstName verwendet den Datenbankstandard CI_AS (unabhängig von Groß-/Kleinschreibung, akzentsensitiv).

Von Bedeutung

Sie können ORDER BY oder GROUP BY nicht für Indexzeichenfolgenspalten verwenden, die keine BIN2-Sortierung verwenden.

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  

Die folgenden Einschränkungen gelten für speicheroptimierte Tabellen und systemeigene kompilierte gespeicherte Prozeduren:

  • (var)char-Spalten in speicheroptimierten Tabellen müssen die Kollation der Codepage 1252 verwenden. Diese Einschränkung gilt nicht für n(var)char-Spalten. Der folgende Code ruft alle 1252-Kollationen ab.

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

    Wenn Sie nicht lateinische Zeichen speichern müssen, verwenden Sie n(var)char-Spalten.

  • Indizes für (n)(var)char-Spalten können nur mit BIN2-Sortierungen angegeben werden (siehe erstes Beispiel). Die folgende Abfrage ruft alle unterstützten BIN2-Sortierungen ab:

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

    Wenn Sie über interpretierte Transact-SQL auf die Tabelle zugreifen, können Sie das COLLATE Schlüsselwort verwenden, um die Sortierung mit Ausdrücken oder Sortiervorgängen zu ändern. Ein Beispiel hierfür finden Sie im letzten Beispiel.

  • Nativ kompilierte gespeicherte Prozeduren können keine Parameter, lokalen Variablen oder Zeichenfolgenkonstanten vom Typ (var)char verwenden, wenn die Datenbanksortierung keine Codepage 1252-Sortierung ist.

  • Alle Ausdrücke und Sortiervorgänge in nativ kompilierten gespeicherten Prozeduren müssen BIN2-Kollationen verwenden. Die Auswirkung besteht darin, dass alle Vergleichs- und Sortiervorgänge auf den Unicode-Codepunkten der Zeichen (binäre Darstellungen) basieren. Bei allen Sortierungen wird beispielsweise die Groß-/Kleinschreibung beachtet ('Z' kommt vor 'a'). Verwenden Sie bei Bedarf Transact-SQL im interpretierenden Modus für Sortierung und Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung.

  • Das Abschneiden von UTF-16-Daten wird in nativ kompilierten gespeicherten Prozeduren nicht unterstützt. Dies bedeutet, dass n(var)char(n)-Werte nicht in Typ n(var)char(i) konvertiert werden können, wenn i<n, wenn die Sortierung _SC Eigenschaft aufweist. Beispielsweise wird Folgendes nicht unterstützt:

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

    Zeichenfolgenmanipulationsfunktionen wie LEN, SUBSTRING, LTRIM und RTRIM mit UTF-16-Daten werden in nativ kompilierten gespeicherten Prozeduren nicht unterstützt. Sie können diese Zeichenfolgenbearbeitungsfunktionen nicht für n(var)char-Werte verwenden, die eine _SC Sortierung aufweisen.

    Deklarieren Sie Variablen mithilfe von Typen, die groß genug sind, um eine Abkürzung zu vermeiden.

Das folgende Beispiel zeigt einige der Auswirkungen und Problemumgehungen für die Sortierungseinschränkungen in In-Memory OLTP. Im Beispiel wird die oben angegebene Tabelle "Employees" verwendet. In diesem Beispiel werden alle Mitarbeiter aufgeführt. Bitte beachten Sie, dass durch die binäre Sortierung beim Nachnamen die Großbuchstaben vor den Kleinbuchstaben sortiert werden. Daher kommt "Thomas" vor "nolan", da Großbuchstaben niedrigere Codepunkte aufweisen. FirstName weist eine Sortierung ohne Groß-/Kleinschreibung auf. Die Sortierung erfolgt also nach Buchstaben des Alphabets, nicht nach Codepunkt der Zeichen.

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

Siehe auch

In-Memory OLTP (In-Memory-Optimierung)