2017-07-14 90 views
0

我查看了一下,但無法找到能幫助我解決問題的答案。 (最有可能是由於我的技能很差)使用XMLNAMESPACES搜索特定值時遇到問題

但是希望有人能夠指引我朝着正確的方向前進。

問題: 我在查詢表中有一個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> 
</EventD> 

什麼,我需要做的就是去返回「的NewValue」的所有行的「暗戰」

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

然而,這似乎並沒有不返回任何行,如果有人能指出我在這裏做錯了什麼,我會很感激。

由於提前,

+1

這是SQL Server不是MySQL。兩個非常不同的產品 – gbn

+0

1)名稱空間名稱是'http:// example2',而不是'example2'; 2)你不在你的查詢中指定*任何名字空間。使用'e3q1:NewValue',併爲'http:// example1'聲明另一個名稱空間,以便您可以限定'EventD'。 –

回答

1

你確實聲明瞭命名空間e3q1(儘管它缺少了http://而你不使用它亞特...),但是你沒有申報的默認命名空間

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

但這種方法是 - 至少我是這麼認爲的 - 你真的想不是。我認爲你正在尋找.nodes()。接下來的幾行顯示了替代名稱空間替換爲通配符的方法。但我會建議儘可能具體。

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

貌似的Jeroen Mostert已經說明了一切必要的 我只能添加 - 命名空間的名稱並不重要,只有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:*)') 

select 
    @xml.query('(*/*)') 
結果比較
+0

重點是ommited * default *命名空間。你使用'*',通過這個問題,但你不應該使用這種方法... – Shnugo

相關問題