2017-07-14 3 views
0

J'ai jeté un coup d'œil et je n'ai pas trouvé de réponse qui m'aiderait à résoudre mon problème. (Probablement en raison de mes faibles compétences)Problème de recherche de valeurs spécifiques à l'aide de XMLNAMESPACES

Cependant espérait que quelqu'un serait capable de me diriger dans la bonne direction.

Le problème: J'ai une colonne XML dans la table que j'interroge et j'ai besoin de la requête pour retourner les lignes toutes les lignes avec une valeur spécifique.

Un exemple de la colonne xml

<EventD xmlns="http://example1" xmlns:e3q1="http://example2" xmlns:xsi="http://example3" xsi:type="e3q1:Valuechange"> 
    <e3q1:NewValue>Running</e3q1:NewValue> 
    <e3q1:OldValue>Stopped</e3q1:OldValue> 
</EventD> 

Ce que je besoin de faire est de renvoyer toutes les lignes qui ont « NewValue » comme « Running »

;WITH XMLNAMESPACES ('example2' as e3q1) 
select top 100 
Xml.value('(EventD/NewValue)[1]', 'varchar(100)'), 

* from Table1 
and Xml.value('(EventD/NewValue)[1]', 'varchar(100)') like 'Running' 

Pourtant, cela ne semble pas retourner des lignes du tout, serait vraiment reconnaissant si quelqu'un pouvait signaler ce que je fais mal ici.

Merci à l'avance,

+1

SQL Server n'est pas MySQL. Deux produits très différents – gbn

+0

1) Le nom de l'espace de nommage est 'http: // example2', pas' example2'; 2) vous ne * spécifiez * aucun espace de noms dans vos requêtes. Utilisez 'e3q1: NewValue' et déclarez un autre espace de noms pour' http: // example1' afin de pouvoir qualifier 'EventD'. –

Répondre

1

Vous déclarez l'espace de noms e3q1 (bien qu'il manque le http:// et vous ne l'utilisez pas l ater ...), mais vous ne déclarent pas l'espace de noms par défaut

DECLARE @tbl TABLE([Xml] XML); 
INSERT INTO @tbl VALUES 
(
N'<EventD xmlns="http://example1" xmlns:e3q1="http://example2" xmlns:xsi="http://example3" xsi:type="e3q1:Valuechange"> 
    <e3q1:NewValue>Running</e3q1:NewValue> 
    <e3q1:OldValue>Stopped</e3q1:OldValue> 
</EventD>' 
); 

;WITH XMLNAMESPACES (DEFAULT 'http://example1', 'http://example2' as e3q1) 
SELECT [Xml].value('(EventD/e3q1:NewValue)[1]', 'varchar(100)') 
from @tbl AS Table1 
WHERE Xml.value('(EventD/e3q1:NewValue)[1]', 'varchar(100)') like 'Running'; 

Mais cette approche est - au moins je le crois - pas ce que vous voulez vraiment. Je pense que vous recherchez .nodes(). Les lignes suivantes montrent comme alternative une approche pour remplacer les espaces de noms avec un caractère générique. Mais je recommanderais d'être aussi précis que possible.

SELECT Only.Running.value('text()[1]', 'varchar(100)') 
from @tbl AS Table1 
CROSS APPLY Xml.nodes('*:EventD/*:NewValue[text()="Running"]') AS Only(Running) 
1

On dirait Jeroen Mostert dit déjà tout le nécessaire je ne peux ajouter - nom de l'espace de noms est pas important, que uri

declare @xml xml='<EventD xmlns="http://example1" xmlns:e3q1="http://example2" xmlns:xsi="http://example3" xsi:type="e3q1:Valuechange"> 
    <e3q1:NewValue>Running</e3q1:NewValue> 
    <e3q1:OldValue>Stopped</e3q1:OldValue> 
    <xsi:test>test</xsi:test> 
    <test1>test1</test1> 
</EventD>' 


;WITH XMLNAMESPACES ('http://example2' as test) 
select 
@xml.query('(*/test:*)') 

comparer avec un résultat de

select 
    @xml.query('(*/*)') 
+0

Le point est l'espace de noms ommited * default *. Vous utilisez '*', qui passe par ce problème, mais vous ne devriez pas utiliser cette approche ... – Shnugo