2010-07-13 53 views
9

简化我在干什么一些,作为一个例子,说我有如下表:如何在SQL Server 2005中使用列值作为xml元素名称?

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) 

这只是定义可以是动态的,针对其定义值表元素名称的表格。

我想要的是以下面的形式生成XML,其中@elements表的值成为元素名称,并且@values表的值成为值。

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

但是我有for xml努力至今都不会那么好:

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

回报

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

for xml auto回报

<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返回

​​

有没有一种方法,我可以从列中获取值作为元素名称输出?我确定我在这里错过了一些显然很简单的事情。

+0

我不认为你可以做到这一点。您可以使用各种FOR XML命令做很多事情 - 但是在任何情况下,生成的XML元素和/或属性的名称都需要固定,例如,由您键入。我不知道有什么方法可以将这些从表格中拉出来并动态分配 – 2010-07-13 19:09:08

回答

11

这是cheezy但它的作品...

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

---结果---

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

对不起,很长的延迟(3年!)是的,这是行得通的,Cheezy也许,但是工作。上面的评论也表明EAV并不是正确的方法,但是这是做这项工作的,我早已忘记了我的实际做法,它可能是一些XSL或客户端代码来将XML转换成我所需要的格式 – tjmoore 2014-07-25 16:27:09

+0

@tjmoore所以你怎么最终改变你的模型,以获得自定义XML? – vittore 2015-03-10 16:49:19

+0

如果值包含例如'&',则失败。所以在一般情况下这不起作用。用此测试来查看失败选择投射(' barnes&noble'为xml) – Konstantin 2016-08-26 07:27:23

7

您试图对可怕的语义数据库(Entity-Attribute-Value)建模。阅读本文至少让你开始在正确的道路上:Best Practices for Semantic Data Modeling for Performance and Scalability

从技术上说,这是你要找的查询:

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

好主意 - 但同样的:您需要在PIVOT命令中明确和手动指定列 - 不会读取来自'@elements桌子和使用它们,对吧? – 2010-07-13 19:13:53

+3

@马克:对。但这就是为什么EAV模型从一开始就是一个糟糕的主意的整个想法。 SQL是一个关系系统,表中有列。因此,将列存储为列,并且不会出现此问题;) – 2010-07-13 19:19:34

+0

@Renus:完全同意! EAV是混乱和邪恶的 - 仍然不幸被广泛使用:-( – 2010-07-13 19:23:09

相关问题