Поделиться через


Параметры сортировки автономной базы данных

Область применения: SQL Server Управляемый экземпляр SQL Azure

На порядок сортировки и семантику сравнения текстовых данных влияют различные свойства, в том числе учет регистра, учет диакритических знаков и используемый базовый язык. Эти качества выражаются в SQL Server с помощью выбора сортировки данных. Более подробное обсуждение самих настроек сортировки см. в разделе Поддержка сортировки и Юникода.

Параметры сортировки применяются не только к данным, хранящимся в пользовательских таблицах, но и ко всем текстам, обрабатываемым SQL Server, включая метаданные, временные объекты, имена переменных и т. д. Обработка этих баз данных отличается от содержащихся и не содержащихся баз данных. Это изменение не влияет на многих пользователей, но помогает обеспечить независимость экземпляров и единообразие. Но это также может привести к некоторой путанице и проблемам для сеансов, которые обращаются как к содержащимся, так и несодержащимся базам данных.

Поведение сортировки включённых баз данных отличается от поведения в не включённых базах данных. В целом эти изменения упрощают работу и обеспечивают независимость от экземпляра. У некоторых пользователей могут возникнуть проблемы, особенно если сеанс обращается как к содержащимся, так и не содержащимся базам данных.

В этой статье объясняется содержимое изменения и рассматриваются области, в которых изменение может вызвать проблемы.

Примечание.

Для База данных SQL Azure параметры сортировки для содержащихся баз данных отличаются. Параметры сортировки базы данных и параметры сортировки каталога можно задать при создании базы данных и не могут быть обновлены. Укажите параметры сортировки для данных (COLLATE) и параметры сортировки каталога для системных метаданных и идентификаторов объектов (CATALOG_COLLATION). Дополнительные сведения см. в статье CREATE DATABASE (SQL Server Transact-SQL).

Не содержащиеся базы данных

Все базы данных имеют параметры сортировки по умолчанию (которые можно задать при создании или изменении базы данных). Этот параметр сортировки используется для всех метаданных в базе данных и по умолчанию для всех строковых столбцов в базе данных. Пользователи могут выбрать другие параметры сортировки для любого столбца с помощью предложения COLLATE.

Пример 1

Например, для работы в Пекине можно использовать параметры сортировки китайского языка:

ALTER DATABASE MyDB
    COLLATE Chinese_Simplified_Pinyin_100_CI_AS;

Теперь, если мы создадим столбец, его параметры сортировки по умолчанию — это китайская сортировка, но мы можем выбрать другой, если мы хотим:

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

Вот результирующий набор.

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

Это выглядит довольно простым, однако возникают некоторые проблемы. Так как параметры сортировки для столбца зависят от базы данных, в которой создается таблица, возникают проблемы с использованием временных таблиц, хранящихся в tempdb. Правила сортировки tempdb обычно соответствуют правилам сортировки экземпляра, но они не обязаны совпадать с правилами сортировки базы данных.

Пример 2

Например, рассмотрим ранее показанную (китайскую) базу данных, когда она используется в экземпляре с параметрами сортировки Latin1_General.

CREATE TABLE T1 (T1_txt NVARCHAR (MAX));
GO

CREATE TABLE #T2 (T2_txt NVARCHAR (MAX));
GO

На первый взгляд эти две таблицы выглядят так же, как они имеют одну схему, но так как параметры сортировки баз данных отличаются, значения несовместимы:

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

Вот результирующий набор.

Сообщение 468, уровень 16, состояние 9, строка 2

Не удается устранить конфликт сортировки между "Latin1_General_100_CI_AS_KS_WS_SC" и "Chinese_Simplified_Pinyin_100_CI_AS" в операции равенства.

Чтобы исправить эту проблему, можно явно задать параметры сортировки временной таблицы. SQL Server упрощает это, указав ключевое DATABASE_DEFAULT слово для COLLATE предложения.

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
     INNER JOIN #T2
         ON T1.T1_txt = #T2.T2_txt;

Этот запрос выполняется без ошибок.

Различия параметров сортировки также проявляются в обработке переменных. Рассмотрим следующую функцию:

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

Это довольно необычная функция. В случае сортировки с учетом регистра выражение @i не может привязаться ни к одному из @I или . В нечувствительном регистре Latin1_General сортировки, @i привязывается к @Iфункции и возвращается 1функция. Но в нечувствительном турецком параметров сортировки, @i привязывается к , а функция возвращает 2. Это может негативно отразиться на базе данных, которая перемещается между экземплярами с различными параметрами сортировки.

Контейнеризованные базы данных

Поскольку задачей проектирования автономных баз данных является обеспечение их независимости, необходимо исключить зависимость от параметров сортировки экземпляра и базы данных tempdb. Для этого в автономных базах данных реализовано основное понятие параметров сортировки каталога. Параметры сортировки каталога используются для метаданных системы и временных объектов. Ниже приведены сведения.

В изолированной базе данных сортировка каталога — Latin1_General_100_CI_AS_WS_KS_SC. Этот параметр сортировки одинаков для всех содержащихся баз данных во всех экземплярах SQL Server и не может быть изменен.

Параметры сортировки базы данных сохраняются, но используются только в качестве параметров сортировки по умолчанию для пользовательских данных. По умолчанию параметры сортировки базы данных равны model параметрам сортировки базы данных, но могут быть изменены пользователем с помощью CREATE команды или ALTER DATABASE команды, как и не содержащиеся в ней базы данных.

