2010-04-29 32 views
2

如何使用FOR XML/sql查询获得如下输出。我不知道如何将列值作为元素而不是表格的列名称。我使用SQL Server 2005用于XML语法的SQL SERVER

我有表SCEMA如下

CREATE TABLE PARENT 
(
PID INT, 
PNAME VARCHAR(20) 
) 

CREATE TABLE CHILD 
(
PID INT, 
CID INT, 
CNAME VARCHAR(20) 
) 

CREATE TABLE CHILDVALUE 
(
CID INT, 
CVALUE VARCHAR(20) 
) 

INSERT INTO PARENT VALUES (1, 'SALES1') 
INSERT INTO PARENT VALUES (2, 'SALES2') 

INSERT INTO CHILD VALUES (1, 1, 'FOR01') 
INSERT INTO CHILD VALUES (1, 2, 'FOR02') 
INSERT INTO CHILD VALUES (2, 3, 'FOR03') 
INSERT INTO CHILD VALUES (2, 4, 'FOR04') 

INSERT INTO CHILDVALUE VALUES (1, '250000') 
INSERT INTO CHILDVALUE VALUES (2, '400000') 
INSERT INTO CHILDVALUE VALUES (3, '500000') 
INSERT INTO CHILDVALUE VALUES (4, '800000') 

我找的输出如下:

<SALE1> 
<FOR01>250000</FOR01> 
<FOR02>400000</FOR02> 
</SALE1> 
<SALE2> 
<FOR03>500000</FOR03> 
<FOR04>800000</FOR04> 
</SALE2> 

回答

0

这里使用此查询:

SELECT 
    p.PName '@Name', 
    (SELECT 
     c.CName AS '@Name', 
     (SELECT 
      cv.CValue AS 'Value' 
     FROM dbo.CHILDVALUE cv 
     WHERE cv.CID = c.CID 
     FOR XML PATH(''), TYPE 
     ) 
    FROM dbo.CHILD c 
    WHERE c.PID = p.PID 
    FOR XML PATH('Child'), TYPE 
    ) 
FROM  
    Parent p 
FOR 
    XML PATH('Node'), ROOT('Root') 

你可以得到如下结果:

<Root> 
    <Node Name="SALES1"> 
    <Child Name="FOR01"> 
     <Value>250000</Value> 
    </Child> 
    <Child Name="FOR02"> 
     <Value>400000</Value> 
    </Child> 
    </Node> 
    <Node Name="SALES2"> 
    <Child Name="FOR03"> 
     <Value>500000</Value> 
    </Child> 
    <Child Name="FOR04"> 
     <Value>800000</Value> 
    </Child> 
    </Node> 
</Root> 

这大概是接近你的要求,你可以用FOR XML PATH(), ROOT()

+0

感谢您的回复。我也能够得到像你一样的东西,但我真的希望列名作为元素。那么,我所要求的FOR XML语法是不可能的?此外,我可以在存储过程中操作表格,在内部使用一些临时表格等,但仍不清楚我如何获得所需结果。 – Raj73 2010-04-29 18:01:01

+0

@ Raj73:从我所了解的有关SQL Server及其FOR XML支持的所有信息中,您尝试执行的操作都无法完成。如果您对获得的结果不满意,则必须使用一些编程语言,如C#或VB.NET或其他语言来读取数据并呈现XML。 – 2010-04-29 18:17:20

+0

谢谢,我们将有一百万行,我不想使用C#/ ado.net/linq来生成和渲染xml。我打算从命令行运行查询/存储过程并将结果输出为xml文件。也许使用编程语言是唯一可以完成的方法。 – Raj73 2010-04-29 18:23:36

0

节点对应字段名获得。因此,如果您希望主节点都具有不同的名称(即"<SALE1>", "<SALE2>"等),则它们不能来自同一列。

您要求的输出格式将很难在以后查询值。 (例如,它会阻止你告诉XPATH或你有什么“看在”特定的“场”的值)

什么,你应该寻找的是这样的:

<SALE> 
    <ID>1</ID> 
    <FOR> 
     <ID>1</ID> 
     <NUM>250000</NUM> 
    </FOR> 
    <FOR> 
     <ID>2</ID> 
     <NUM>400000</NUM> 
    </FOR> 
</SALE> 
<SALE> 
    <ID>2</ID> 
    <FOR> 
     <ID>3</ID> 
     <NUM>500000</NUM> 
    </FOR> 
    <FOR> 
     <ID>4</ID> 
     <NUM>800000</NUM> 
    </FOR> 
</SALE> 

或者,属性&元素像这样的组合:

<SALE ID="1"> 
     <FOR ID="1"> 
      <NUM>250000</NUM> 
     </FOR> 
     <FOR ID="2"> 
      <NUM>400000</NUM> 
     </FOR> 
    </SALE> 
    <SALE ID="2"> 
     <FOR ID="3"> 
      <NUM>500000</NUM> 
     </FOR> 
     <FOR ID="4"> 
      <NUM>800000</NUM> 
     </FOR> 
    </SALE> 

不管怎样,看看联机丛书SQL-Server中。这里有一些想法: FOR XML汽车,元素,根(“根”) FOR XML原料 等等

1

不明白为什么每个节点都需要一个不同的标签 - 这不会有任何有趣的查询 - 但无论如何,你可以明确地做到这一点(没有FOR XML)。

通过递增您的MIN(PID),并简单地通过SELECT '<' + PNAME + '>'等等,对您的记录集执行WHILE循环。对它进行格式化会非常棘手,因此它像默认的XML文件一样是人类可读的,但它仍然可以被任何网页等读取,您试图查询它。