Cláusula WHERE en el tipo de datos "Texto" de SQL Server


91

Donde [CastleType] se establece como tipo de datos "texto" en SQL Server y la consulta es:

SELECT *
FROM   [Village]
WHERE  [CastleType] = 'foo' 

Me sale el error:

Los tipos de datos TEXT y VARCHAR son incompatibles en el operador igual a.

¿No puedo consultar este tipo de datos con una cláusula WHERE?


9
Usar en VARCHAR(MAX)lugar de TEXT- ese tipo de datos está obsoleto
marc_s

Respuestas:


101

Puede usar en LIKElugar de =. Sin comodines, esto tendrá el mismo efecto.

DECLARE @Village TABLE
        (CastleType TEXT)

INSERT INTO @Village
VALUES
  (
    'foo'
  )

SELECT *
FROM   @Village
WHERE  [CastleType] LIKE 'foo' 

textes obsoleto. Cambiar a varchar(max)será más fácil de trabajar.

Además, ¿cuál es el tamaño probable de los datos? Si va a hacer comparaciones de igualdad, idealmente querrá indexar esta columna. Esto no es posible si declara que la columna tiene un ancho superior a 900 bytes, aunque puede agregar una columna calculada checksumo hashque se pueda usar para acelerar este tipo de consulta.


21

Por favor intente esto

SELECT *
FROM   [Village]
WHERE  CONVERT(VARCHAR, CastleType) = 'foo'

Esto también es útil para poder ver directamente los datos en el campo TEXT si está utilizando algunas herramientas como Toad for Sql Server que protegen los campos de tipo BLOB para que se vean en la primera ejecución. Siempre puedes hacer clic en el campo para decirle a Toad que muestre el campo, pero es un procedimiento de dos pasos.
Roger

Tenga en cuenta que esto probablemente hará que su consulta no sea sargable .
Heinzi

13

No puede comparar textcon el =operador, sino que debe utilizar una de las funciones de comparación enumeradas aquí . También tenga en cuenta el cuadro de advertencia grande en la parte superior de la página, es importante.


5

Si no puede cambiar el tipo de datos en la tabla para usar varchar (max), cambie su consulta a esto:

SELECT *
FROM   [Village]
WHERE  CONVERT(VARCHAR(MAX), [CastleType]) = 'foo'

2

Eso no es lo que dice el mensaje de error. Dice que no puede utilizar el =operador. Prueba, por ejemplo LIKE 'foo'.


Col IN ('foo', 'bar')es básicamente el mismo Col = 'foo' or Col = 'bar'y tendrá el mismo problema.
Martin Smith

@Martin: Gracias por lo más destacado, no lo sabía. Entonces lo corregiré.
Will Marcouiller

0

Otra opcion seria:

SELECT * FROM [Village] WHERE PATINDEX('foo', [CastleType]) <> 0

Sospecho que like 'foo'podría dar mejores estimaciones de cardinalidad que este enfoque, pero no estoy 100% seguro.
Martin Smith

@Martin: Como no puede indexar una columna de TEXTO, creo que terminará con un escaneo completo de la tabla en cualquier caso.
Joe Stefanelli

Estoy de acuerdo, pero todavía usará estadísticas en la columna para obtener una estimación de las filas que se devolverán, lo que podría afectar las decisiones de unión, etc.
Martin Smith

0

Esto funciona en MSSQL y MySQL:

SELECT *
FROM   Village
WHERE  CastleType LIKE '%foo%'; 

1
OP está utilizando MSSQL, no MySQL.
Deckard
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.