2010-07-06 6 views
2

Si vous avez cette XML:Défi - Traitement XML dans la structure de la table T-SQL?

<people> 
    <person id="1"> 
    <firstname>John</firstname> 
    <surname>Doe</surname> 
    </person> 
    <person id="2"> 
    <firstname>Mary</firstname> 
    <surname>Jane</surname> 
    </person> 
</people> 

Et vous vouliez cette table:

id firstname surname 
--- ---------- ---------- 
1 John  Doe 
2 Mary  Jane 

Comment décririez-vous l'obtenir là-bas, en utilisant T-SQLXML?

Et jeter une clé dans le mélange: Disons que vous connaissez la profondeur des éléments <person>, <firstname> et <surname>, mais vous ne savez pas ce qu'ils appellent!

Ne hésitez pas à la flamme si vous pensez que cela est mieux affiché à reddit :)

Répondre

5

Je recommande d'utiliser l'interface XQuery, plutôt que l'approche ancienne OPENXML plutôt maladroites:

SELECT 
    Ppl.Person.value('(@id)[1]', 'int') AS 'ID', 
    Ppl.Person.value('(firstname)[1]', 'varchar(20)') AS 'First Name', 
    Ppl.Person.value('(surname)[1]', 'varchar(20)') AS 'Last Name' 
FROM 
    @input.nodes('/people/person') as Ppl(Person) 

C'est la manière préférée de le faire dans SQL Server 2005 et vers l'avant.

La sortie est la même:

ID First Name Last Name 
1 John    Doe 
2 Mary    Jane 

Vous ne pouvez pas vraiment faire cependant, si vous ne connaissez pas la structure XML .....

+0

OPENXML, même si maladroites, peut être beaucoup plus rapide (http://social.msdn.microsoft.com/Forums/en-US/sqlxml/thread/e51ef84d-72d6-490a-844a-fe28fbea3648). Ainsi, même si ce n'est pas la «méthode préférée», la performance l'emporte parfois sur la préférence. Mais j'ai quand même augmenté votre réponse parce que je pensais que c'était un bon :). – dcp

+0

J'aime les deux réponses, mais tbh, celui-ci est plus simple (lire: il y a moins de code donc je comprends mieux, oups je viens de me frapper la tête sur la souris :) donc c'est ma 'bonne réponse', mais ils ' re les deux sont super. Le premier va prendre un peu plus d'apprentissage de ma part pour comprendre (ce que je ne suis pas contre, fyi) –

+2

J'ai découvert qu'il est beaucoup, beaucoup plus rapide d'utiliser XQUERY avec SELECT/INTO pour vider dans une table temporaire, puis utilisez INSERT/INTO de la table temporaire dans la table de production. –

3

Vous obtiendrez la table. Si vous ne connaissez pas les noms des colonnes XML, vous devrez probablement utiliser le SQL dynamique (par exemple pour "prénom varchar (20)" prénom "", vous devrez remplacer "prénom" par le nom de colonne XML quel que soit le nom , que je suppose que vous analyserez lors de l'exécution):

DECLARE @idoc int 
DECLARE @doc varchar(1000) 
SET @doc =' 
<people> 
    <person id="1"> 
    <firstname>John</firstname> 
    <surname>Doe</surname> 
    </person> 
    <person id="2"> 
    <firstname>Mary</firstname> 
    <surname>Jane</surname> 
    </person> 
</people> 
' 
/* Create an internal representation of the XML document */ 
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc 
-- Execute a SELECT statement that uses the OPENXML rowset provider. 
SELECT * 
FROM  OPENXML (@idoc, '/people/person',1) 
      WITH (id varchar(20), 
        firstname varchar(20) 'firstname', 
        surname varchar(20) 'surname') 
EXECUTE sp_xml_removedocument @idoc 

Résultat:

id firstname  surname 
1 John   Doe 
2 Mary   Jane 
Questions connexes