在SQL Server或powerBuilder中从主详细信息行创建XML。

问题描述 投票:-1回答:1

我有来自SQL Server的主数据,如下图所示,我想按照以下格式生成XML,并从PowerBuilder以SOAP XML的形式发送。

CREATE TABLE dbo.Orders
    (
    OrderNo varchar(10) NOT NULL,
    PakDesc varchar(50) NOT NULL
    )  
GO

INSERT INTO Orders values('11111','Test1' )
GO

CREATE TABLE dbo.Components
    (
    OrderNo varchar(10) NOT NULL,
    CompNo varchar(10) NOT NULL,
    CompDesc varchar(50) NOT NULL,
    Qty int NOT NULL
    )  
GO

INSERT INTO Components values('11111','01234', 'Comp1', 10 )
INSERT INTO Components values('11111','56789', 'Comp2', 5 )
GO

希望的XML输出

<entrylist>
   <name>OrderNo</name>
   <value>11111</value>
</entrylist>
<entrylist>
   <name>PakDesc</name>
   <value>Test1</value>
</entrylist>
<entrylist>
   <name>CompNo1</name>
   <value>01234</value>
</entrylist>
<entrylist>
   <name>CompDesc1</name>
   <value>Comp1</value>
</entrylist>
<entrylist>
   <name>Qty1</name>
   <value>10</value>
</entrylist>
<entrylist>
   <name>CompNo2</name>
   <value>56789</value>
</entrylist>
<entrylist>
   <name>CompDesc2</name>
   <value>Comp2</value>
</entrylist>
<entrylist>
   <name>Qty2</name>
   <value>5</value>
</entrylist>

在PowerBuilder中,我在Datawindow中得到这些数据,我可以浏览每一行和每一列,并使用CREATE PBDOM_Element创建一个XML元素。

但我想知道,如果有任何其他方式,我可以很容易地生成类似的XML?这可以在SQL Server中生成像这样的输出?

sql-server xml master details
1个回答
1
投票

这是一个基于XQuery FLWOR表达式的解决方案。

这是一个两步的过程,在一个单一的T-SQL语句。

首先,为了模拟masterdetails结构,我们创建一个原始的XML,将master数据作为属性,将细节作为元素。其次,我们通过FLWOR表达式来塑造最终输出的XML。

SQL

-- DDL and sample data population, start
DECLARE @Orders TABLE (OrderNo varchar(10) NOT NULL, PakDesc varchar(50) NOT NULL);
INSERT INTO @Orders values('11111','Test1' );

DECLARE @Components TABLE 
(
    ID INT IDENTITY(1,1) PRIMARY KEY,
    OrderNo varchar(10) NOT NULL,
    CompNo varchar(10) NOT NULL,
    CompDesc varchar(50) NOT NULL,
    Qty int NOT NULL
);

INSERT INTO @Components VALUES
('11111','01234', 'Comp1', 10 )
,('11111','56789', 'Comp2', 5 );
-- DDL and sample data population, end

SELECT 
(
SELECT o.OrderNo AS [@OrderNo], o.PakDesc AS [@PakDesc]
    --, c.ID AS [@ID]
    , ROW_NUMBER() OVER(ORDER BY o.OrderNo) AS [@ID]
    , c.CompNo, c.CompDesc, c.Qty
FROM @Orders AS o LEFT OUTER JOIN 
    @Components AS c ON c.OrderNo = o.OrderNo
FOR XML PATH('r'), TYPE, ROOT('root')
).query('
for $y in /root/r   (: master level :)
    let $index := $y/@ID
    return (if ($index eq 1) then
        (
            for $z in $y/@*[local-name(.) ne "ID"]  (: all attributes except @ID :)
            return <entrylist>
                        <name>{local-name($z)}</name>
                        <value>{data($z)}</value>
                    </entrylist>
        )
        else ()
    ,
    for $x in $y/*  (: details level :)
    return <entrylist>
                <name>{concat(local-name($x), $index)}</name>
                <value>{data($x)}</value>
            </entrylist>)
');

产量

<entrylist>
  <name>OrderNo</name>
  <value>11111</value>
</entrylist>
<entrylist>
  <name>PakDesc</name>
  <value>Test1</value>
</entrylist>
<entrylist>
  <name>CompNo1</name>
  <value>01234</value>
</entrylist>
<entrylist>
  <name>CompDesc1</name>
  <value>Comp1</value>
</entrylist>
<entrylist>
  <name>Qty1</name>
  <value>10</value>
</entrylist>
<entrylist>
  <name>CompNo2</name>
  <value>56789</value>
</entrylist>
<entrylist>
  <name>CompDesc2</name>
  <value>Comp2</value>
</entrylist>
<entrylist>
  <name>Qty2</name>
  <value>5</value>
</entrylist>
© www.soinside.com 2019 - 2024. All rights reserved.