2014-01-09 30 views
1

我有一個表作爲這樣:如何在多個條件篩選的XML字段

CREATE TABLE MyTable(
    Id [int] IDENTITY(1,1) NOT NULL, 
    XmlField xml NULL, 
    /// Some other fields 
) 

的XML字段包含的C#Dictionary<int, string> XML表示。 E.g:

<dictionary> 
    <item> 
     <key><int>1</int></key> 
     <value><string>Web</string></value> 
    </item> 
    <item> 
     <key><int>2</int></key> 
     <value><string>Email</string></value> 
    </item> 
    // more item 
</dictionary> 

我想要做的就是選擇其中XmlField包含所有行(鍵= 1值=「網絡」),並且還包含(與關鍵值= 2 =「電子郵件」)。

到目前爲止,我只設法過濾行1唯一鍵/值匹配:

SELECT TableId, XmlField FROM MyTable 
CROSS APPLY XmlField.nodes('/dictionary/item') x(fields) 
WHERE (x.fields.value('(key/int/text())[1]', 'int') = 1 
AND x.fields.value('(value/string/text())[1]', 'varchar(MAX)') = 'Web') 

如果我添加AND (x.fields.value('(key/int/text())[1]', 'int') = 2 AND x.fields.value('(value/string/text())[1]', 'varchar(MAX)') = 'Email')那麼不返回任何結果(順理成章)。

我也曾嘗試不使用CROSS APPLY,做一個簡單的過濾器,例如:

SELECT TableId, XmlField FROM MyTable 
WHERE XmlField.exist('/dictionary/item/key/int[text() = 1]') = 1 
AND XmlField.exist('/dictionary/item/value/string[text() = "Web"]') = 1 

但後來它就像一個OR和將返回行,其中的XML包含2鍵值對,例如( 1,電子郵件)和(2,Web)

回答

2

這樣的事情應該這樣做。

select * 
from MyTable as T 
where T.XmlField.exist('/dictionary[item[key/int/text() = 1 and value/string/text() = "Web"] and 
            item[key/int/text() = 2 and value/string/text() = "Email"]]') = 1 
+0

簡單完美。看起來我需要一個XPath的速成課程!非常感謝 – Johann