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?

mmcglynn
fonte
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.

Martin Smith
fonte
19

Por favor tente isto

SELECT *
FROM   [Village]
WHERE  CONVERT(VARCHAR, CastleType) = 'foo'
Emma Thapa
fonte
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.

Donnie
fonte
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'
SoggyBottomBoy
fonte
2

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

Will Marcouiller
fonte
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
Joe Stefanelli
fonte
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%'; 
Oi cara
fonte
1
OP está usando MSSQL, não MySQL.
Deckard de