Не удается разрешить конфликт параметров сортировки между "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
ссылка здесь
вот что мы сделали, в нашей ситуации нам нужен специальный запрос, который будет выполняться с использованием ограничения даты по требованию, и запрос определен в таблице.
наш новый запрос должен соответствовать данным между различными базами данных и включать данные из обоих из них.
похоже, что параметры сортировки отличаются между БД, импортирующей данные из системы 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 простых шага
- резервное копирование базы данных, просто Incase
- изменить параметры сортировки базы данных: щелкните правой кнопкой мыши базу данных, выберите Свойства, перейдите к параметрам и измените параметры сортировки на требуемые параметры сортировки.
- создать скрипт для удаления и воссоздания всех объектов базы данных: щелкните правой кнопкой мыши базу данных, выберите задачи, выберите создать скрипт... (убедитесь, что вы выбрали Drop & Create в Дополнительных параметрах мастера, Также выберите Schema & Data)
- запустите скрипт, сгенерированный выше
проверьте уровень несоответствия параметров сортировки (сервер, база данных,таблица,столбец, символ).
Если это сервер, то эти шаги помогли мне однажды:
- остановить сервер
- найдите свой sqlservr.инструмент exe
-
выполните эту команду:
sqlservr -m -T4022 -T3659 -s"name_of_insance" -q "name_of_collation"
-
запустите sql server:
net start name_of_instance
проверьте параметры сортировки вашего сервера снова.
вот дополнительная информация:
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)
У вас может не быть никаких проблем с сортировкой в вашей базе данных, но если вы восстановили копию своей базы данных из резервной копии на сервере с другой сортировкой, чем исходная, и ваш код создает временные таблицы, эти временные таблицы унаследуют сортировку от сервера, и возникнут конфликты с вашей базой данных.