簡體   English   中英

從SQL查詢嵌套XML-問題

[英]Nesting XML from a SQL Query - Problems

所以這是我想要的成品:

<GPAutoActions>
 <createDispute>
  <transaction>
    <defaultKey>
      <custNo>10000000-AD</custNo>
      <invNo>28893848</invNo>
    </defaultKey>
  </transaction>
  <reason>405</reason>
  <amount>185.17</amount>  
  <pnote>Notes</pnote>
  <owner>LARRYGIST</owner>
 </createDispute>
</GPAutoActions>

這是表格結構

custno          invno    reason amount  pnote   owner
117455521-AD    28894882    405 972.04  Note    LARRYGIST
128623268-AD    28887277    405 182.99  Note    LARRYGIST
131537715-AD    28893848    405 185.17  Note    LARRYGIST
189063783-AD    28927273    405 777.49  Note    LARRYGIST

這是我正在使用的SQL:

Select 1 as TAG
, null as parent
, null as 'createDispute!1!'
, null as 'transaction!2!Element'
, null as 'defaultKey!3!'
, null as 'defaultKey!3!custno!Element'
, null as 'defaultKey!3!InvNo!Element'
, null as 'reason!4!'
UNION ALL
Select 2 as Tag
, 1 as Parent
, Null
, NULL
, null
, null
, null
, null
Union ALL
Select 3 as Tag
, 2 as Parent
, Null
, NULL
, null
, custno
, InvNo
, null
FROM [GetPaid_Sandbox].[dbo].[DisputeData]
Union ALL
Select 4 as Tag
, 2 as Parent
, Null
, NULL
, null
, null
, null
, reason
FROM [GetPaid_Sandbox].[dbo].[DisputeData]
for XML EXPLICIT

這是返回的內容:

<createDispute>
  <transaction>
    <defaultKey>
      <custno>117455521-AD</custno>
      <InvNo>28894882</InvNo>
    </defaultKey>
    <defaultKey>
      <custno>128623268-AD</custno>
      <InvNo>28887277</InvNo>
    </defaultKey>
    <defaultKey>
      <custno>131537715-AD</custno>
      <InvNo>28893848</InvNo>
    </defaultKey>
    <defaultKey>
      <custno>189063783-AD</custno>
      <InvNo>28927273</InvNo>
    </defaultKey>
    <reason>405</reason>
    <reason>405</reason>
    <reason>405</reason>
    <reason>405</reason>
  </transaction>
</createDispute>

我不明白的是為什么每個<defaultKey>標記后<transaction>標記都沒有關閉? 我還需要在原因代碼之后添加其余的標簽,但是我被困在這里。 我應該使用Explicit還是PATH在這種情況下會更好? 我討厭必須通過SQL來執行此操作,但是我不確定如何輕松完成該操作。

從您的代碼中,我假設這是SQL Server。 但這還不能完全確定...希望,我的魔術水晶球運轉良好。 下次,請分隔實際的RDBMS(供應商和版本)。

使用FOR XML EXPLICIT真是令人頭疼……數百年來,這是一個好方法,如今,人們應該更喜歡FOR XML PATH

您的目標可以輕松實現:

DECLARE @mockup TABLE(custno VARCHAR(100),invno INT,reason INT,amount DECIMAL(10,4),pnote VARCHAR(100),[owner] VARCHAR(100));
INSERT INTO @mockup VALUES
 ('117455521-AD',28894882,405,972.04,'Note','LARRYGIST')
,('128623268-AD',28887277,405,182.99,'Note','LARRYGIST')
,('131537715-AD',28893848,405,185.17,'Note','LARRYGIST')
,('189063783-AD',28927273,405,777.49,'Note','LARRYGIST');

-查詢將創建XML,如最終產品中所示

SELECT custno AS [transaction/defaultKey/custNo]
      ,invno AS  [transaction/defaultKey/invNo]
      ,reason
      ,amount
      ,pnote
      ,[owner]
FROM @mockup 
WHERE invno=28893848
FOR XML PATH('createDispute'),ROOT('GPAutoActions');

結果

<GPAutoActions>
  <createDispute>
    <transaction>
      <defaultKey>
        <custNo>131537715-AD</custNo>
        <invNo>28893848</invNo>
      </defaultKey>
    </transaction>
    <reason>405</reason>
    <amount>185.1700</amount>
    <pnote>Note</pnote>
    <owner>LARRYGIST</owner>
  </createDispute>
</GPAutoActions>

提示:如果需要CDATA節或帶有名稱空間的技巧,則FOR XML EXPLICIT仍然是正確的選擇。

但是我不理解您的評論: 我希望數據庫中的每一行數據都返回一個結果集

可能是您在尋找這個:

SELECT outerTable.invno
,(
    SELECT innerTable.custno AS [transaction/defaultKey/custNo]
          ,innerTable.invno AS  [transaction/defaultKey/invNo]
          ,innerTable.reason
          ,innerTable.amount
          ,innerTable.pnote
          ,innerTable.[owner]
    FROM @mockup AS innerTable
    WHERE innerTable.invno=outerTable.invno
    FOR XML PATH('createDispute'),ROOT('GPAutoActions'),TYPE
 )
 FROM @mockup AS outerTable;

