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


91

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

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

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

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

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


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'

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, я думаю, что в любом случае вы получите полное сканирование таблицы.
Джо Стефанелли

Я согласен, но он все равно будет использовать статистику по столбцу, чтобы получить оценку возвращаемых строк, которые могут повлиять на решения о присоединении и т. Д.
Мартин Смит

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.