Может ли 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сведения (это не влияет наNVARCHARdata). Не-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
VARCHARdata), и у вас может быть код и/или ожидания клиентов, основанные на поведении "сортировка строк". это требует тестирования кода и, возможно, исследования, чтобы увидеть, если это изменение в поведении может иметь негативное влияние на пользователей. -
еще одно различие между
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. Однако, как и при перемещении" сортировка строк "в" сортировка слов", применяется та же осторожность: это определенная разница в поведении между двумя сортировками (опять же, только для
VARCHARdata), и вы могли бы имейте код и / или ожидания клиентов, основанные на не имея эти сопоставления. это требует тестирования кода и, возможно, исследования, чтобы увидеть, если это изменение в поведении может иметь негативное влияние на пользователей.(впервые отмечено в @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), так что вы должны не столкнетесь с потерей данных-если что-то изменится после преобразования, это может быть порядок сортировки, который, вероятно, нематериален.