No se puede resolver el conflicto de intercalación entre “SQL_Latin1_General_CP1_CI_AS” y “Latin1_General_CI_AS” en la operación igual

Tengo el siguiente código

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 

Cuando ejecuto el código, obtengo el error pegado en el título después de agregar las dos combinaciones para la tabla C. Creo que esto puede tener algo que ver con el hecho de que estoy usando SQL Server 2008 y he restaurado una copia de este db en mi máquina que es 2005.

Tiene una discrepancia de dos intercalaciones diferentes en su tabla. Puede verificar qué colaciones tiene cada columna en su (s) tabla (s) al usar esta consulta:

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

Las intercalaciones son necesarias y se utilizan al ordenar y comparar cadenas. En general, es una buena idea tener una intercalación única y única en toda su base de datos, no use intercalaciones diferentes dentro de una sola tabla o base de datos, solo está buscando problemas …

Una vez que se haya conformado con una sola intercalación, puede cambiar esas tablas / columnas que aún no coinciden utilizando este comando:

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

Bagazo

ACTUALIZACIÓN: para encontrar los índices de texto completo en su base de datos, use esta consulta aquí:

 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 

A continuación, puede soltar el índice de texto completo con:

 DROP FULLTEXT INDEX ON (tablename) 

Yo hago lo siguiente:

 ...WHERE fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT 

Funciona todo el tiempo. 🙂

Use la cláusula de collate en su consulta:

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

Puede que no tenga la syntax exactamente correcta (marque BOL), pero puede hacer esto para cambiar la intercalación sobre la marcha para la consulta; es posible que deba agregar la cláusula para cada combinación.

editar: me di cuenta de que esto no era del todo correcto, la cláusula de clasificación va después del campo que necesita cambiar, en este ejemplo cambié la intercalación en el campo tA.oldValue .

Identifique los campos para los que arroja este error y añádalos a ellos: COLLATE DATABASE_DEFAULT

Hay dos tablas unidas en el campo Código:

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

Actualiza tu consulta a:

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

@Valkyrie respuesta increíble. Pensé en poner aquí un caso al realizar lo mismo con una subconsulta dentro de un procedimiento almacenado, ya que me preguntaba si su respuesta funciona en este caso, y lo hizo increíble.

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

Esto puede suceder fácilmente cuando tienes 2 bases de datos diferentes y especialmente 2 bases de datos diferentes de 2 servidores diferentes. La mejor opción es cambiarlo a una colección común y hacer la unión o comparación.

 select * from sd inner join pd on sd.SCaseflowID collate Latin1_General_CS_AS = pd.PDebt_code collate Latin1_General_CS_AS 

La causa raíz es que la base de datos del servidor SQL que tomó el esquema tiene una intercalación que difiere de su instalación local. Si no desea preocuparse por la intercalación, instale SQL Server localmente utilizando la misma intercalación que la base de datos de SQL Server 2008.

He tenido algo así antes, y lo que encontramos fue que la intercalación entre 2 tablas era diferente.

Verifique que estos sean iguales.

En donde los criterios agregan collate SQL_Latin1_General_CP1_CI_AS

Esto funciona para mí

 WHERE U.Fullname = @SearchTerm collate SQL_Latin1_General_CP1_CI_AS 

Gracias a la respuesta de marc_s, resolví mi problema original, inspirándome a dar un paso más allá y publicar un enfoque para transformar una tabla completa a la vez: secuencia de comandos tsql para generar las siguientes declaraciones de columna:

 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) 

obtiene: ALTER TABLE Afiliado ALTER COLUMN myTable NVARCHAR (4000) COLLATE Latin1_General_CI_AS NOT NULL

Admitiré estar desconcertado por la necesidad de col.max_length / 2

error (No se puede resolver el conflicto de intercalación entre ….) generalmente ocurre al comparar datos de múltiples bases de datos.

ya que no puede cambiar la recostackción de bases de datos ahora, use COLLATE DATABASE_DEFAULT.

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

Para aquellos que tienen una secuencia de comandos CREATE DATABASE (como era mi caso) para la base de datos que está causando este problema, puede usar la siguiente secuencia de comandos CREATE para que coincida con la intercalación:

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

o

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

Esto aplica la intercalación deseada a todas las tablas, que era justo lo que necesitaba. Es ideal intentar y mantener la intercalación igual para todas las bases de datos en un servidor. Espero que esto ayude.

Más información en el siguiente enlace: SERVIDOR SQL – Creación de una base de datos con diferentes colas en el servidor

He utilizado el contenido de este sitio para crear el siguiente script que cambia la intercalación de todas las columnas en todas las tablas:

 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 

Si esto ocurre en toda su base de datos, entonces es mejor cambiar su colación DB así:

 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 

Referencia aquí

Tuve un error similar (No se puede resolver el conflicto de intercalación entre “SQL_Latin1_General_CP1_CI_AS” y “SQL_Latin1_General_CP1250_CI_AS” en la operación INTERSECT), cuando utilicé el antiguo controlador jdbc.

Resolví esto descargando un nuevo controlador de Microsoft o jTDS de código abierto .

esto es lo que hicimos, en nuestra situación necesitamos que se ejecute una consulta ad hoc usando una restricción de fecha a petición, y la consulta se define en una tabla.

Nuestra nueva consulta debe coincidir con los datos entre diferentes bases de datos e incluir datos de ambos.

Parece que COLLATION es diferente entre el db que importa datos del sistema iSeries / AS400 y nuestra base de datos de informes, esto podría deberse a los tipos de datos específicos (como los acentos griegos en los nombres, etc.).

Entonces usamos la siguiente cláusula de unión:

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

ALTER DATABASE test2 – ponga aquí el nombre de su base de datos COLLATE Latin1_General_CS_AS – reemplácelo con la colación que necesite

Usted puede hacer esto fácilmente usando 4 sencillos pasos

  1. haga una copia de seguridad de su base de datos, solo en caso
  2. cambiar la intercalación de la base de datos: haga clic derecho en la base de datos, seleccione propiedades, vaya a las opciones y cambie la intercalación a la intercalación requerida.
  3. Genere un script para descartar y volver a crear todos sus objetos de base de datos: haga clic con el botón derecho en su base de datos, seleccione tareas, seleccione generar script … (asegúrese de seleccionar y crear en las opciones avanzadas del asistente, también seleccione Esquema y datos)
  4. Ejecute el script generado anteriormente

Compruebe el nivel de colación que no coincide (servidor, base de datos, tabla, columna, carácter).

Si es el servidor, estos pasos me ayudaron una vez:

  1. Detener el servidor
  2. Encuentre su herramienta sqlservr.exe
  3. Ejecute este comando:

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

  4. Comience su servidor sql:

    net start name_of_instance

  5. Compruebe la recostackción de su servidor de nuevo.

Aquí hay más información:

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 ) 

Se agregó código a la respuesta de @SteSteve para tratar con columnas varchar y 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) 

Puede que no tenga ningún problema de intercalación en su base de datos, pero si restauró una copia de su base de datos desde una copia de seguridad en un servidor con una intercalación diferente al origen y su código está creando tablas temporales, esas tablas temporales heredarán la intercalación de el servidor y habría conflictos con su base de datos.