sql-server - microsoft - sql server descargar
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 (22)
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
Al ejecutar el código, el error se pega 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 esta db Mi máquina que es el 2005.
@Valkyrie impresionante respuesta. Pensé que puse 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 fue increíble.
...WHERE fieldname COLLATE DATABASE_DEFAULT in ( select distinct otherfieldname COLLATE DATABASE_DEFAULT from ... where ... )
ALTER DATABASE test2 - ponga aquí el nombre de su base de datos COLLATE Latin1_General_CS_AS - reemplace con la intercalación que necesite
Compruebe el nivel de intercalación que no coincide (servidor, base de datos, tabla, columna, carácter).
Si es el servidor, estos pasos me ayudaron una vez:
- Detener el servidor
- Encuentra tu herramienta sqlservr.exe
Ejecute este comando:
sqlservr -m -T4022 -T3659 -s"name_of_insance" -q "name_of_collation"
Inicie su servidor SQL:
net start name_of_instance
Revise la colación de su servidor de nuevo.
Aquí hay más información:
https://www.mssqltips.com/sqlservertip/3519/changing-sql-server-collation-after-installation/
En donde los criterios se agregan, se collate SQL_Latin1_General_CP1_CI_AS
Esto funciona para mi
WHERE U.Fullname = @SearchTerm collate SQL_Latin1_General_CP1_CI_AS
Es posible 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 a la del origen, y su código está creando tablas temporales, esas tablas temporales heredarán la intercalación de El servidor y no habría conflictos con su base de datos.
Esto es lo que hicimos. En nuestra situación, necesitamos una consulta ad hoc que se ejecute utilizando una restricción de fecha a pedido, y la consulta se define en una tabla.
Nuestra nueva consulta debe hacer coincidir los datos entre diferentes bases de datos e incluir datos de ambas.
Parece que la COLLATION es diferente entre la base de datos 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.).
Así que 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
Esto puede suceder fácilmente cuando tiene 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
Gracias a la respuesta de marc_s, resolví mi problema original, inspirado para ir un paso más allá y publicar un enfoque para transformar una tabla completa a la vez, el script 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
Admito que estoy desconcertado por la necesidad de col.max_length / 2 -
He tenido algo como esto antes, y lo que encontramos fue que la intercalación entre 2 tablas era diferente.
Comprueba que estos son los mismos.
He utilizado el contenido de este site 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
Identifique los campos para los que está generando este error y agregue lo siguiente: COLLATE DATABASE_DEFAULT
Hay dos tablas unidas en el campo Código:
...
and table1.Code = table2.Code
...
Actualice su consulta a:
...
and table1.Code COLLATE DATABASE_DEFAULT = table2.Code COLLATE DATABASE_DEFAULT
...
La causa principal es que la base de datos del servidor SQL del que tomó el esquema tiene una intercalación que difiere de su instalación local. Si no desea preocuparse por la intercalación, vuelva a instalar SQL Server localmente utilizando la misma intercalación que la base de datos de SQL Server 2008.
Para aquellos que tienen un script CREATE DATABASE (como fue mi caso) para la base de datos que está causando este problema, puede usar el siguiente script 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 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 base de datos con diferente intercalación en el servidor
Podrías hacer esto fácilmente usando 4 sencillos pasos.
- copia de seguridad de su base de datos, solo en caso
- cambie la intercalación de la base de datos: haga clic con el botón derecho en la base de datos, seleccione propiedades, vaya a las opciones y cambie la intercalación a la intercalación requerida.
- Genere un script para eliminar y recrear 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 Eliminar y crear en las opciones avanzadas del asistente, seleccione también Esquema y datos)
- Ejecutar el script generado anteriormente
Se agregó código a la respuesta de @ JustSteve para lidiar con las 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)
Si esto ocurre en toda la base de datos, entonces es mejor cambiar la intercalación de la base de datos 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 here
Tienes una discordancia de dos colaciones diferentes en tu tabla. Puede verificar qué colaciones tiene cada columna en su (s) tabla (s) utilizando esta consulta:
SELECT
col.name, col.collation_name
FROM
sys.columns col
WHERE
object_id = OBJECT_ID(''YourTableName'')
Las colaciones son necesarias y utilizadas al ordenar y comparar cadenas. Por lo general, es una buena idea tener una recopilación única y única utilizada en su base de datos; no use diferentes intercalaciones dentro de una sola tabla o base de datos; solo está buscando problemas ...
Una vez que se haya conformado con una sola recopilación, puede cambiar las tablas / columnas que aún no coinciden con 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 eliminar el índice de texto completo utilizando:
DROP FULLTEXT INDEX ON (tablename)
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 usé el viejo controlador jdbc.
Resolví esto descargando un nuevo controlador de Microsoft o el proyecto de código abierto jTDS .
Utilice 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 sintaxis exactamente correcta (marque BOL), pero puede hacer esto para cambiar la intercalación sobre la marcha de la consulta; es posible que deba agregar la cláusula para cada combinación.
edit: me di cuenta de que esto no era del todo correcto - la cláusula de intercalación va después del campo que necesita cambiar - en este ejemplo, cambié la intercalación en el campo tA.oldValue
.
Yo hago lo siguiente:
...WHERE
fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT
Funciona cada vez. :)
el error (No se puede resolver el conflicto de intercalación entre ...) suele ocurrir al comparar datos de varias bases de datos.
Ya que no puede cambiar la intercalación de bases de datos ahora, use COLLATE DATABASE_DEFAULT.
----------
AND db1.tbl1.fiel1 COLLATE DATABASE_DEFAULT =db2.tbl2.field2 COLLATE DATABASE_DEFAULT
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 )