Может ли SQL-сервер общие латинских типа 1 для SQL СР1 ки как быть безопасно преобразован в latin1 генеральный Ди как?
У нас есть устаревшая база данных с некоторыми (более старыми) столбцами, использующими "SQL_Latin1_General_CP1_CI_AS", а более последние изменения использовали"Latin1_General_CI_AS".
Это боль, так как соединения нуждаются в дополнительной инструкции COLLATE для работы.
Я хотел бы довести все до "Latin1_General_CI_AS". Из того, что я могу собрать, они более или менее идентичны, и я не потеряю данные во время этого процесса...
кто-нибудь знает, если это так?
4 ответов
на этом форуме MSDN есть дополнительная информация:
в которой говорится:
вы должны видеть небольшую разницу, если параметры сортировки SQL_Latin1_General_CP1_CI_AS или Latin1_General_CI_AS, но оба имеют экземпляры, где они быстрее или медленнее, чем другие.
Latin1_General_CI_AS: - Latin1-Общие Сведения, регистр, акцент- чувственный, типа японской азбуки-бесчувственный, ширина-нечувствительны
SQL_Latin1_General_CP1_CI_AS: - Latin1-общие, без учета регистра, чувствительный к акценту, нечувствительный к канатипу, нечувствительный к ширине для Unicode Данные, порядок сортировки SQL Server 52 на кодовой странице 1252 для данных, отличных от Unicode
поэтому, на мой взгляд, вы не должны видеть разницы, особенно если ваши данные только a-z0-9
вот более полный ответ:
ключевое различие между этими параметрами сортировки заключается в том, как они применяют правила расширения символов. Некоторые латинские символы можно разложить на несколько символов. Параметры сортировки SQL_xxxx могут игнорировать эти расширения символов при работе с текстом без Юникода, но применять их для Юникода текст. В результате: соединения, сортировки и сравнения могут возвращать разные результаты при использовании одной сортировки по сравнению с другой.
пример:
под Latin1_General_CI_AS
эти два оператора возвращают тот же набор записей, что и ß
увеличивается до ss
.
SELECT * FROM MyTable3 WHERE Comments = 'strasse'
SELECT * FROM MyTable3 WHERE Comments = 'straße'
при использовании SQL_Latin1_General_CP1_CI_AS
вышеуказанные операторы возвращают различные записи, поскольку ß
рассматривается как другой символ, чем ss
.
если вы собираетесь изменить параметры сортировки базы данных, то есть определенно вещи, которые вы должны знать, так что вы можете планировать соответственно:
-
относительно потенциала потери данных:
-
NVARCHAR
поля-это все Unicode, который является одним набором символов, поэтому для этих полей не может быть потери данных (это также охватывает XML-поля, которые также хранятся как UTF-16 Little Endian). Поля метаданных, хранящие объект / столбец / index / etc имена всеNVARCHAR
так что не нужно беспокоиться о них. -
VARCHAR
поля, имеющие разные параметры сортировки, но одну и ту же кодовую страницу между различными параметрами сортировки не будет проблемой, так как кодовая страница является набором символов. -
VARCHAR
поля, имеющие разные параметры сортировки и перемещающиеся на другую кодовую страницу (при изменении параметров сортировки) можете потеря данных, если какой-либо из используемых символов не представлен на новой кодовой странице. Однако это проблема только при физическом изменении параметров сортировки конкретного поля (описано ниже) и не произойдет при изменении параметров сортировки по умолчанию базы данных.
-
-
локальные переменные и строковые литералы получают параметры сортировки из базы данных по умолчанию. Изменение базы данных по умолчанию изменит параметры сортировки, используемые как для локальных переменных, так и для строковых литералов. Но изменение параметров сортировки базы данных по умолчанию не изменяет параметры сортировки используется для существующих строковых полей в таблицах этой базы данных. Это то, что вызывает ситуацию, когда вы получаете проблему неявных преобразований, которая может аннулировать индексы (описанные в блоге связан в @Zarepheth это ответ).
если вы собираетесь изменить параметры сортировки базы данных по умолчанию, то любое строковое поле, отфильтрованное локальной переменной или строковым литералом, должно быть изменено в соответствии с параметрами сортировки по умолчанию База данных. Для этого вы должны использовать следующее:
ALTER TABLE [{table_name}] ALTER COLUMN [{column_name}] {same_datatype} {same_NULL_or_NOT NULL_setting} COLLATE {name_of_Database_default_Collation};
после этого, если есть какие-либо индексы в любом из строковых полей, которые только что изменили их параметры сортировки, вам нужно перестроить эти индексы.
Изменение параметров сортировки базы данных по умолчанию изменит параметры сортировки определенных метаданных базы данных, таких как
name
поле вsys.objects
,sys.columns
,sys.indexes
, etc. Фильтрация этих системных представлений по локальным переменным или строковые литералы не будут проблемой, так как параметры сортировки будут меняться с обеих сторон. Но если вы присоедините любое из локальных системных представлений к временным таблицам в строковых полях и сопоставлению на уровне базы данных между локальной базой данных иtempdb
не соответствует, тогда вы получите ошибку "несоответствие сортировки". Это обсуждается ниже вместе с средством правовой защиты.-
одно различие между этими двумя сортировками заключается в том, как они сортируют определенные символы для
VARCHAR
сведения (это не влияет наNVARCHAR
data). Не-EBCDICSQL_
параметры сортировки используют то, что называется "сортировка строк" дляVARCHAR
данные, в то время как все другие сортировки и дажеNVARCHAR
данные для не-EBCDICSQL_
сортировки, используйте то, что называется "сортировка слов". Разница в том, что в "Сортировке слов" тире-
и апостроф'
(и, может быть, несколько других персонажей?) имеют очень низкий вес и по существу игнорируются, если нет других различий в строках. Видеть это поведения в действии, выполните следующее:DECLARE @Test TABLE (Col1 VARCHAR(10) NOT NULL); INSERT INTO @Test VALUES ('aa'); INSERT INTO @Test VALUES ('ac'); INSERT INTO @Test VALUES ('ah'); INSERT INTO @Test VALUES ('am'); INSERT INTO @Test VALUES ('aka'); INSERT INTO @Test VALUES ('akc'); INSERT INTO @Test VALUES ('ar'); INSERT INTO @Test VALUES ('a-f'); INSERT INTO @Test VALUES ('a_e'); INSERT INTO @Test VALUES ('a''kb'); SELECT * FROM @Test ORDER BY [Col1] COLLATE SQL_Latin1_General_CP1_CI_AS; -- "String Sort" puts all punctuation ahead of letters SELECT * FROM @Test ORDER BY [Col1] COLLATE Latin1_General_100_CI_AS; -- "Word Sort" mostly ignores dash and apostrophe
возвращает:
String Sort ----------- a'kb a-f a_e aa ac ah aka akc am ar
и:
Word Sort --------- a_e aa ac a-f ah aka a'kb akc am ar
в то время как вы" потеряете "поведение" сортировки строк", я не уверен, что я бы назвал это"функцией". Это поведение, которое было сочтено нежелательным (о чем свидетельствует тот факт, что оно не было перенесено ни в один из параметров сортировки Windows). Однако это is определенная разница в поведении между двумя сортировками (опять же, только для non-EBCDIC
VARCHAR
data), и у вас может быть код и/или ожидания клиентов, основанные на поведении "сортировка строк". это требует тестирования кода и, возможно, исследования, чтобы увидеть, если это изменение в поведении может иметь негативное влияние на пользователей. -
еще одно различие между
SQL_Latin1_General_CP1_CI_AS
иLatin1_General_100_CI_AS
- это возможность делать расширения onVARCHAR
сведения (NVARCHAR
данные уже могут сделать это для большинстваSQL_
параметры сортировки), например, обращениеæ
как будтоae
:IF ('æ' COLLATE SQL_Latin1_General_CP1_CI_AS = 'ae' COLLATE SQL_Latin1_General_CP1_CI_AS) BEGIN PRINT 'SQL_Latin1_General_CP1_CI_AS'; END; IF ('æ' COLLATE Latin1_General_100_CI_AS = 'ae' COLLATE Latin1_General_100_CI_AS) BEGIN PRINT 'Latin1_General_100_CI_AS'; END;
возвращает:
Latin1_General_100_CI_AS
единственное, что вы "теряете" здесь, это не возможность делать эти расширения. Вообще говоря, это еще одно преимущество перехода на параметры сортировки Windows. Однако, как и при перемещении" сортировка строк "в" сортировка слов", применяется та же осторожность: это определенная разница в поведении между двумя сортировками (опять же, только для
VARCHAR
data), и вы могли бы имейте код и / или ожидания клиентов, основанные на не имея эти сопоставления. это требует тестирования кода и, возможно, исследования, чтобы увидеть, если это изменение в поведении может иметь негативное влияние на пользователей.(впервые отмечено в @Zarepheth это ответ и развернуто здесь)
-
параметры сортировки на уровне сервера используются для задания параметров сортировки системных баз данных, которые включают
[model]
. The[model]
база данных используется как шаблон для создания новых баз данных, который включает в себя[tempdb]
при каждом запуске сервера. Таким образом, если параметры сортировки по умолчанию базы данных не соответствуют параметрам сортировки по умолчанию экземпляра и вы присоединяете локальные таблицы к временным таблицам в строковых полях, затем вы получите ошибку сопоставления. К счастью, есть несколько простой способ исправить различия сортировки между базой данных, которая является "текущей", когдаCREATE #TempTable
выполнена и[tempdb]
. При создании временных таблиц объявите параметры сортировки с помощьюCOLLATE
предложение и укажите параметры сортировкиDATABASE_DEFAULT
:CREATE TABLE #Temp (Col1 NVARCHAR(40) COLLATE DATABASE_DEFAULT);
это не обязательно для переменных таблицы, так как они получают параметры сортировки по умолчанию из "текущей" базы данных. Однако, если у вас есть переменные таблицы и временные таблицы и присоединяются к ним в строковых полях, вам нужно будет использовать
COLLATE DATABASE_DEFAULT
как показано выше. параметры сортировки на уровне сервера также управляет именами локальных переменных,
CURSOR
имена переменных, аGOTO
метки. Хотя ни одно из этих изменений не будет затронуто конкретным изменением, рассматриваемым в этом вопросе, по крайней мере, об этом следует знать.-
лучше всего использовать самую последнюю версию нужной сортировки, если доступно несколько версий. Начиная с SQL Server 2005, была введена серия параметров сортировки "90", а SQL Server 2008-серия параметров сортировки" 100". Вы можете найти эти параметры сортировки, используя следующие запросы:
SELECT * FROM sys.fn_helpcollations() WHERE [name] LIKE N'%[_]90[_]%'; -- 476 SELECT * FROM sys.fn_helpcollations() WHERE [name] LIKE N'%[_]100[_]%'; -- 2686
кроме того, в то время как вопрос задает параметры сортировки без учета регистра, следует отметить, что если кто-то еще хочет внести аналогичные изменения, но использует параметры сортировки с учетом регистра, то другое различие между параметрами сортировки SQL Server и параметрами сортировки Windows,на
VARCHAR
сведения только случае сортировка сначала. То есть, если у вас есть обаA
иa
, theSQL_
Сортировки будет сортироватьA
доa
, а неSQL_
параметры сортировки (иSQL_
сортировки при работе сNVARCHAR
сведения) будет вродеa
доA
.
SELECT * FROM ::fn_helpcollations()
WHERE name IN (
'SQL_Latin1_General_CP1_CI_AS',
'Latin1_General_CI_AS'
)
...дает...
Latin1_General_CI_AS: Латинских типа 1-Общие, без учета регистра, диакритических знаков, типа японской азбуки-бесчувственный, ширина-нечувствительны
sql_latin1_general_cp1_ci_as в: Латинских типа 1-Общие, без учета регистра, диакритических знаков, типа японской азбуки-бесчувственный, ширина-нечувствительны для данных Unicode SQL Server сортирует порядок 52 на кодовой странице 1252 для данных, отличных от Unicode
Итак, из этого я бы сделал вывод, что используемая кодовая страница одинакова (Latin1-General => 1252), так что вы должны не столкнетесь с потерей данных-если что-то изменится после преобразования, это может быть порядок сортировки, который, вероятно, нематериален.