Предложение WHERE для типа данных SQL Server «Текст»

91

Где [CastleType] установлен как тип данных "текст" в SQL Server и запрос:

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

Я получаю сообщение об ошибке:

Типы данных TEXT и VARCHAR несовместимы в операторе равенства.

Могу ли я не запрашивать этот тип данных с помощью предложения WHERE?

mmcglynn
источник
9
Использовать VARCHAR(MAX)вместо TEXT- этот тип данных устарел
marc_s

Ответы:

101

Вы можете использовать LIKEвместо =. Без подстановочных знаков это будет иметь тот же эффект.

DECLARE @Village TABLE
        (CastleType TEXT)

INSERT INTO @Village
VALUES
  (
    'foo'
  )

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

textне рекомендуется. Переход к varchar(max)вам будет легче работать.

Также насколько велики могут быть данные? Если вы собираетесь проводить сравнения на равенство, в идеале вам нужно проиндексировать этот столбец. Это невозможно, если вы объявите столбец размером более 900 байт, хотя вы можете добавить вычисляемый столбец checksumили hashстолбец, который можно использовать для ускорения этого типа запроса.

Мартин Смит
источник
22

Пожалуйста, попробуйте это

SELECT *
FROM   [Village]
WHERE  CONVERT(VARCHAR, CastleType) = 'foo'
Эмма Тапа
источник
Это также полезно, чтобы иметь возможность напрямую видеть данные в поле ТЕКСТ, если вы используете некоторые инструменты, такие как Toad для Sql Server, которые защищают поля типа BLOB, которые будут видны при первом выполнении. Вы всегда можете щелкнуть поле, чтобы указать Toad показать поле, но это двухэтапная процедура.
Роджер
Обратите внимание, что это, вероятно, сделает ваш запрос несаргируемым .
Heinzi
13

Вы не можете сравнивать textс =оператором, вместо этого необходимо использовать одну из функций сравнения, перечисленных здесь . Также обратите внимание на большое окно с предупреждением в верхней части страницы, это важно.

Донни
источник
5

Если вы не можете изменить тип данных в самой таблице для использования varchar (max), измените свой запрос на это:

SELECT *
FROM   [Village]
WHERE  CONVERT(VARCHAR(MAX), [CastleType]) = 'foo'
SoggyBottomBoy
источник
2

В сообщении об ошибке говорится не об этом. Там написано, что нельзя пользоваться =оператором. Попробуйте, например LIKE 'foo'.

Уилл Маркуллер
источник
Col IN ('foo', 'bar')в основном то же самое, Col = 'foo' or Col = 'bar'и будет та же проблема.
Мартин Смит
@Martin: Спасибо за выделение, я не знал об этом. Я тогда поправлю.
Уилл Маркуллер
0

Другой вариант:

SELECT * FROM [Village] WHERE PATINDEX('foo', [CastleType]) <> 0
Джо Стефанелли
источник
Я подозреваю, что это like 'foo'может дать лучшие оценки мощности, чем этот подход, но я не уверен на 100%.
Мартин Смит
@Martin: Поскольку вы не можете проиндексировать столбец TEXT, я думаю, что в любом случае вы получите полное сканирование таблицы.
Джо Стефанелли
Я согласен, но он все равно будет использовать статистику по столбцу, чтобы получить оценку возвращаемых строк, которые могут повлиять на решения о присоединении и т. Д.
Мартин Смит
0

Это работает в MSSQL и MySQL:

SELECT *
FROM   Village
WHERE  CastleType LIKE '%foo%'; 
Привет Чувак
источник
1
OP использует MSSQL, а не MySQL.
Декард