2009-10-01 7 views
0

Je n'ai pas beaucoup travaillé avec XML en SQL, donc je vais essayer de poser la question du mieux que je peux.Comment obtenir une identité individuelle dans un insert XML?

Dites que je reçois du code XML structuré en SQL pour insertion.

La structure pourrait être:

<Team> 
    <Player> 
    <Name>Player1</Name> 
    <Games> 
     <Game> 
     <Date>9/7/2009</Date> 
     <MinutesPlayed>90</MinutesPlayed> 
     </Game> 
    </Games> 
    </Player> 
    <Player> 
    <Name>Player2</Name> 
    <Games> 
     <Game> 
     <Date>9/7/2008</Date> 
     <MinutesPlayed>87</MinutesPlayed> 
     </Game> 
    </Games> 
    </Player> 
</Team> 

Je suis en mesure d'insérer l'enregistrement -Team- et obtenir l'identité, puisque dans ce cas, je n'ai que 1 enregistrement et l'accès à SCOPE_IDENTITY() correspondra à l'identité pour cet enregistrement, et cette identité que je vais utiliser pour insérer les nœuds du lecteur.

Dans la table de jeu, j'ai un champ PlayerID. Comment puis-je obtenir l'identité de chaque joueur inséré, puis utiliser cette identité pour insérer les enregistrements du jeu? Depuis un SELECT comme SELECT FROM @ ReceivedXML.nodes ('Player') renverrait plusieurs valeurs, et tous les nœuds Player seraient insérés par lot.

Quelqu'un peut-il s'il vous plaît me diriger vers des guides sur la façon de le faire, ou peut-être partager comment vous avez résolu ce problème? Merci, vraiment apprécié.


Modifier - peut-être que je ne me suis pas expliqué correctement.

L'équipe a un champ TeamID. Les joueurs ont un champ PlayerID, ainsi que le champ TeamID. Les jeux ont un GameID et un champ PlayerID. A partir du XML, comment insérer l'équipe, obtenir l'ID d'équipe nouvellement identifiée, puis insérer le lecteur un dans la table PLayers, obtenir son identité PlayerID nouvellement générée, puis insérer l'enregistrement du jeu, en utilisant l'identifiant PLayerID précédemment obtenu. Une fois que j'ai terminé avec Player1, je ferais la même chose pour Player2. Insérer le dossier du joueur, obtenir l'identité PlayerID < insérer le jeu, etc

+0

Pour ce faire, vous êtes probablement mieux loti essayer de l'accomplir en C# - comme vous disons, vous pourriez insérer un tas de joueurs, et à tour de rôle tout un tas de jeux pour chaque joueur. Ceci est mieux fait dans les boucles, et c'est un domaine où T-SQL ne brille certainement pas .. –

Répondre

1

Charger le tableau des joueurs, comme ci-dessous.

Ensuite, rejoindre XML analysable avec table joueur sur le nom pour obtenir les identifiants pour la prochaine insertion dans le jeu etc

DECLARE @foo XML 

SELECT @foo = N' 
<Team> 
    <Player> 
    <Name>Player1</Name> 
    <Games> 
     <Game> 
     <Date>9/7/2009</Date> 
     <MinutesPlayed>90</MinutesPlayed> 
     </Game> 
    </Games> 
    </Player> 
    <Player> 
    <Name>Player2</Name> 
    <Games> 
     <Game> 
     <Date>9/7/2008</Date> 
     <MinutesPlayed>87</MinutesPlayed> 
     </Game> 
    </Games> 
    </Player> 
</Team> 
' 


INSERT Players 
    (PlayerName) 
SELECT 
    CAST(y.item.query('data(Name)') AS varchar(30)) 
FROM 
    @foo.nodes('/Team') x(item) 
    CROSS APPLY 
    x.item.nodes('./Player') AS y(item) 


INSERT Game 
    (PlayerID, Date, MinutesPlayed) 
SELECT 
    P.PlayerID, 
    CAST(z.item.query('data(Date)') AS varchar(30)), 
    CAST(z.item.query('data(MinutesPlayed)') AS varchar(30)) 
FROM 
    @foo.nodes('/Team') x(item) 
    CROSS APPLY 
    x.item.nodes('./Player') AS y(item) 
    CROSS APPLY 
    y.item.nodes('./Games/Game') AS z(item) 
    JOIN 
    Players P ON CAST(y.item.query('data(Name)') AS varchar(30)) = P.PlayerName 
+0

Merci gbn, mais cela n'a pas fonctionné pour ce que je devais faire. Fondamentalement, je suppose que ce que je cherchais était une boucle FOR EACH, pour pouvoir insérer chaque joueur individuellement et utiliser l'identité du joueur inséré pour insérer les enregistrements enfants (Game, etc.). La requête que vous avez écrite ci-dessus me donne toutes les données dans une seule ligne, que je pourrais utiliser pour insérer chaque ligne connaissant le nom des champs corresopnding à chaque table, mais je voulais plus une approche FOR EACH boucle. Merci quand même pour l'effort – GR7

+0

Vous pouvez l'écrire en boucle si vous le souhaitez, mais vous n'avez pas lu mon commentaire. Vous devez charger les joueurs * puis vous reconnecter * pour obtenir les ID insérés correspondant au nom pour charger les jeux. etc. Ou vous pouvez charger une table temporaire avec toutes les données et y revenir. – gbn

+0

... code mis à jour aussi – gbn

Questions connexes