В предложении CATALOG_DEFAULT доступно новое ключевое слово COLLATE. Оно служит ярлыком для текущих параметров сортировки метаданных и в автономных и в неавтономных базах данных. То есть в незаключенной базе данных CATALOG_DEFAULT возвращает текущий порядок сортировки базы данных, так как метаданные сопоставляются в порядке сортировки базы данных. В автономной базе данных эти два значения могут отличаться, так как пользователь может изменить параметры сортировки базы данных, чтобы он не соответствовал параметрам сортировки каталога.

В данной таблице представлен порядок обработки различных объектов в автономных и неавтономных базах данных.

Товар Ненезависимая база данных Содержащаяся база данных
Пользовательские данные (по умолчанию) DATABASE_DEFAULT DATABASE_DEFAULT
Временные данные (по умолчанию) tempdb сортировка DATABASE_DEFAULT
Метаданные DATABASE_DEFAULT / CATALOG_DEFAULT CATALOG_DEFAULT
Временные метаданные tempdb сопоставление CATALOG_DEFAULT
Переменные Сортировка экземпляров CATALOG_DEFAULT
Метки Goto Сортировка экземпляров CATALOG_DEFAULT
Имена курсоров Сопоставление экземпляров CATALOG_DEFAULT

В приведенном ранее примере временной таблицы видно, что это поведение сортировки устраняет необходимость явного COLLATE предложения в большинстве временных таблиц. В автономной базе данных этот код теперь работает без ошибок, даже в случае, когда параметры сортировки различаются для базы данных и для экземпляра.

CREATE TABLE T1 (T1_txt NVARCHAR (MAX));
GO

CREATE TABLE #T2 (T2_txt NVARCHAR (MAX));
GO

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

Этот запрос работает, поскольку и T1_txt, и T2_txt учитываются в сортировке содержащей базы данных.

Взаимодействие между изолированными и неизолированными контекстами

Пока сеанс в автономной базе данных остается автономным, он должен оставаться в пределах базы данных, с которой установлено соединение. В этом случае поведение является простым. Однако если сеанс переходит между автономными и неавтономными контекстами, то его обработка усложняется, поскольку требуется организовать связь между двумя наборами правил. Это может произойти в частично изолированной базе данных, так как пользователь может USE использовать другую базу данных. В этом случае различия в правилах параметров сортировки обрабатываются следующим образом.

  • Правило параметров сортировки для пакета определяется базой данных, в которой начинается пакет.

Это решение принимается до выдачи каких-либо команд, включая начальное USE. То есть, если пакет начинается в содержащей базе данных, но первая команда — USE в несодержащейся базе данных, то для пакета по-прежнему используется содержащее поведение сортировки. Учитывая этот сценарий, ссылка на переменную может иметь несколько возможных результатов:

  • Ссылка может обнаружить ровно одно совпадение. В этом случае ссылка работает без ошибок.

  • Ссылка может не найти совпадение в текущей сортировке данных, где раньше было совпадение. При этом возникает ошибка, указывающая на то, что переменная не существует, даже если она была создана.

  • Ссылка может найти несколько совпадений, которые изначально были различными. Это также вызывает ошибку.

Иллюстрируем это с помощью нескольких примеров. В данном случае предполагается наличие частично вложенной базы данных, в которой параметр сортировки базы данных MyCDB установлен по умолчанию Latin1_General_100_CI_AS_WS_KS_SC. Предположим, что параметры сортировки экземпляра являются Latin1_General_100_CS_AS_WS_KS_SC. Таким образом, два набора параметров сортировки различаются только учетом регистра.

Пример 1

В следующем примере показан вариант, где ссылка обнаруживает ровно одно совпадение.

USE MyCDB;
GO

CREATE TABLE #a (x INT);

INSERT INTO #a VALUES (1);
GO

USE master;
GO

SELECT * FROM #a;
GO

Results:

Вот результирующий набор.

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

В данном случае конструкция #a привязывается к параметрам сортировки каталога (без учета регистра) и к параметрам сортировки экземпляра (с учетом регистра) и код работает.

Пример 2

В следующем примере показано, что ссылка не находит совпадения в текущей сортировке, там, где ранее было совпадение.

USE MyCDB;
GO

CREATE TABLE #a (x INT);

INSERT INTO #A VALUES (1);
GO

#A Здесь привязка к #a нечувствительной сортировке регистра по умолчанию, а также работает вставка.

Вот результирующий набор.

(1 row(s) affected)

Однако если работа скрипта продолжается...

USE master;
GO

SELECT * FROM #A;
GO

Мы получаем ошибку, пытающуюся привязаться к #A параметрам сортировки экземпляра с учетом регистра;

Вот результирующий набор.

Msg 208, Level 16, State 0, Line 2
Invalid object name '#A'.

Пример 3

В следующем примере показан вариант, где ссылка обнаруживает несколько соответствий, которые прежде были различными. Во-первых, мы начнем с tempdb (который имеет ту же параметры сортировки с учетом регистра, что и наш экземпляр) и выполните следующие инструкции.

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

Этот запрос удачно выполнен, так как таблицы отличаются в этом сопоставлении.

Вот результирующий набор.

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

Однако если перейти в автономную базу данных, то окажется, что привязка к этим таблицам уже невозможна.

USE MyCDB;
GO

SELECT * FROM #a;
GO

Вот результирующий набор.

Msg 12800, Level 16, State 1, Line 2
The reference to temp table name #a is ambiguous and cannot be resolved. Possible candidates are #a and #A.