Cláusula WHERE no tipo de dados “Texto” do SQL Server


89

Onde [CastleType] é definido como tipo de dados "texto" no SQL Server e a consulta é:

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

Recebo o erro:

Os tipos de dados TEXT e VARCHAR são incompatíveis no operador igual a.

Não posso consultar esse tipo de dados com uma cláusula WHERE?


9
Use em VARCHAR(MAX)vez de TEXT- esse tipo de dados está obsoleto
marc_s

Respostas:


99

Você pode usar em LIKEvez de =. Sem qualquer caractere curinga, isso terá o mesmo efeito.

DECLARE @Village TABLE
        (CastleType TEXT)

INSERT INTO @Village
VALUES
  (
    'foo'
  )

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

textestá obsoleto. Mudar para varchar(max)será mais fácil de trabalhar.

Além disso, qual é o tamanho provável dos dados? Se você for fazer comparações de igualdade, o ideal é indexar esta coluna. Isso não é possível se você declarar a coluna como algo maior que 900 bytes, embora você possa adicionar uma coluna computada checksumou hashque pode ser usada para acelerar esse tipo de consulta.


19

Por favor tente isto

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

Isso também é útil para poder ver diretamente os dados no campo TEXT se você estiver usando algumas ferramentas como o Toad para Sql Server que protege campos do tipo BLOB para serem vistos na primeira execução. Você sempre pode clicar no campo para dizer ao Toad para mostrar o campo, mas é um procedimento de duas etapas.
Roger

Observe que isso provavelmente tornará sua consulta não-sargável .
Heinzi

13

Você não pode comparar textcom o =operador, mas deve usar uma das funções de comparação listadas aqui . Observe também a grande caixa de aviso no topo da página, é importante.


5

Se você não pode alterar o tipo de dados na própria tabela para usar varchar (max), altere sua consulta para este:

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

2

Não é isso que diz a mensagem de erro. Diz que você não pode usar a =operadora. Experimente, por exemplo LIKE 'foo'.


Col IN ('foo', 'bar')é basicamente o mesmo que Col = 'foo' or Col = 'bar'e terá o mesmo problema.
Martin Smith

@Martin: Obrigado pelo destaque, não sabia sobre isso. Vou corrigir então.
Will Marcouiller

0

Outra opção seria:

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

Suspeito que isso like 'foo'possa fornecer melhores estimativas de cardinalidade do que essa abordagem, mas não estou 100% certo.
Martin Smith

@Martin: Como você não pode indexar uma coluna TEXT, acho que você terminará com uma varredura completa da tabela em ambos os casos.
Joe Stefanelli

Eu concordo, mas ainda usará estatísticas na coluna para obter uma estimativa das linhas que serão retornadas, o que pode afetar as decisões de junção etc.
Martin Smith

0

Isso funciona em MSSQL e MySQL:

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

1
OP está usando MSSQL, não MySQL.
Deckard de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.