Не удается разрешить конфликт сопоставления между «SQL_Latin1_General_CP1_CI_AS» и «Latin1_General_CI_AS» в операции равно


345

У меня есть следующий код

SELECT tA.FieldName As [Field Name],
       COALESCE(tO_A.[desc], tO_B.[desc], tO_C.Name, tA.OldVAlue) AS [Old Value],
       COALESCE(tN_A.[desc], tN_B.[desc], tN_C.Name, tA.NewValue) AS [New Value],
       U.UserName AS [User Name],
       CONVERT(varchar, tA.ChangeDate) AS [Change Date] 
  FROM D tA
       JOIN 
       [DRTS].[dbo].[User] U 
         ON tA.UserID = U.UserID
       LEFT JOIN 
       A tO_A 
         on tA.FieldName = 'AID' 
        AND tA.oldValue = CONVERT(VARCHAR, tO_A.ID)
       LEFT JOIN 
       A tN_A 
         on tA.FieldName = 'AID' 
        AND tA.newValue = CONVERT(VARCHAR, tN_A.ID)
       LEFT JOIN 
       B tO_B 
         on tA.FieldName = 'BID' 
        AND tA.oldValue = CONVERT(VARCHAR, tO_B.ID)
       LEFT JOIN 
       B tN_B 
         on tA.FieldName = 'BID' 
        AND tA.newValue = CONVERT(VARCHAR, tN_B.ID)
       LEFT JOIN 
       C tO_C 
         on tA.FieldName = 'CID' 
        AND tA.oldValue = tO_C.Name
       LEFT JOIN 
       C tN_C 
         on tA.FieldName = 'CID' 
        AND tA.newValue = tN_C.Name
 WHERE U.Fullname = @SearchTerm
ORDER BY tA.ChangeDate

При выполнении кода я получаю сообщение об ошибке, вставленное в заголовок после добавления двух объединений для таблицы C. Я думаю, что это может иметь какое-то отношение к тому факту, что я использую SQL Server 2008 и восстановил копию этой базы данных в моя машина которая 2005 года.

Ответы:


307

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

SELECT
    col.name, col.collation_name
FROM 
    sys.columns col
WHERE
    object_id = OBJECT_ID('YourTableName')

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

После того как вы выбрали одно сопоставление, вы можете изменить те таблицы / столбцы, которые еще не совпадают, с помощью этой команды:

ALTER TABLE YourTableName
  ALTER COLUMN OffendingColumn
    VARCHAR(100) COLLATE Latin1_General_CI_AS NOT NULL

Марк

ОБНОВЛЕНИЕ: чтобы найти полнотекстовые индексы в вашей базе данных, используйте этот запрос здесь:

SELECT
    fti.object_Id,
    OBJECT_NAME(fti.object_id) 'Fulltext index',
    fti.is_enabled,
    i.name 'Index name',
    OBJECT_NAME(i.object_id) 'Table name'
FROM 
    sys.fulltext_indexes fti
INNER JOIN 
    sys.indexes i ON fti.unique_index_id = i.index_id

Затем вы можете удалить полнотекстовый индекс, используя:

DROP FULLTEXT INDEX ON (tablename)

Спасибо, Марк, это именно то, что я искал, одна из таблиц была по разному сопоставлению по какой-то глупой причине! Я постараюсь изменить стандартную сортировку и посмотреть, что произойдет.
Jhowe

marc Я получаю это сейчас: не могу изменить или удалить столбец, потому что он включен для полнотекстового поиска.
Jhowe

1
В этом случае вам необходимо временно удалить свой полнотекстовый индекс для этой таблицы, изменить параметры сортировки, а затем заново создать полнотекстовый индекс
marc_s,

