Ver Mensaje Individual
  #9 (permalink)  
Antiguo 09/08/2016, 16:38
Avatar de Libras
Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Problema con el COLLATE

Vamos a ver donde esta el problema:

Creamos 1 tabla

El collate por default de mi servidor es: Modern_Spanish_CI_AS

Código SQL:
Ver original
  1. CREATE TABLE testing
  2. (
  3. valor1 VARCHAR(20),
  4. valor2 VARCHAR(20),
  5. valor3 VARCHAR(20)
  6. )
  7.  
  8. --Ejecutamos algunas veces este query:
  9. INSERT INTO testing VALUES ('AAAAA','BBBB','CCCC')

Ahora creamos 3 tablas para usar diferentes collations:

Código SQL:
Ver original
  1. SELECT VALUE = valor1, value2=valor2, value3=valor3 COLLATE Modern_Spanish_CI_AS INTO collate_1 FROM testing
  2. SELECT VALUE = valor1, value2=valor2, value3=valor3 COLLATE SQL_Latin1_General_CP1_CI_AS INTO collate_2 FROM testing
  3. SELECT VALUE = valor1, value2=valor2, value3=valor3 COLLATE SQL_Latin1_General_CP1_CI_AS INTO collate_3 FROM testing

Hacemos un query con un join:

Código SQL:
Ver original
  1. SELECT t1.VALUE  ,t1.value2  ,t1.value3 , t2.VALUE  , t2.value2  , t2.value3  
  2. FROM collate_1 AS t1
  3. INNER JOIN collate_3  AS t2 ON (t1.VALUE  = t2.VALUE  )
  4. UNION ALL
  5. SELECT t1.VALUE,t1.value2,t1.value3, t2.VALUE, t2.value2, t2.value3   FROM collate_2 AS t1
  6. INNER JOIN collate_3 AS t2 ON (t1.VALUE=t2.VALUE)

y nos manda el error:

Mens. 457, Nivel 16, Estado 1, Línea 1
No se puede realizar la conversión implícita del valor varchar a varchar porque la intercalación del valor no está resuelta a causa de un conflicto de intercalación entre "SQL_Latin1_General_CP1_CI_AS" y "Modern_Spanish_CI_AS" en el operador UNION ALL.

ahora hacemos un query usando collate:

Código SQL:
Ver original
  1. SELECT t1.VALUE  ,t1.value2  ,t1.value3 , t2.VALUE  , t2.value2  , t2.value3  COLLATE DATABASE_DEFAULT
  2. FROM collate_1 AS t1
  3. INNER JOIN collate_3  AS t2 ON (t1.VALUE  = t2.VALUE  )
  4. UNION ALL
  5. SELECT t1.VALUE,t1.value2,t1.value3, t2.VALUE, t2.value2, t2.value3   FROM collate_2 AS t1
  6. INNER JOIN collate_3 AS t2 ON (t1.VALUE=t2.VALUE)
Nos vuelve a mandar error.......Verificamos el collate de nuestras tablas:

Código SQL:
Ver original
  1. SELECT
  2.     col.name, col.collation_name
  3. FROM
  4.     sys.COLUMNS col
  5. WHERE
  6.     object_id = OBJECT_ID('collate_1')
  7.  
  8. --value Modern_Spanish_CI_AS
  9. --value2    Modern_Spanish_CI_AS
  10. --value3    Modern_Spanish_CI_AS
  11.  
  12. SELECT
  13.     col.name, col.collation_name
  14. FROM
  15.     sys.COLUMNS col
  16. WHERE
  17.     object_id = OBJECT_ID('collate_2')
  18.  
  19. --value Modern_Spanish_CI_AS
  20. --value2    Modern_Spanish_CI_AS
  21. --value3    SQL_Latin1_General_CP1_CI_AS
  22.  
  23. SELECT
  24.     col.name, col.collation_name
  25. FROM
  26.     sys.COLUMNS col
  27. WHERE
  28.     object_id = OBJECT_ID('collate_3')
  29.  
  30. --value Modern_Spanish_CI_AS
  31. --value2    Modern_Spanish_CI_AS
  32. --value3    SQL_Latin1_General_CP1_CI_AS

Y vemos que en 2 de ellas tenemos un collate diferente, para eso usamos el siguiente query:

Código SQL:
Ver original
  1. SELECT t1.VALUE  ,t1.value2  ,t1.value3 COLLATE database_default, t2.VALUE  , t2.value2  , t2.value3  COLLATE DATABASE_DEFAULT
  2. FROM collate_1 AS t1
  3. INNER JOIN collate_3  AS t2 ON (t1.VALUE  = t2.VALUE  )
  4. UNION ALL
  5. SELECT t1.VALUE,t1.value2,t1.value3, t2.VALUE, t2.value2, t2.value3   FROM collate_2 AS t1
  6. INNER JOIN collate_3 AS t2 ON (t1.VALUE=t2.VALUE)
Y nos regresa el resultado :), aqui lo que hay que tomar en cuenta son las columnas con collate diferente, revisa las de tu base de datos y ve cuales necesitas incluir en tu query :)

P.D: Tambien se puede usar en lugar del collate database_default el collate correspondiente en mi caso Modern_Spanish_CI_AS
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me

Última edición por Libras; 09/08/2016 a las 16:44