2012-06-14 62 views
0

這可能很簡單,我只是沒有正確地使用大括號,但由於我幾乎沒有查詢SQL SERVER XML數據的經驗,所以這使我瘋了。如何在Sql Server 2008中的XML列中使用WHERE屬性

我有一個簡單的表,帶有一個XML類型的列NoSqlField。這包含NULL或

<root version="1.0"> 
    <entry key="mykey">1</entry> 
</root> 

我想在表中有一個<輸入鍵=「的myKey」 /進入他們NoSqlField列>值的所有行。

A(而不是愚蠢的,因爲它使用的ToString())使用

where h.NoSqlField.ToString().IndexOf("<entry key=\"mykey\">1</entry>") > -1 

返回結果LINQ查詢,所以它肯定有。

如何在T-SQL中運行相同的查詢?我已經在各種變化試圖

SELECT * FROM mytable WHERE 
NoSqlField.value('(//entry[@key=mykey])[1]','varchar(1)') = '1' 

(有和沒有斜槓,完整路徑,...),但從來沒有得到一個返回的行。

回答

1

解決方案1: 如果你想檢查NoSqlField列具有//root/entry元素,這個元素包含1(內文),那麼你可以使用此解決方案:

SET ANSI_WARNINGS ON; 
GO 

DECLARE @TestData TABLE (
    ID INT IDENTITY PRIMARY KEY, 
    NoSqlField XML NULL 
); 

INSERT @TestData (NoSqlField) 
SELECT NULL 
UNION ALL 
SELECT ' 
<root version="1.0"> 
    <entry key="mykey">1</entry> 
</root>' 
UNION ALL 
SELECT ' 
<root version="1.0"> 
    <entry key="mykey" anotherkey="myanotherkey">1</entry> 
</root>' 
UNION ALL 
SELECT ' 
<root version="1.0"> 
    <entry key="anotherkey" key2="a">1</entry> 
</root>' 
UNION ALL 
SELECT ' 
<root version="1.0"> 
    <entry key="mykey" key3="3">22</entry> 
</root>'; 

SELECT * 
FROM @TestData t 
WHERE t.NoSqlField.exist('//root/entry[@key="mykey"][text() = "1"]') = 1 

結果:

ID NoSqlField 
-- --------------------------------------------------------------------------------- 
2 <root version="1.0"><entry key="mykey">1</entry></root> 
3 <root version="1.0"><entry key="mykey" anotherkey="myanotherkey">1</entry></root> 

注1:您可以看到此解決方案允許(存在)其他屬性(例如anotherkey)。

解決方案2: 如果你想有一個嚴格的過濾器(只有一個屬性entry元素:key),那麼你可以使用此查詢:

SELECT * 
FROM 
(
     SELECT * 
       ,t.NoSqlField.exist('//root/entry[@key="mykey"][text() = 1]') AS XmlExist 
       ,t.NoSqlField.query(' 
        let $list := //root/entry/@* 
        for $i in $list 
        where local-name($i) != "key" 
         return <ret value="1"/> 
       ').exist('//ret') AS HasAnotherAttribute 
     FROM @TestData t 
) src 
WHERE src.XmlExist = 1 
AND  src.HasAnotherAttribute = 0 

結果:

ID NoSqlField            XmlExist HasAnotherAttribute 
-- ------------------------------------------------------- -------- ------------------- 
2 <root version="1.0"><entry key="mykey">1</entry></root> 1  0 

注2:let $list := //root/entry/@*將使用來自//root/entry元素的所有(@ *)屬性構建一個列表。

注3:local-name()

+0

它的工作原理(我試過解決方案1,但肯定會研究2號爲好。)!就這樣!正是我在找什麼。非常感謝! – Olaf

相關問題