1
Благодаря OP, я настраивал временную таблицу, так что это помогло, но поскольку я не мог изменить таблицу, мне нужно было просто объявить ее правильно, чтобы начать с (как показано ниже): DECLARE @Table TABLE (CompareMessage VARCHAR (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL)
FrostbiteXIII

1
Почему мы не можем иметь 2 разных сопоставления на одном столе. Если у меня есть 1 столбец как nvarchar, которому нужны только английские имена и другой столбец как русские буквы, другой столбец как японские буквы. Как мне это устроить? Есть ли одно сопоставление охватывает все это?
batmaci

856

Я делаю следующее:

...WHERE 
    fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT

Работает каждый раз. :)


68
Это один из самых полезных постов на SO
Джейми Стросс

2
Я использовал это решение, потому что я работал с двумя устаревшими системами, использующими один и тот же дБ, поэтому я не был уверен, что изменение сортировки таблиц нарушит функциональность.
paolobueno

5
Если одни и те же два поля используются вместе в других местах (сравнения, объединения, объединения и т. Д.), Убедитесь, что в каждом из них также указано сопоставление.
Зарепет

5
Это чрезвычайно полезно. Я использую локальную базу данных и выполняю запросы к связанному серверу, и у них есть два разных сопоставления. Очевидно, что я не могу изменить параметры сортировки на связанном сервере, и я не хотел менять свои параметры локально, так что это абсолютно лучший ответ.
jtate

7
@ppumkin Хотя это отличное решение, оно все же только избегает проблемы, а не решает ее. Если вы не хотите изменять параметры сортировки для каждого запроса, который утомителен и не оптимально выполняется. Хотя это отличный ответ, я считаю, что принятый ответ - лучший.
Роб

80

Используйте collateпредложение в вашем запросе:

LEFT JOIN C tO_C on tA.FieldName = 'CID' AND tA.oldValue COLLATE Latin1_General_CI_AS = tO_C.Name  

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

редактировать: я понял, что это было не совсем правильно - предложение сортировки идет после поля, которое нужно изменить - в этом примере я изменил сортировку по tA.oldValueполю.


29

Определите поля, для которых он выдает эту ошибку, и добавьте к ним следующее: COLLATE DATABASE_DEFAULT

В поле Код объединены две таблицы:

...
and table1.Code = table2.Code
...

Обновите ваш запрос:

...
and table1.Code COLLATE DATABASE_DEFAULT = table2.Code COLLATE DATABASE_DEFAULT
...

Спасибо. При работе в базе данных prod мы не всегда можем изменять структуру базы данных, как это предусмотрено принятым ответом.
Дженнифер Вуд

21

Это может легко случиться, когда у вас есть 2 разные базы данных и особенно 2 разные базы данных с 2 разных серверов. Лучший вариант - изменить его на общую коллекцию и выполнить объединение или сравнение.

SELECT 
   *
FROM sd
INNER JOIN pd ON sd.SCaseflowID COLLATE Latin1_General_CS_AS = pd.PDebt_code COLLATE Latin1_General_CS_AS

13

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

...WHERE fieldname COLLATE DATABASE_DEFAULT in (
          SELECT DISTINCT otherfieldname COLLATE DATABASE_DEFAULT
          FROM ...
          WHERE ...
        )


6

Основная причина в том, что база данных сервера sql, из которой вы взяли схему, имеет параметры сортировки, которые отличаются от вашей локальной установки. Если вы не хотите беспокоиться о сопоставлении, переустановите SQL Server локально, используя то же сопоставление, что и база данных SQL Server 2008.


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

5

ошибка (не удается разрешить конфликт сопоставления между ....) обычно возникает при сравнении данных из нескольких баз данных.

поскольку вы не можете изменить параметры сортировки баз данных сейчас, используйте COLLATE DATABASE_DEFAULT.

----------
AND db1.tbl1.fiel1 COLLATE DATABASE_DEFAULT =db2.tbl2.field2 COLLATE DATABASE_DEFAULT 

это ничем не отличается от другого уже полученного ответа: stackoverflow.com/a/1607725/479251
Pac0

4

У меня было что-то подобное раньше, и мы обнаружили, что сопоставление между двумя таблицами было разным.

Убедитесь, что они одинаковы.


