web-dev-qa-db-fra.com

Utiliser une instruction LIKE sur un type de données SQL Server XML

Si vous avez un champ varchar, vous pouvez facilement faire SELECT * FROM TABLE WHERE ColumnA LIKE '%Test%' pour voir si cette colonne contient une certaine chaîne.

Comment faites-vous cela pour le type XML?

J'ai ce qui suit qui renvoie uniquement les lignes qui ont un nœud 'Texte' mais je dois effectuer une recherche dans ce nœud

select * from WebPageContent where data.exist('/PageContent/Text') = 1
72
Jon

Vous devriez pouvoir le faire assez facilement:

SELECT * 
FROM WebPageContent 
WHERE data.value('(/PageContent/Text)[1]', 'varchar(100)') LIKE 'XYZ%'

Le .value méthode vous donne la valeur réelle et vous pouvez la définir pour qu'elle soit renvoyée sous forme de VARCHAR (), que vous pouvez ensuite vérifier à l'aide d'une instruction LIKE.

Remarquez, cela ne va pas être extrêmement rapide. Donc, si vous avez certains champs dans votre XML que vous devez inspecter beaucoup, vous pouvez:

  • créer une fonction stockée qui récupère le code XML et renvoie la valeur recherchée en tant que VARCHAR ()
  • définir un nouveau champ calculé sur votre table qui appelle cette fonction et en faire une colonne PERSISTED

Avec ceci, vous "extrairez" fondamentalement une certaine partie du code XML dans un champ calculé, le rendre persistant, puis vous pourrez effectuer une recherche très efficace sur celui-ci (diable: vous pouvez même INDEXer ce champ!).

Marc

67
marc_s

Une autre option consiste à convertir le code XML en nvarchar, puis à rechercher la chaîne donnée comme si le code XML était un champ nvarchar.

SELECT * 
FROM Table
WHERE CAST(Column as nvarchar(max)) LIKE '%TEST%'

J'adore cette solution car elle est propre, facile à retenir, difficile à gâcher et peut être utilisée dans le cadre d'une clause where.

EDIT: Comme Cliff le mentionne, vous pouvez utiliser:

... nvarchar s'il y a des caractères qui ne sont pas convertis en varchar

63
Squazz

Une autre option consiste à rechercher le XML en tant que chaîne en le convertissant en chaîne puis en utilisant LIKE. Cependant, comme une colonne calculée ne peut pas faire partie d'une clause WHERE, vous devez l'envelopper dans un autre SELECT comme ceci:

SELECT * FROM
    (SELECT *, CONVERT(varchar(MAX), [COLUMNA]) as [XMLDataString] FROM TABLE) x
WHERE [XMLDataString] like '%Test%'
10
Carl Onager

Voici ce que je vais utiliser en fonction de la réponse de marc_s:

SELECT 
SUBSTRING(DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)'),PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')) - 20,999)

FROM WEBPAGECONTENT 
WHERE COALESCE(PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')),0) > 0

Renvoyer une sous-chaîne sur la recherche où les critères de recherche existent

0
Jon