El otro dia usando tablas temporales para resolver una consulta me dio entre error al hacer un INNER JOIN entre una tabla un una tabla temporal que había creado
Mens. 468, Nivel 16, Estado 9, Línea 21
No se puede resolver el conflicto de intercalación entre "Modern_Spanish_CI_AS" y "Modern_Spanish_CI_AS_WS" de la operación equal to.
Investigando un poco logré encontrar cual era el problema, así que voy a tratar de explicarlo con un ejemplo bastante simple.
Primero, creamos una tabla simple, con un campo entero y un campo varchar
CREATE TABLE [dbo].[Foo]
(
[IdFoo] [int] NOT NULL,
[Text] [varchar](50) NOT NULL,
)
Ahora creamos una tabla temporal, que tenga el mismo esquema que la tabla anterior
CREATE TABLE #Bar
(
[IdBar] int NOT NULL,
[Text] varchar(50) NOT NULL
)
Y ahora simplemente hagamos un INNER JOIN entre estas tablas por el campo Text (se que no es normal, pero me sirve para este ejemplo)
SELECT *
FROM Foo f
INNER JOIN #Bar b ON f.Text = b.Text
Y ahí tenemos nuestro error
Mens. 468, Nivel 16, Estado 9, Línea 21
No se puede resolver el conflicto de intercalación entre "Modern_Spanish_CI_AS" y "Modern_Spanish_CI_AS_WS" de la operación equal to.
El motivo es que la tabla "real" y la "temporal" tienen "collations" distintos. Para comprobar esto podemos ejecutar lo siguiente
SELECT db_name() as db, TABLE_NAME, COLUMN_NAME, COLLATION_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Foo'
AND TABLE_SCHEMA = current_user
AND COLUMN_NAME = 'Text'
SELECT 'tempdb' as db, TABLE_NAME, COLUMN_NAME, COLLATION_NAME
FROM tempdb.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME like '#Bar%'
AND TABLE_SCHEMA = current_user
AND COLUMN_NAME = 'Text'
Y obtendremos lo siguiente
| foodb |
Foo |
Text |
Modern_Spanish_CI_AS_WS |
| tempdb |
#Bar________________________________________________________________________________________________________________000000000020 |
Text |
Modern_Spanish_CI_AS |
Como vemos los "esquemas son distintos", ya que la tabla temporal #foo se ha creado en la base de datos tempdb y esta tiene otro esquema al de nuestra base de datos. Para evitar esto, lo que tenemos que hacer, es crear la tabla temporal con el mismo esquema que la usamos en nuestra base de datos. Para esto, sólo hay que hacer lo siguiente
CREATE TABLE #Bar
(
[IdBar] int NOT NULL,
[Text] varchar(50) COLLATE database_default NOT NULL
)
Si ahora consultamos los esquemas, veremos que son idénticos y que nos permite hacer el INNER JOIN sin problemas.