4

Благодаря ответу marc_s я решил свою первоначальную проблему - вдохновился сделать еще один шаг и опубликовать один подход к преобразованию всей таблицы за раз - скрипт tsql для генерации операторов alter column:

DECLARE @tableName VARCHAR(MAX)
SET @tableName = 'affiliate'
--EXEC sp_columns @tableName
SELECT  'Alter table ' + @tableName + ' alter column ' + col.name
        + CASE ( col.user_type_id )
            WHEN 231
            THEN ' nvarchar(' + CAST(col.max_length / 2 AS VARCHAR) + ') '
          END + 'collate Latin1_General_CI_AS ' + CASE ( col.is_nullable )
                                                    WHEN 0 THEN ' not null'
                                                    WHEN 1 THEN ' null'
                                                  END
FROM    sys.columns col
WHERE   object_id = OBJECT_ID(@tableName)

получает: ALTER TABLE Партнер ALTER COLUMN myTable NVARCHAR (4000) COLLATE Latin1_General_CI_AS NOT NULL

Я признаюсь, что озадачен необходимостью col.max_length / 2 -


Я думаю, что деление на два требуется, потому что длина хранится как количество байтов внутри. Nvarchar берет два байта на символ вместо одного в качестве varchar.
Зеби

Отличная работа, как бы то ни было, количество запросов в ncha для типов данных ncha, вероятно, из-за col.max_length / 2
Имран,

2

Для тех, у кого есть сценарий CREATE DATABASE (как было в моем случае) для базы данных, которая вызывает эту проблему, вы можете использовать следующий сценарий CREATE, чтобы сопоставить параметры сортировки:

-- Create Case Sensitive Database
CREATE DATABASE CaseSensitiveDatabase
COLLATE SQL_Latin1_General_CP1_CS_AS -- or any collation you require
GO
USE CaseSensitiveDatabase
GO
SELECT *
FROM sys.types
GO
--rest of your script here

или

-- Create Case In-Sensitive Database
CREATE DATABASE CaseInSensitiveDatabase
COLLATE SQL_Latin1_General_CP1_CI_AS -- or any collation you require
GO
USE CaseInSensitiveDatabase
GO
SELECT *
FROM sys.types
GO
--rest of your script here

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

Дополнительная информация по следующей ссылке: SQL SERVER - Создание базы данных с разным сопоставлением на сервере.


2

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

CREATE PROCEDURE [dbo].[sz_pipeline001_collation] 
    -- Add the parameters for the stored procedure here
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;


SELECT 'ALTER TABLE [' + SYSOBJECTS.Name + '] ALTER COLUMN [' + SYSCOLUMNS.Name + '] ' +
SYSTYPES.name + 
    CASE systypes.NAME
    WHEN 'text' THEN ' '
    ELSE
    '(' + RTRIM(CASE SYSCOLUMNS.length
    WHEN -1 THEN 'MAX'
    ELSE CONVERT(CHAR,SYSCOLUMNS.length)
    END) + ') ' 
    END

    + ' ' + ' COLLATE Latin1_General_CI_AS ' + CASE ISNULLABLE WHEN 0 THEN 'NOT NULL' ELSE 'NULL' END
    FROM SYSCOLUMNS , SYSOBJECTS , SYSTYPES
    WHERE SYSCOLUMNS.ID = SYSOBJECTS.ID
    AND SYSOBJECTS.TYPE = 'U'
    AND SYSTYPES.Xtype = SYSCOLUMNS.xtype
    AND SYSCOLUMNS.COLLATION IS NOT NULL
    AND NOT ( sysobjects.NAME LIKE 'sys%' )
    AND NOT ( SYSTYPES.name LIKE 'sys%' )

END

1
SYSCOLUMNS. Длина столбцов nvarchar должна быть разделена на 2
palota

2

Проверьте уровень сопоставления, который не соответствует (сервер, база данных, таблица, столбец, символ).

