WHERE klauzula dotycząca typu danych „Text” programu SQL Server

91

Gdzie [CastleType] jest ustawiony jako typ danych „tekst” w SQL Server, a zapytanie to:

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

Wyskakuje mi błąd:

Typy danych TEXT i VARCHAR są niezgodne w przypadku operatora równości.

Czy nie mogę zapytać o ten typ danych za pomocą klauzuli WHERE?

mmcglynn
źródło
9
Użyj VARCHAR(MAX)zamiast TEXT- ten typ danych jest przestarzały
marc_s

Odpowiedzi:

101

Możesz użyć LIKEzamiast =. Bez żadnych symboli wieloznacznych będzie to miało ten sam efekt.

DECLARE @Village TABLE
        (CastleType TEXT)

INSERT INTO @Village
VALUES
  (
    'foo'
  )

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

textjest przestarzałe. Zmiana na varchar(max)będzie łatwiejsza w obsłudze.

Jak duże będą prawdopodobnie dane? Jeśli zamierzasz przeprowadzać porównania równości, najlepiej zindeksować tę kolumnę. Nie jest to możliwe, jeśli zadeklarujesz kolumnę jako inną niż 900 bajtów, chociaż możesz dodać kolumnę obliczoną checksumlub hashkolumnę, której można użyć do przyspieszenia tego typu zapytania.

Martin Smith
źródło
21

Spróbuj tego

SELECT *
FROM   [Village]
WHERE  CONVERT(VARCHAR, CastleType) = 'foo'
Emma Thapa
źródło
Jest to również przydatne, aby móc bezpośrednio zobaczyć dane w polu TEKST, jeśli używasz niektórych narzędzi, takich jak Toad dla serwera Sql, które chronią pola typu BLOB, które są widoczne przy pierwszym wykonaniu. Zawsze możesz kliknąć pole, aby nakazać Ropuchowi wyświetlenie pola, ale jest to procedura dwuetapowa.
Roger
Zauważ, że prawdopodobnie spowoduje to, że twoje zapytanie będzie niemożliwe do sargowania .
Heinzi,
13

Nie można porównywać textz =operatorem, ale zamiast tego należy użyć jednej z wymienionych tutaj funkcji porównania . Zwróć także uwagę na duże pole ostrzegawcze u góry strony, jest to ważne.

Donnie
źródło
5

Jeśli nie możesz zmienić typu danych w samej tabeli, aby używać varchar (max), zmień zapytanie na to:

SELECT *
FROM   [Village]
WHERE  CONVERT(VARCHAR(MAX), [CastleType]) = 'foo'
SoggyBottomBoy
źródło
2

Nie o tym mówi komunikat o błędzie. Mówi, że nie możesz użyć =operatora. Spróbuj na przykład LIKE 'foo'.

Will Marcouiller
źródło
Col IN ('foo', 'bar')jest w zasadzie taki sam jak Col = 'foo' or Col = 'bar'i będzie miał ten sam problem.
Martin Smith
@Martin: Dzięki za wyróżnienie, nie wiedziałem o tym. W takim razie poprawię to.
Will Marcouiller,
0

Inną opcją byłoby:

SELECT * FROM [Village] WHERE PATINDEX('foo', [CastleType]) <> 0
Joe Stefanelli
źródło
Podejrzewam, że like 'foo'może to dać lepsze szacunki kardynalności niż to podejście, ale nie jestem w 100% pewien.
Martin Smith
@Martin: Ponieważ nie możesz zindeksować kolumny TEKST, myślę, że w obu przypadkach skończysz z pełnym skanem tabeli.
Joe Stefanelli
Zgadzam się, ale nadal będzie używał statystyk z kolumny, aby uzyskać szacunkową liczbę wierszy, które zostaną zwrócone, co może wpłynąć na decyzje dotyczące łączenia itp.
Martin Smith
0

Działa to w MSSQL i MySQL:

SELECT *
FROM   Village
WHERE  CastleType LIKE '%foo%'; 
cześć mężczyzno
źródło
1
OP używa MSSQL, a nie MySQL.
Deckard