Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Область применения: 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.