Если это сервер, эти шаги помогли мне один раз:

  1. Остановить сервер
  2. Найдите свой инструмент sqlservr.exe
  3. Запустите эту команду:

    sqlservr -m -T4022 -T3659 -s"name_of_insance" -q "name_of_collation"

  4. Запустите ваш sql сервер:

    net start name_of_instance

  5. Проверьте параметры сортировки вашего сервера еще раз.

Вот больше информации:

https://www.mssqltips.com/sqlservertip/3519/changing-sql-server-collation-after-installation/


2

Если это происходит по всей вашей БД, то лучше изменить параметры сортировки БД следующим образом:

USE master;  
GO  
ALTER DATABASE MyOptionsTest  
COLLATE << INSERT COLATION REQUIRED >> ;  
GO  

--Verify the collation setting.  
SELECT name, collation_name  
FROM sys.databases  
WHERE name = N'<< INSERT DATABASE NAME >>';  
GO 

Ссылка здесь


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

2

Добавлен код в ответ @ JustSteve для работы со столбцами varchar и varchar (MAX):

DECLARE @tableName VARCHAR(MAX)
SET @tableName = 'first_notes'
--EXEC sp_columns @tableName
SELECT  'Alter table ' + @tableName + ' alter column ' + col.name
        + CASE ( col.user_type_id )
            WHEN 231
            THEN ' nvarchar(' + CAST(col.max_length / 2 AS VARCHAR) + ') '
            WHEN 167
            THEN ' varchar(' + CASE col.max_length 
                                WHEN -1 
                                THEN 'MAX'
                                ELSE 
                                CAST(col.max_length AS VARCHAR)
                                end
                                 + ') '
          END + 'collate Latin1_General_CI_AS ' + CASE ( col.is_nullable )
                                                    WHEN 0 THEN ' not null'
                                                    WHEN 1 THEN ' null'
                                                  END
FROM    sys.columns col
WHERE   object_id = OBJECT_ID(@tableName)

2

Чтобы решить эту проблему в запросе без изменения какой-либо базы данных, вы можете привести выражения к другой стороне знака «=» с помощью

COLLATE SQL_Latin1_General_CP1_CI_AS

как предложено здесь .


1

У меня была похожая ошибка (не удалось разрешить конфликт сопоставления между «SQL_Latin1_General_CP1_CI_AS» и «SQL_Latin1_General_CP1250_CI_AS» в операции INTERSECT), когда я использовал старый драйвер jdbc.

Я решил эту проблему, загрузив новый драйвер от Microsoft или проект с открытым исходным кодом jTDS .


1

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

Наш новый запрос должен сопоставлять данные между различными базами данных и включать данные из обеих из них.

Кажется, что COLLATION отличается между базой данных, которая импортирует данные из системы iSeries / AS400, и нашей базой данных отчетов - это может быть связано с конкретными типами данных (такими как греческие акценты в именах и т. Д.).

Таким образом, мы использовали следующее предложение join:

...LEFT Outer join ImportDB..C4CTP C4 on C4.C4CTP COLLATE Latin1_General_CS_AS=CUS_Type COLLATE Latin1_General_CS_AS

1

Вы можете легко сделать это, используя 4 простых шага

  1. сделайте резервную копию вашей базы данных, просто
  2. изменить параметры сортировки базы данных: щелкните базу данных правой кнопкой мыши, выберите свойства, перейдите к параметрам и измените параметры сортировки на требуемые параметры сортировки.
  3. Создайте сценарий для удаления и воссоздания всех объектов базы данных: щелкните правой кнопкой мыши базу данных, выберите задачи, выберите создать сценарий ... (убедитесь, что вы выбрали «Удалить и создать» в дополнительных параметрах мастера, также выберите «Схема и данные»)
  4. Запустите созданный выше скрипт