第一:看起來您已經為reason元素設置了父級。 您的規格表明您想reason是的子元素createDispute元素。 然而; 您的查詢將其設置為transaction的子元素。

要更正此問題,請將返回reason的查詢的parent值從2更改為1 然后,您可以從同一查詢返回amountpnoteorder

下一步:您不需要第五列( defaultKey!3! )-在所有查詢中將其刪除。

然后:將null as 'createDispute!1!'更改null as 'createDispute!1!' 轉換為custno + '_' + cast(invno as varchar(50)) as 'createDispute!1!' custno + '_' + cast(invno as varchar(50))每個附加查詢的第三個返回值編碼為custno + '_' + cast(invno as varchar(50))而不是返回null。

最后: ORDER BY custno + '_' + cast(invno as varchar(50)) 這是將所有事物聯系在一起的“特殊調味料”。

那應該做。 編碼愉快!

TL:DR(重構):

Select 1 as TAG
, null as parent
, custno + '_' + cast(invno as varchar(50)) as 'createDispute!1!'
, null as 'transaction!2!reason!Element'
, null as 'transaction!2!amount!Element'
, null as 'transaction!2!pnote!Element'
, null as 'transaction!2!owner!Element'
, null as 'defaultKey!3!custno!Element'
, null as 'defaultKey!3!InvNo!Element'
FROM [GetPaid_Sandbox].[dbo].[DisputeData]
UNION ALL
Select 2 as Tag
, 1 as Parent
, custno + '_' + cast(invno as varchar(50))
, reason
, amount
, pnote
, [owner]
, null
, null
FROM [GetPaid_Sandbox].[dbo].[DisputeData]
Union ALL
Select 3 as Tag
, 2 as Parent
, custno + '_' + cast(invno as varchar(50))
, NULL
, NULL
, NULL
, NULL
, custno
, InvNo
FROM [GetPaid_Sandbox].[dbo].[DisputeData]
Union ALL
ORDER BY custno + '_' + cast(invno as varchar(50))
for XML EXPLICIT

考慮一個嵌套查詢:

SELECT 1 as TAG
, null as parent
, (SELECT 1 AS [Tag], NULL AS [Parent], sub.custno AS 'defaultKey!1!custno!Element', sub.invno AS 'defaultKey!1!invno!Element'
   FROM DisputeData sub
   WHERE d.custno = sub.custno
   FOR XML EXPLICIT, TYPE)  AS 'createDispute!1!transaction!Element'

, d.reason as 'createDispute!1!reason!Element'
, d.amount as 'createDispute!1!amount!Element'
, d.pnote as 'createDispute!1!pnote!Element'
, d.owner as 'createDispute!1!owner!Element'
FROM DisputeData As d
FOR XML EXPLICIT, ROOT('GPAutoActions');

Rextester演示

不幸的是,這里的結果返回嵌套元素defaultKey重復命名空間的眾所周知的問題,這里是一個空的: xmlns=""

<?xml version="1.0"?>
<GPAutoActions>
  <createDispute>
    <transaction>
      <defaultKey xmlns="">
        <custno>117455521-AD</custno>
        <invno>28894882</invno>
      </defaultKey>
    </transaction>
    <reason>405</reason>
    <amount>972.04</amount>
    <pnote>Dispute Reason: Inbound email from John requesting that account be cancelled, providing letter of cancellation. Attachments: Yes</pnote>
    <owner>LARRYGIST</owner>
  </createDispute>
  <createDispute>
    <transaction>
      <defaultKey xmlns="">
        <custno>128623268-AD</custno>
        <invno>28887277</invno>
      </defaultKey>
    </transaction>
    <reason>405</reason>
    <amount>182.99</amount>
    <pnote>Dispute Reason: Inbound email from Catherine requesting cancelation of services. Attachments: Yes</pnote>
    <owner>LARRYGIST</owner>
  </createDispute>
  <createDispute>
    <transaction>
      <defaultKey xmlns="">
        <custno>131537715-AD</custno>
        <invno>28893848</invno>
      </defaultKey>
    </transaction>
    <reason>405</reason>
    <amount>185.17</amount>
    <pnote>Dispute Reason: Syed stated that he canceled his Tyco contract a long time ago. Syad stated that he doesn't have an email address and didn't want to send CR a cancellation notice.  Attachments: No</pnote>
    <owner>LARRYGIST</owner>
  </createDispute>
  <createDispute>
    <transaction>
      <defaultKey xmlns="">
        <custno>189063783-AD</custno>
        <invno>28927273</invno>
      </defaultKey>
    </transaction>
    <reason>405</reason>
    <amount>777.49</amount>
    <pnote>Dispute Reason: Spoke to Grant stated moved out of building on 12 01 2017. Stated company that bought building decided not to go with Tyco and Tyco came and picked up the equipment. Attachments: No</pnote>
    <owner>LARRYGIST</owner>
  </createDispute>
</GPAutoActions>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM