我有一张桌子:
CREATE TABLE MyTable(
Id [int] IDENTITY(1,1) NOT NULL,
XmlField xml NULL,
/// Some other fields
)
XML字段包含C#Dictionary<int, string>
的XML表示。例如:
<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包含的所有行(key = 1,value ='Web'),并且还包含(key = 2,value ='Email')。
到目前为止,我只设法过滤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,Email)和(2,Web)
答案 0 :(得分:3)
这样的事情应该这样做。
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