Подтвердить что ты не робот

Можно ли безопасно преобразовать SQL Server SQL_Latin1_General_CP1_CI_AS в Latin1_General_CI_AS?

У нас есть устаревшая база данных с некоторыми (более старыми) столбцами, использующая "SQL_Latin1_General_CP1_CI_AS", а более поздние изменения использовали "Latin1_General_CI_AS".

Это боль, поскольку для объединения требуется дополнительная инструкция COLLATE.

Я хотел бы довести все до "Latin1_General_CI_AS". Из того, что я могу собрать, это более или менее одинаковые сопоставления, и я не потеряю данные во время этого процесса...

Кто-нибудь знает, если это так?

4b9b3361

Ответ 1

На этом форуме MSDN есть дополнительная информация:

http://social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/196b4586-1338-434d-ba8c-49fa3c9bdeeb/

Какие состояния:

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

Latin1_General_CI_AS: - Latin1-General, без учета регистра, чувствительный, нечувствительный к канату, нечувствительный к ширине

SQL_Latin1_General_CP1_CI_AS: - Latin1-General, без учета регистра, чувствительный к акценту, нечувствительный к канату, нечувствительный к ширине для Unicode Данные, порядок сортировки SQL Server 52 на кодовой странице 1252 для данных, не относящихся к Unicode

Поэтому, на мой взгляд, вы не должны видеть разницу, особенно если ваши данные только a-z0-9

Ответ 2

Вот более полный ответ:

http://www.olcot.co.uk/sql-blogs/revised-difference-between-collation-sql_latin1_general_cp1_ci_as-and-latin1_general_ci_as

Ключевое различие между этими сопоставлениями заключается в том, как они применяют правила расширения символов. Некоторые латинские символы могут быть расширены до нескольких символов. Сопоставления SQL_xxxx могут игнорировать эти расширения символов при работе с текстом, отличным от юникода, но применять их для текста в Unicode. В результате: объединения, сортировки и сравнения могут возвращать разные результаты при использовании одного сопоставления в сравнении с другим.

Пример:

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

Ответ 3

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

  • Что касается потенциала потери данных:

    • Поля
    • NVARCHAR - это все Unicode, который представляет собой единый набор символов, поэтому потери данных для этих полей не могут быть (это также охватывает поля XML, которые также хранятся как UTF-16 Little Endian). Поля метаданных, в которых хранятся имена объектов/столбцов/индексов/etc, все NVARCHAR, поэтому не нужно беспокоиться о них.
    • VARCHAR поля с разными коллажами, но одна и та же Страница кода между различными сортировками не будет проблемой, поскольку кодовая страница является набором символов.
    • VARCHAR поля, имеющие разные сортировки и перемещающиеся на другую страницу кода (при изменении Collations), могут иметь потерю данных, если какой-либо из используемых символов не представлен на новой кодовой странице. ОДНАКО, это только проблема при физическом изменении Collation конкретного поля (описанного ниже) и не произойдет при изменении стандартного набора данных базы данных.
  • Локальные переменные и строковые литералы получают свою сортировку из базы данных по умолчанию. При изменении базы данных по умолчанию будет изменена сортировка, используемая как для локальных переменных, так и для строковых литералов. Но изменение значения по умолчанию для базы данных по умолчанию не изменяет сортировку, используемую для существующих строковых полей в таблицах в этой базе данных. Именно поэтому возникает ситуация, когда вы получаете проблему неявных преобразований, которая может привести к недействительности индексов (описанных в сообщении в блоге, связанном в @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 и т.д. Фильтрация этих систем Представления против локальных переменных или строковых литералов не будут проблемой, поскольку сортировка будет меняться с обеих сторон. Но если вы подключаетесь к любой из локальных системных представлений к временным таблицам в строковых полях, а сопоставление уровня базы данных между локальной базой данных и tempdb не соответствует, тогда вы получите ошибку "Нечеткое сопоставление". Это обсуждается ниже вместе с лекарством.

  • Одна разница между этими двумя Collations заключается в том, как они сортируют определенные символы для данных VARCHAR (это не влияет на данные NVARCHAR). В не-EBCDIC SQL_ Collations используется то, что называется "Сортировка строк" ​​для данных VARCHAR, тогда как все другие данные Collations и даже NVARCHAR для не-EBCDIC SQL_ Collations используют так называемое "Сортировка слов" ". Разница в том, что в" Сортировке слов" тире - и apostrophe ' (и, возможно, несколько других символов?) Дают очень низкий вес и по существу игнорируются, если нет других различий в строках. Чтобы увидеть это поведение в действии, запустите следующее:

    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
    

    Пока вы "потеряете" поведение "String Sort", я не уверен, что я бы назвал это "функцией". Это поведение, которое было сочтено нежелательным (о чем свидетельствует тот факт, что он не был перенесен ни в одну из сортировок Windows). Тем не менее, это определенная разница в поведении между двумя сопоставлениями (опять же, только для данных, не относящихся к EBCDIC VARCHAR), и у вас могут быть ожидания кода и/или клиента на основе поведения "Сортировка строк" . Это требует тестирования вашего кода и, возможно, изучения, чтобы увидеть, может ли это изменение в поведении иметь какое-либо негативное влияние на пользователей.

  • Другим отличием между SQL_Latin1_General_CP1_CI_AS и Latin1_General_100_CI_AS является возможность делать Expansions в VARCHAR данных (NVARCHAR данные уже могут сделать это для большинства SQL_ Collations), например, для обработки æ, как если бы это было 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 Collation. Однако, как и при сортировке "Сортировка строк" ​​до "Сортировка слов", применяется одно и то же предупреждение: это определенная разница в поведении между двумя сортировками (опять же, только для данных VARCHAR), и у вас может быть код и/или ожидания клиентов, основанные на отсутствии этих сопоставлений. Это требует тестирования вашего кода и, возможно, изучения, чтобы увидеть, может ли это изменение в отношении поведения оказать какое-либо негативное влияние на пользователей.

    (сначала отмечено в @Зарефте ответ и расширено здесь)

  • Слияние на уровне сервера используется для установки сортировки системных баз данных, которая включает [model]. База данных [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 Collations и Windows Коллации, только для VARCHAR данных, в каком случае сортируется первым. Значение, если у вас есть как A, так и A, SQL_ Collations будут сортировать A до A, а не SQL_ Collations (и SQL_ Collations при работе с NVARCHAR данные) сортирует A до A.

Ответ 4

SELECT * FROM ::fn_helpcollations()
WHERE name IN (
'SQL_Latin1_General_CP1_CI_AS',
'Latin1_General_CI_AS'
)

... дает...

Latin1_General_CI_AS: Latin1-General, не чувствительный к регистру, чувствительный к акценту, нечувствительный к канату, нечувствительный к ширине

SQL_Latin1_General_CP1_CI_AS: Latin1-General, чувствительный к регистру, чувствительный к акценту, нечувствительный к канату, нечувствительный к ширине для данных Unicode, порядок сортировки SQL Server 52 на кодовой странице 1252 для данных, не относящихся к Unicode

Таким образом, я бы сделал вывод, что используемая кодовая страница одинакова (Latin1-General = > 1252), поэтому вы не должны потерять данные - если что-то изменит постконверсию, это может быть порядок сортировки - что, вероятно, несущественно.