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?


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.


19

Veuillez essayer ceci

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

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.


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'

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'.


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

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%'; 

1
OP utilise MSSQL et non MySQL.
Deckard
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.