2010-07-13 11 views
9

Simplificar lo que estoy haciendo algo, como un ejemplo, decir que tengo las siguientes tablas:¿Cómo uso los valores de columna como nombres de elementos xml utilizando para xml en 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) 

que simplemente se define una tabla de nombres de elementos que podrían ser dinámico, contra el que se definen una tabla de valores.

Lo que me gustaría es generar XML de la siguiente forma, donde los valores de la tabla @elements se convierten en los nombres de los elementos, y los valores de la tabla @values ​​se convierten en los valores.

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

Sin embargo mis esfuerzos con for xml hasta el momento no van tan bien:

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

vuelve

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

for xml auto vuelve

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

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

¿Hay alguna manera de obtener los valores de una columna a la salida como nombres de elementos? Estoy seguro de que me estoy perdiendo algo obviamente simple aquí.

+0

creo que no se puede hacer eso. Puede hacer mucho con los diversos comandos FOR XML, pero en todos los casos, los nombres de los elementos y/o atributos XML resultantes deben ser corregidos, p. escrito por ti. No sé de ninguna manera para obtenerlos de una tabla y asignarlos dinámicamente. –

Respuesta

11

Es cheezy pero funciona ...

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

--- --- resultados

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

Disculpe la larga demora (3 años) Sí, esto funciona. Cheezy tal vez, pero funciona. Estoy de acuerdo con el arriba también comenta que EAV no es el enfoque correcto de todos modos, pero esto hace el trabajo. Hace tiempo que he olvidado lo que realmente hice. Podría haber sido un poco de código XSL o cliente para traducir el XML al formato que necesitaba. – tjmoore

+0

@tjmoore entonces, ¿cómo terminaste cambiando tu modelo para obtener xml personalizado? – vittore

+0

Si el valor contiene, por ejemplo, '&' falla. Entonces esto no funciona en el caso general. Prueba con esto para ver el error select cast (' barnes & noble' como xml) – Konstantin

7

Está tratando de modelar la temida base de datos semántica (Entity-Attribute-Value). Leer este artículo a por lo menos a comenzar en el camino correcto: Best Practices for Semantic Data Modeling for Performance and Scalability

Técnicamente, esto es la consulta que está buscando:

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

Buena idea, pero nuevamente: necesitas especificar explícita y manualmente las columnas en el comando PIVOT. No hay lectura de los elementos '@elementos 'tabla y usarlos, ¿verdad? –

+3

@Marc: correcto. Pero esa es la idea de por qué el modelo EAV es una mala idea para empezar. SQL es un sistema relacional, donde las tablas tienen columnas. Así que guarde las columnas como columnas y no tendrá este 'problema' para comenzar;) –

+0

@Renus: ¡totalmente de acuerdo! EAV es desordenado y malvado, y desafortunadamente muy utilizado: ( –

Cuestiones relacionadas