WHERE-Klausel für den SQL Server-Datentyp "Text"


89

Wobei [CastleType] in SQL Server als Datentyp "Text" festgelegt ist und die Abfrage lautet:

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

Ich bekomme den Fehler:

Die Datentypen TEXT und VARCHAR sind im Operator gleich nicht kompatibel.

Kann ich diesen Datentyp nicht mit einer WHERE-Klausel abfragen?


9
Verwenden Sie VARCHAR(MAX)anstelle von TEXT- dieser Datentyp ist veraltet
marc_s

Antworten:


99

Sie können LIKEanstelle von verwenden =. Ohne Platzhalter hat dies den gleichen Effekt.

DECLARE @Village TABLE
        (CastleType TEXT)

INSERT INTO @Village
VALUES
  (
    'foo'
  )

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

textist veraltet. Das Wechseln zu varchar(max)ist einfacher zu bearbeiten.

Wie groß sind die Daten wahrscheinlich? Wenn Sie Gleichheitsvergleiche durchführen möchten, sollten Sie diese Spalte idealerweise indizieren. Dies ist nicht möglich, wenn Sie die Spalte als breiter als 900 Byte deklarieren. Sie können jedoch eine berechnete Spalte checksumoder hashSpalte hinzufügen , mit der diese Art von Abfrage beschleunigt werden kann.


19

Bitte versuchen Sie dies

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

Dies ist auch nützlich, um die Daten im TEXT-Feld direkt anzeigen zu können, wenn Sie einige Tools wie Toad for SQL Server verwenden, die BLOB-Felder schützen, die bei der ersten Ausführung angezeigt werden. Sie können jederzeit auf das Feld klicken, um Toad anzuweisen, das Feld anzuzeigen. Dies erfolgt jedoch in zwei Schritten.
Roger

Beachten Sie, dass dies Ihre Anfrage wahrscheinlich nicht sarkierbar macht .
Heinzi

13

Sie können nicht textmit dem =Operator vergleichen, sondern müssen stattdessen eine der hier aufgeführten Vergleichsfunktionen verwenden . Beachten Sie auch das große Warnfeld oben auf der Seite, es ist wichtig.


5

Wenn Sie den Datentyp in der Tabelle selbst nicht ändern können, um varchar (max) zu verwenden, ändern Sie Ihre Abfrage wie folgt:

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

2

Das steht nicht in der Fehlermeldung. Es heißt, dass Sie den =Operator nicht verwenden können. Versuchen Sie es zum Beispiel LIKE 'foo'.


Col IN ('foo', 'bar')ist im Grunde das gleiche wie Col = 'foo' or Col = 'bar'und wird das gleiche Problem haben.
Martin Smith

@ Martin: Danke für das Highlight, ich wusste nichts davon. Ich werde es dann korrigieren.
Will Marcouiller

0

Eine andere Option wäre:

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

Ich vermute, like 'foo'dass dies zu besseren Kardinalitätsschätzungen führen könnte als dieser Ansatz, bin mir aber nicht 100% sicher.
Martin Smith

@Martin: Da Sie eine TEXT-Spalte nicht indizieren können, werden Sie in beiden Fällen wahrscheinlich einen vollständigen Tabellenscan erhalten.
Joe Stefanelli

Ich bin damit einverstanden, aber es werden weiterhin Statistiken für die Spalte verwendet, um eine Schätzung der zurückgegebenen Zeilen zu erhalten, die sich auf Beitrittsentscheidungen usw. auswirken können.
Martin Smith

0

Dies funktioniert in MSSQL und MySQL:

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

1
OP verwendet MSSQL, nicht MySQL.
Deckard
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.