Не удается разрешить конфликт параметров сортировки между "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.

22 ответов


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

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)

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

...WHERE 
    fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT

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


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

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

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

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


определите поля, для которых он выдает эту ошибку, и добавьте к ним следующее: СЛИЧИТЬ РАВНЫМ DATABASE_DEFAULT

есть две таблицы, Соединенные в поле кода:

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

обновить запрос:

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

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

...WHERE fieldname COLLATE DATABASE_DEFAULT in ( select distinct otherfieldname COLLATE DATABASE_DEFAULT from ... where ... )


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

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


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

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

WHERE U.Fullname = @SearchTerm  collate SQL_Latin1_General_CP1_CI_AS

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

проверить, что это то же самое.


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

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

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

благодаря ответу 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 Affiliate ALTER COLUMN myTable NVARCHAR (4000) COLLATE Latin1_General_CI_AS NOT NULL

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


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

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


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

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

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

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 

ссылка здесь


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

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


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

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

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

поэтому мы использовали приведенное ниже предложение join:

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

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


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

  1. резервное копирование базы данных, просто Incase
  2. изменить параметры сортировки базы данных: щелкните правой кнопкой мыши базу данных, выберите Свойства, перейдите к параметрам и измените параметры сортировки на требуемые параметры сортировки.
  3. создать скрипт для удаления и воссоздания всех объектов базы данных: щелкните правой кнопкой мыши базу данных, выберите задачи, выберите создать скрипт... (убедитесь, что вы выбрали Drop & Create в Дополнительных параметрах мастера, Также выберите Schema & Data)
  4. запустите скрипт, сгенерированный выше

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

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

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

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

  4. запустите sql server:

    net start name_of_instance

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

вот дополнительная информация:

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


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 )

добавлен код в ответ @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)

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