我有一张这样的桌子:

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

XML字段包含C的XML表示形式# Dictionary<int, string>.例如 :

<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=1with value='Web'),并且还包含(key=2with 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,电子邮件)和(2,Web)

有帮助吗?

解决方案

像这样的事情应该做到这一点。

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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top