1
INSERT INTO eSSLSmartOfficeSource2.[dbo].DeviceLogs  (DeviceId,UserId,LogDate,UpdateFlag) 
SELECT DL1.DeviceId ,DL1.UserId COLLATE DATABASE_DEFAULT,DL1.LogDate 
,0 FROM eSSLSmartOffice.[dbo].DeviceLogs DL1 
WHERE  NOT EXISTS 
(SELECT DL2.DeviceId ,DL2.UserId COLLATE DATABASE_DEFAULT
,DL2.LogDate ,DL2.UpdateFlag 
FROM eSSLSmartOfficeSource2.[dbo].DeviceLogs DL2    
WHERE  DL1.DeviceId =DL2.DeviceId
 and DL1.UserId collate  Latin1_General_CS_AS=DL2.UserId collate  Latin1_General_CS_AS
  and DL1.LogDate =DL2.LogDate )

0

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



0

У меня было похожее требование; документирование моего подхода здесь для любого с похожим сценарием ...

сценарий

  • У меня есть база данных из чистой установки с правильными параметрами сортировки.
  • У меня есть другая база данных, которая имеет неправильные сопоставления.
  • Мне нужно обновить последний, чтобы использовать параметры сортировки, определенные на первом.

Решение

Используйте Сравнение схем SQL Server (из Инструментов данных SQL Server / Visual Studio), чтобы сравнить источник (чистая установка) с местом назначения (БД с неверным сопоставлением).

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

  • Запустите Visual Studio
  • Создайте новый проект данных SQL Server
  • Нажмите Инструменты, SQL Server, Сравнение новой схемы
  • Выберите исходную базу данных
  • Выберите целевую базу данных
  • Варианты нажатия (⚙)
    • В разделе Object Typesвыберите только те типы, которые вас интересуют (для меня это было только ViewsиTables )
    • Под General выбором:
      • Блокировать возможную потерю данных
      • Отключить и включить триггеры DDL
      • Игнорировать путь к файлу криптографического провайдера
      • Игнорировать путь к файлу и лог-файлу
      • Игнорировать размер файла
      • Игнорировать размещение файловой группы
      • Игнорировать путь к файлу полнотекстового каталога
      • Игнорировать регистр ключевых слов
      • Игнорировать SID входа
      • Игнорировать цитируемые идентификаторы
      • Игнорировать время жизни маршрута
      • Игнорировать точку с запятой между утверждениями
      • Игнорировать пробелы
      • Модуль обновления скрипта
      • Проверка скрипта для новых ограничений
      • Проверьте совместимость сопоставления
      • Проверить развертывание
  • Нажмите Сравнить
    • Снимите флажки с любых объектов, помеченных для удаления (примечание: у них все еще могут быть проблемы с сопоставлением; но поскольку они не определены в нашей базе данных source / template, мы не знаем; в любом случае, мы не хотим потерять вещи, если мы только нацеливание изменений сопоставления). Вы можете снять все сразу, щелкнув правой кнопкой мыши по DELETEпапке и выбрав EXCLUDE.
    • Точно так же исключают для любого CREATE объектов (здесь, поскольку они не существуют в цели, у них не может быть неправильного сопоставления там; вопрос, должны ли они существовать, является вопросом для другой темы).
    • Нажмите на каждый объект в разделе ИЗМЕНИТЬ, чтобы увидеть сценарий для этого объекта. Используйте diff, чтобы убедиться, что мы меняем только параметры сортировки (если вы обнаружите другие различия вручную, вы, вероятно, захотите исключить / обработать эти объекты вручную).
  • Нажмите, Updateчтобы нажать изменения

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

Также вы можете сохранить проект базы данных с допустимой схемой, чтобы вы могли использовать универсальный шаблон для ваших БД, если у вас есть более 1 для обновления, при условии, что все целевые БД должны иметь одну и ту же схему.

Вы также можете использовать поиск / замену файлов в проекте базы данных, если хотите массово изменить настройки (например, чтобы создать проект из недопустимой базы данных, используя сравнение схем, изменить файлы проекта, а затем переключить источник / цель в сравнение схемы, чтобы отправить ваши изменения обратно в БД).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.