Не удается разрешить конфликт сортировки между "SQL_Latin1_General_CP1_CI_AS" и "Latin1_General_CI_AS" в равном действии

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

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 года.

Ответ 1

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

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

Марк

UPDATE: чтобы найти полнотекстовые индексы в вашей базе данных, используйте этот запрос здесь:

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)

Ответ 2

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

...WHERE 
    fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT

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

Ответ 3

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

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

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

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

Ответ 4

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

В поле Код есть две таблицы:

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

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

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

Ответ 5

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

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

Ответ 6

В критерии где добавьте collate SQL_Latin1_General_CP1_CI_AS

Это работает для меня.

WHERE U.Fullname = @SearchTerm  collate SQL_Latin1_General_CP1_CI_AS

Ответ 7

Это может легко случиться, когда у вас есть 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

Ответ 8

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

Ответ 9

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

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

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

Ответ 10

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

Убедитесь, что они совпадают.

Ответ 11

Благодаря ответу marc_s я решил свою оригинальную проблему - вдохновил ее сделать еще один шаг и опубликовать один подход к преобразованию всей таблицы за один раз - tsql script для генерации операторов 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 -

Ответ 12

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

-- 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 - создание базы данных с различной сортировкой на сервере

Ответ 13

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

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

Ответ 14

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

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

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

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

  • Запустите свой сервер sql:

    net start name_of_instance

  • Проверьте настройку сервера еще раз.

Подробнее:

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

Ответ 15

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

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 

Ссылка здесь

Ответ 16

В ответ @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)

Ответ 17

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

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

Ответ 18

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

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

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

Итак, мы использовали предложение ниже:

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

Ответ 19

ALTER DATABASE test2 - введите название своей базы данных здесь  COLLATE Latin1_General_CS_AS - замените нужную сортировку

Ответ 20

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

  • резервное копирование базы данных, просто incase
  • изменить сортировку базы данных: щелкнуть правой кнопкой мыши базу данных, выбрать свойства, перейти к параметрам и изменить сортировку на требуемую сортировку.
  • Создайте script для удаления и воссоздания всех объектов базы данных: щелкните правой кнопкой мыши вашу базу данных, выберите задачи, выберите сгенерируйте script... (убедитесь, что вы выбрали Drop и Create в дополнительных опциях мастера, также выберите "Схема и данные" ).
  • Запустите script Сгенерировано выше

Ответ 21

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 )

Ответ 22

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

COLLATE SQL_Latin1_General_CP1_CI_AS

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

Ответ 23

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