Question

J'ai un tableau comme tel :

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

Le champ XML contient une représentation XML d'un C# Dictionary<int, string>.Par exemple :

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

Ce que je veux faire, c'est sélectionner toutes les lignes où XmlField contient (clé = 1 avec valeur = 'Web') et contient également (clé = 2 avec valeur = 'Email').

Jusqu'à présent, je n'ai réussi à filtrer les lignes que pour une seule correspondance clé/valeur :

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

Si j'ajoute AND (x.fields.value('(key/int/text())[1]', 'int') = 2 AND x.fields.value('(value/string/text())[1]', 'varchar(MAX)') = 'Email') alors rien n'est renvoyé (assez logiquement).

J'ai également essayé de ne pas utiliser CROSS APPLY et faites un simple filtre en tant que tel :

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

Mais alors il agit comme un OR et renverrait des lignes où le XML contient 2 paires clé-valeur telles que (1, Email) et (2, Web)

Était-ce utile?

La solution

Quelque chose comme ça devrait le faire.

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top