2010-07-13 3 views
9

Simplifier ce que je fais un peu, comme un exemple, disons que je les tableaux suivants:Comment utiliser les valeurs de colonne en tant que noms d'éléments XML à l'aide de xml dans SQL Server 2005?

declare @elements table (id int, name nvarchar(20)) 

insert into @elements (id, name) values (1, 'FirstName') 
insert into @elements (id, name) values (2, 'Surname') 
insert into @elements (id, name) values (3, 'Address') 

declare @values table (id int, value nvarchar(20), elementId int) 

insert into @values (id, value, elementId) values (1, 'XXX', 1) 
insert into @values (id, value, elementId) values (2, 'YYY', 2) 
insert into @values (id, value, elementId) values (3, 'ZZZ', 3) 

qui définit simplement une table des noms d'éléments qui pourraient être dynamiques, contre laquelle sont définies une table de valeurs. Ce que je voudrais, c'est générer du XML sous la forme suivante, où les valeurs de la table @elements deviennent les noms des éléments, et les valeurs de la table @values ​​deviennent les valeurs.

<Customer> 
    <FirstName>XXX</FirstName> 
    <Surname>YYY</Surname> 
    <Address>ZZZ<Address> 
</Customer> 

Cependant mes efforts avec for xml à ce jour ne vont pas si bien:

select e.name, v.value from @elements e 
inner join @values v on v.elementId = e.id 
for xml path(''), root('customer') 

retours

<customer> 
    <name>FirstName</name> 
    <value>XXX</value> 
    <name>Surname</name> 
    <value>YYY</value> 
    <name>Address</name> 
    <value>ZZZ</value> 
</customer> 

for xml auto retours

<customer> 
    <e name="FirstName"> 
    <v value="XXX" /> 
    </e> 
    <e name="Surname"> 
    <v value="YYY" /> 
    </e> 
    <e name="Address"> 
    <v value="ZZZ" /> 
    </e> 
</customer> 

for xml raw retours

<customer> 
    <row name="FirstName" value="XXX" /> 
    <row name="Surname" value="YYY" /> 
    <row name="Address" value="ZZZ" /> 
</customer> 

Est-il possible que je peux obtenir les valeurs d'une colonne à la sortie en tant que noms d'éléments? Je suis sûr qu'il me manque quelque chose de simple ici.

+0

Je ne pense pas que vous pouvez le faire. Vous pouvez faire beaucoup avec les différentes commandes FOR XML - mais dans tous les cas, les noms des éléments XML et/ou des attributs résultants doivent être corrigés, par ex. tapé par vous. Je ne connais pas de moyen d'obtenir ceux d'être tiré à partir d'une table et dynamique assigné –

Répondre

11

Il est cheezy mais ça fonctionne ...

select 
    cast('<' + name + '>' + value + '</' + name + '>' as xml) 
from @values v 
join @elements e on v.id = e.id  
for xml path(''), root('Customer') 

--- --- résultats

<Customer> 
    <FirstName>XXX</FirstName> 
    <Surname>YYY</Surname> 
    <Address>ZZZ</Address> 
</Customer> 
+0

Désolé pour le long délai (3 ans!) Oui, ça marche, peut-être que Cheezy fonctionne mais je suis d'accord avec Les commentaires ci-dessus également que EAV n'est pas la bonne approche de toute façon, mais cela fait le travail.J'ai oublié depuis longtemps ce que j'ai fait.Il pourrait y avoir eu un peu de code XSL ou client pour traduire le XML dans le format dont j'avais besoin – tjmoore

+0

@tjmoore alors comment avez-vous fini par changer votre modèle afin d'obtenir xml personnalisé? – vittore

+0

Si la valeur contient par exemple '&', elle échoue. Donc non cela ne fonctionne pas dans le cas général. Tester avec ceci pour voir l'erreur sélectionner cast (' barnes & noble' comme xml) – Konstantin

7

Vous essayez de modéliser la redoutée base de données sémantique (Entity-Attribute-Value). Lire cet article au moins vous permettre de démarrer sur le bon chemin: Best Practices for Semantic Data Modeling for Performance and Scalability

Techniquement, cela est la requête que vous cherchez:

select * from (
select name, value 
from @values v 
join @elements e on v.id = e.id) ve 
pivot (max(value) 
for name in ([FirstName], [Surname], [Address])) as p 
for xml path('Customer') 
+0

Bonne idée - mais encore une fois: vous devez spécifier explicitement et manuellement les colonnes dans la commande PIVOT - il n'y a pas à lire ceux des '@elements 'Table et en les utilisant, non? –

+3

@Marc: à droite. Mais c'est l'idée même de la raison pour laquelle le modèle EAV est une si mauvaise idée pour commencer. SQL est un système relationnel, où les tables ont des colonnes. Donc stockez les colonnes comme des colonnes et vous n'aurez pas ce 'problème' pour commencer;) –

+0

@Renus: totalement d'accord! EAV est en désordre et le mal -. Et malheureusement encore largement utilisé :-(Merci –

Questions connexes