2011-01-04 2 views
1

Dernièrement, je suis époustouflé par xml pour SQL Server, mais celui-ci ici me fait noixPourquoi cette requête XML dans SQL Server fonctionne pas

DECLARE @xml XML; 
SET @xml = ' 
    <ROOT> 
     <Object> 
      <FooProperty1>123</FooProperty1> 
      <FooProperty2>456</FooProperty2> 
     </Object> 
     <Object> 
      <FooProperty1>123</FooProperty1> 
      <FooProperty2>456</FooProperty2> 
     </Object> 
    </ROOT> 
'; 

SELECT [doc].[FooProperty1].value('.', 'INT') AS [fooProperty1], 
     [doc].[FooProperty2].value('.', 'INT') AS [fooProperty2] 
FROM @xml.nodes('/ROOT/Object') 
AS  [doc] 
(
    [FooProperty1], 
    [FooProperty2] 
) 

Ça me donne

Msg 8159, niveau 16 , État 1, ligne 22 'doc' contient moins de colonnes que celles qui étaient spécifiées dans la liste des colonnes.

Est-ce msg ne change pas si je change changer @xml comme

SET @xml = ' 
    <ROOT> 
     <Object FooProperty1="123" FooProperty2="456"/> 
     <Object FooProperty1="123" FooProperty2="456"/> 
    </ROOT> 
'; 

Répondre

3

Votre XQuery est pas correct, je crois - essayer ceci:

SELECT 
    Root.Obj.value('(FooProperty1)[1]', 'INT') AS [fooProperty1], 
    Root.Obj.value('(FooProperty2)[1]', 'INT') AS [fooProperty2] 
FROM 
    @xml.nodes('/ROOT/Object') AS Root(Obj) 

Le @xml.nodes() définit des fragments XML - un pour chaque entrée dans XPath - et vous devez lui attribuer un alias à deux identifiants pour une pseudo-table avec une seule colonne (format: Root(Obj)). Cette seule colonne de cette pseudo-table est le fragment XML que votre requête XPath a sélectionné dans le document XML.

Basé sur cet alias, vous pouvez ensuite accéder à ces fragments XML et extraire les différentes propriétés.

Mise à jour: pour votre deuxième XML, avec les attributs XML, utilisez ceci:

SELECT 
    Root.Obj.value('(@FooProperty1)[1]', 'INT') AS [fooProperty1], 
    Root.Obj.value('(@FooProperty2)[1]', 'INT') AS [fooProperty2] 
FROM 
    @xml.nodes('/ROOT/Object') AS Root(Obj) 

En spécifiant @FooProperty1 vous êtes saisissant le code XML attribut au lieu de l'élément sous-XML de cette <ROOT>/<Object> nœud que vous êtes en train de regarder.

+0

Cette approche ne fonctionne que si j'utilise le premier motif avec des éléments supplémentaires pour chaque colonne ... Pourriez-vous me donner un exemple pour le deuxième motif? –

+0

Merci beaucoup! .... –

+0

@Andreas Niedermair: mis à jour ma réponse pour gérer aussi votre deuxième scénario (avec des attributs XML) –

Questions connexes