Clause WHERE sur le type de données «Texte» SQL Server

89

Où [CastleType] est défini comme type de données "texte" dans SQL Server et la requête est:

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

J'obtiens l'erreur:

Les types de données TEXT et VARCHAR sont incompatibles dans l'opérateur égal à.

Puis-je ne pas interroger ce type de données avec une clause WHERE?

mmcglynn
la source
9
Utiliser à la VARCHAR(MAX)place de TEXT- ce type de données est obsolète
marc_s

Réponses:

99

Vous pouvez utiliser à la LIKEplace de =. Sans aucun joker, cela aura le même effet.

DECLARE @Village TABLE
        (CastleType TEXT)

INSERT INTO @Village
VALUES
  (
    'foo'
  )

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

textest obsolète. Changer en varchar(max)sera plus facile à utiliser.

Quelle est également la taille probable des données? Si vous comptez faire des comparaisons d'égalité, vous voudrez idéalement indexer cette colonne. Cela n'est pas possible si vous déclarez la colonne comme étant plus large que 900 octets, mais vous pouvez ajouter une colonne calculée checksumou hashqui peut être utilisée pour accélérer ce type de requête.

Martin Smith
la source
19

Veuillez essayer ceci

SELECT *
FROM   [Village]
WHERE  CONVERT(VARCHAR, CastleType) = 'foo'
Emma Thapa
la source
Ceci est également utile pour pouvoir voir directement les données dans le champ TEXT si vous utilisez certains outils comme Toad pour Sql Server qui protègent les champs de type BLOB à voir lors de la première exécution. Vous pouvez toujours cliquer sur le champ pour dire à Toad d'afficher le champ, mais c'est une procédure en deux étapes.
Roger le
Notez que cela rendra probablement votre requête non sargable .
Heinzi
13

Vous ne pouvez pas comparer textavec l' =opérateur, mais à la place, vous devez utiliser l'une des fonctions de comparaison répertoriées ici . Notez également la grande boîte d'avertissement en haut de la page, c'est important.

Donnie
la source
5

Si vous ne pouvez pas modifier le type de données sur la table elle-même pour utiliser varchar (max), modifiez votre requête comme suit:

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

Ce n'est pas ce que dit le message d'erreur. Il dit que vous ne pouvez pas utiliser l' =opérateur. Essayez par exemple LIKE 'foo'.

Will Marcouiller
la source
Col IN ('foo', 'bar')est fondamentalement le même Col = 'foo' or Col = 'bar'et aura le même problème.
Martin Smith
@Martin: Merci pour le clou, je n'en savais rien. Je vais le corriger alors.
Will Marcouiller
0

Une autre option serait:

SELECT * FROM [Village] WHERE PATINDEX('foo', [CastleType]) <> 0
Joe Stefanelli
la source
Je soupçonne que cela like 'foo'pourrait donner de meilleures estimations de cardinalité que cette approche, mais je ne suis pas sûr à 100%.
Martin Smith
@Martin: Puisque vous ne pouvez pas indexer une colonne TEXT, je pense que vous vous retrouverez avec une analyse complète de la table dans les deux cas.
Joe Stefanelli
Je suis d'accord mais il utilisera toujours des statistiques sur la colonne pour obtenir une estimation des lignes qui seront renvoyées, ce qui pourrait affecter les décisions de jointure, etc.
Martin Smith
0

Cela fonctionne dans MSSQL et MySQL:

SELECT *
FROM   Village
WHERE  CastleType LIKE '%foo%'; 
Salut mec
la source
1
OP utilise MSSQL et non MySQL.
Deckard