2008-10-10 9 views
35

J'ai une requête qui fonctionnait bien sur SQL2005 mais le déplacement de la base de données vers SQL2008 me donne l'erreur du titre.7645 Prédicat plein texte vide ou vide

Le code qui constitue le problème est un appel à CONTAINS, CONTAINSTABLE ou FREETEXT avec un paramètre vide. Cependant, je suis en train de seulement appel ou rejoindre quand il y a une valeur comme telle

where (@search_term = '' or (FREETEXT(lst.search_text, @search_term))) 

ou

left join containstable (listing_search_text, search_text, @search_term) ftb on l.listing_id = ftb.[key] 
    and len(@search_term) > 0 

Cependant, je ne peux trouver aucune solution de contournement pour que cela fonctionne sur SQL2008. Des idées?

Je sais que je peux faire SQL dynamique ou une instruction if avec deux cas différents (sélectionner avec FT JOIN, sélectionnez sans FT joindre. Toute meilleure solution qui ne nécessite pas le faire?

Répondre

52

J'ai trouvé la réponse à ce jour lors de la conversion ma propre base de données SQL 2005 vers SQL 2008.

col "" pour votre terme de recherche et changer le @search_term = '' test pour être @search_term = '""' serveur SQL ignore les guillemets doubles et non une erreur.

Par exemple, les éléments suivants se retourne en fait tous les enregistrements de la table des utilisateurs:

declare @SearchTerm nvarchar(250) 

SET @SearchTerm = '""' 

select UserId, U.Description, U.UserName 
from dbo.Users U 
WHERE ((@SearchTerm = '""') OR CONTAINS((U.Description, U.UserName), @SearchTerm)) 

Si vous utilisez .Net, vous pourriez récupérer une copie de la classe FullTextSearch E. W. Bachtal. Son site est très instructif:

+0

Merci Chris, qui a fixé le! –

+0

Merci l'homme ... vous avez sauvé mes HEURES! Bonne journée; – effkay

+3

(@SearchTerm = '""') le prédicat ajoute une quantité extrême de lectures et les temps d'attente de requête occasionnellement (comme indiqué par Whiplashtony) –

14

Cette solution n'a pas fonctionné pour moi sur SQL 2008. La réponse a semblé assez claire et a été jugée utile mais j'aurais des temps morts sur une table avec 2M dossiers. En fait, il a bloqué un serveur exécutant la requête dans SSMS.

Il ne semblait pas aimer le OU dans la clause where, mais je pourrais bien exécuter la requête en séparant les conditions. J'ai fini par utiliser UNION avec succès comme une solution de contournement.

declare @SearchTerm nvarchar(250) 

SET @SearchTerm = '""' 

select UserId, U.Description, U.UserName 
from dbo.Users U 
WHERE ((@SearchTerm = '""') 

UNION 

select UserId, U.Description, U.UserName 
from dbo.Users U 
WHERE CONTAINS((U.Description, U.UserName), @SearchTerm)) 
+3

Le problème que vous avez probablement est dû au fait que celui que j'ai est loin d'être optimisé . Dernièrement, j'ai découvert que l'utilisation des UNIONs à la place des OR dans les clauses WHERE s'exécute plusieurs fois plus vite.Donc, +1 – NotMe

+0

J'ai eu une requête avec des tonnes de LIKE et des caractères génériques de premier plan qui couraient comme un chien. J'avais essayé l'indexation de texte intégral qui n'a pas aidé du tout. L'utilisation des UNIONs au lieu des ORs a permis à ma requête de passer de ~ 15 secondes à moins de 1. +1 !!!! – Melanie

+0

Et si j'avais une jointure interne entre deux tables et que je voulais faire une recherche en texte intégral sur les deux tables? cela signifie que je vais avoir besoin de 3-4 syndicats? –

1

Le problème avec FTS et l'opérande OR a été corrigé dans SP2 CU4. La condition OU devrait fonctionner correctement sans avoir à UNION si vous êtes à ce niveau ou plus tard. Nous avons essayé une mise à jour très récente de SP2 CU8 et FTS fonctionne avec OR maintenant. En outre, les recherches telles que 3.12 qui échoueraient avant fonctionnent maintenant très bien.

0

Just ADD Guillemets doubles. Vous pouvez rechercher une chaîne vide, puis ajouter des guillemets.

Set @search_term = case when @search_term = '' then '""' else @Address End 

Ici, vous allez -

where (@search_term = '""' or (FREETEXT(lst.search_text, @search_term)))