在SQL Server中将层次结构表元素转换为xml格式

时间:2011-03-30 14:37:21

标签: sql-server xml sql-server-2005

我有两个表用于代码,另一个是子映射表来表示与代码表的父子关系。

表:代码

Code ID    |  Code Value  |  code Group | code Desc
1             Person 1       Accounts     cashier
2             Person 2       Finance      teller
3             Person 3       HR           administrator
4             Person 4       IT           system admin

表:映射

Id (Primarykey)       | code ID  | Parent Code ID   (both code ID and parent code ID are foreign keys with codes table
1                     1          Null
2                     2          1
3                     3          1
4                     4          Null
5                     3          4

我需要输出

<Codes>
<CodeParent group = "Accounts">
    <ChildCodes group= "Finance">
       <CodeParent name = "person 2" desc = "teller"/>
    </ChildCodes>
    <ChildCodes group = "HR">
       <CodeParent name = "Person 3" desc = "Administrator"/>
    <ChildCodes>    
</CodeParent >
<CodeParent group = "IT>
    <ChildCodes group = "HR">
       <CodeParent name = "Person 3" desc = "Administrator"/>
    <ChildCodes> 
</CodeParent >
</Root>

我尝试使用这个SQL函数,但它似乎没有提供正确的所需输出

ALTER FUNCTION dbo.GetPartsSubTree(@PartNumberID int)
RETURNS XML
BEGIN RETURN
(SELECT codeMappingTable.codeID AS "@codeID",
codes.codeLiteral AS "@codeLiteral",
codes.codeGroup AS "@codeGroup",
dbo.GetPartsSubTree(codeMappingTable.codeID)
FROM codeMappingTable,codes

WHERE codeMappingTable.ParentcodeID=@PartNumberID and codes.codeID = codeMappingTable.codeID
ORDER BY codeMappingTable.codeID
FOR XML PATH('CodeParent'),ROOT('ChildCodes'),TYPE)
END

GO

SELECT codeMappingTable.codeID AS "@codeID",
codes.codeLiteral AS "@codeLiteral",
codes.codeGroup AS "@codeGroup",
dbo.GetPartsSubTree(codeMappingTable.codeID)
FROM codeMappingTable,codes
WHERE codeMappingTable.ParentcodeID is null and codes.codeID = codeMappingTable.codeID
ORDER BY codeMappingTable.codeID
FOR XML PATH('CodeParent'),ROOT('Codes'),TYPE

请帮我解决这个问题。

更大规模的预期产出如下:

<Codes>
  <codeGroup codeGroup="Entity">
    <CodeParent codeID="18" codeDesc="Borrower" codeGroup="Entity">
      <ChildCodes codeGroup="Fin Reporting Type">
        <CodeParent codeID="20" codeDesc="Financial Statement - Annual" codeGroup="Fin Reporting Type" />
        <CodeParent codeID="21" codeDesc="Tax Returns" codeGroup="Fin Reporting Type" />
      </ChildCodes>
      <ChildCodes codeGroup="Covenant Type">
        <CodeParent codeID="24" codeDesc="Capital Expenditures" codeGroup="Covenant Type" />
        <CodeParent codeID="25" codeDesc="Cash Flow Coverage Ratio" codeGroup="Covenant Type" />
      </ChildCodes>
    </CodeParent>
    <CodeParent codeID="17" codeDesc="Guarantor" codeGroup="Entity">
      <ChildCodes codeGroup="Fin Reporting Type">
        <CodeParent codeID="20" codeDesc="Financial Statement - Annual" codeGroup="Fin Reporting Type" />
        <CodeParent codeID="22" codeDesc="Brokerage Statements" codeGroup="Fin Reporting Type" />
      </ChildCodes>
      <ChildCodes codeGroup="Covenant Type">
        <CodeParent codeID="27" codeDesc="Current Ratio" codeGroup="Covenant Type" />
        <CodeParent codeID="28" codeDesc="Debt Service Coverage Ratio" codeGroup="Covenant Type" />
      </ChildCodes>
    </CodeParent>
  </codeGroup>
  <codeGroup codeGroup="Entity Category">
    <CodeParent codeID="4" codeDesc="Company" codeGroup="Entity Category">
      <ChildCodes codeGroup="AFS Obligor Type">
        <CodeParent codeID="9" codeDesc="American Subsidiary or Agency of Japanese TR Co" codeGroup="AFS Obligor Type">
          <ChildCodes codeGroup="test type">
            <CodeParent codeID="29" codeDesc="xyz" codeGroup="test type" />
            <CodeParent codeID="30" codeDesc="www" codeGroup="test type" />
          </ChildCodes>
        </CodeParent>
        <CodeParent codeID="11" codeDesc="Cooperative" codeGroup="AFS Obligor Type" />
        <CodeParent codeID="13" codeDesc="Corporation" codeGroup="AFS Obligor Type" />
      </ChildCodes>
    </CodeParent>
    <CodeParent codeID="8" codeDesc="Individual" codeGroup="Entity Category">
      <ChildCodes codeGroup="AFS Obligor Type">
        <CodeParent codeID="1" codeDesc="US Bancorp Employee" codeGroup="AFS Obligor Type" />
        <CodeParent codeID="3" codeDesc="US Bancorp Officer" codeGroup="AFS Obligor Type" />
      </ChildCodes>
    </CodeParent>
    <CodeParent codeID="5" codeDesc="LLC" codeGroup="Entity Category" />
    <CodeParent codeID="6" codeDesc="Trust" codeGroup="Entity Category">
      <ChildCodes codeGroup="AFS Obligor Type">
        <CodeParent codeID="1" codeDesc="US Bancorp Employee" codeGroup="AFS Obligor Type" />
      </ChildCodes>
    </CodeParent>
  </codeGroup>
  <codeGroup codeGroup="Category">
    <CodeParent codeID="31" codeDesc="cat1" codeGroup="Category" />
    <CodeParent codeID="32" codeDesc="cat2" codeGroup="Category" />
    <CodeParent codeID="33" codeDesc="cat3" codeGroup="Category" />
  </codeGroup>
  <codeGroup codeGroup="Facility">
    <CodeParent codeID="34" codeDesc="cat1" codeGroup="Facility" >
      <ChildCodes codeGroup="BorrowerType">
        <CodeParent codeID="40" codeDesc="Employee" codeGroup="BorrowerType" />
        <CodeParent codeID="41" codeDesc="Officer" codeGroup="BorrowerType" />
      </ChildCodes>
    </CodeParent>
    <CodeParent codeID="35" codeDesc="cat2" codeGroup="Facility" />
    <CodeParent codeID="36" codeDesc="cat3" codeGroup="Facility" />
  </codeGroup>
  <codeGroup codeGroup="Loan">
    <CodeParent codeID="37" codeDesc="cat1" codeGroup="Loan" >
      <ChildCodes codeGroup="BorrowerType">
        <CodeParent codeID="40" codeDesc="Employee" codeGroup="BorrowerType" />
        <CodeParent codeID="41" codeDesc="Officer" codeGroup="BorrowerType" />
      </ChildCodes>
    </CodeParent>
    <CodeParent codeID="38" codeDesc="cat2" codeGroup="Loan" />
    <CodeParent codeID="39" codeDesc="cat3" codeGroup="Loan" />
  </codeGroup>
</Codes>

2 个答案:

答案 0 :(得分:0)

declare @Codes table(ID int, CodeValue varchar(10), CodeGroup varchar(10), CodeDesc varchar(20))
declare @Mapping table(ID int, CodeID int, ParentCodeID int)

insert into @Codes values
(1, 'Person 1', 'Accounts', 'cashier'),
(2, 'Person 2', 'Finance',  'teller'),
(3, 'Person 3', 'HR',       'administrator'),
(4, 'Person 4', 'IT',       'system admin'),
(5, 'Person 5', 'Accounts', 'accountant'),
(6, 'Person 6', 'Finance', 'Investbanker')

insert into @Mapping values
(1, 1, null),
(2, 2, 1),
(3, 3, 1),
(4, 4, null),
(5, 3, 4),
(6, 5, null),
(7, 6, 1)

select
  CRoot.CodeGroup as '@group',
  (select 
     CChild.CodeGroup as '@group',
     CChild.CodeValue as 'CodeParent/@name',
     CChild.CodeDesc as 'CodeParent/@desc'
   from @Mapping as MChild
    inner join @Codes as CChild
      on MChild.CodeID = CChild.ID
   where MChild.ParentCodeID = MRoot.ID
   for xml path('ChildCodes'), type)
from @Mapping as MRoot
  inner join @Codes as CRoot
    on MRoot.CodeID = CRoot.ID
where
  MRoot.ParentCodeID is null
for xml path('CodeParent'), root('Codes')

结果

<Codes>
  <CodeParent group="Accounts">
    <ChildCodes group="Finance">
      <CodeParent name="Person 2" desc="teller" />
    </ChildCodes>
    <ChildCodes group="HR">
      <CodeParent name="Person 3" desc="administrator" />
    </ChildCodes>
    <ChildCodes group="Finance">
      <CodeParent name="Person 6" desc="Investbanker" />
    </ChildCodes>
  </CodeParent>
  <CodeParent group="IT">
    <ChildCodes group="HR">
      <CodeParent name="Person 3" desc="administrator" />
    </ChildCodes>
  </CodeParent>
  <CodeParent group="Accounts" />
</Codes>

答案 1 :(得分:0)

Mikael,我在上表中有以下可能的关系 1)父代码组本身就是完整的。 2)父代码组驱动单个子组 3)父代码组驱动两个不同的子组 4)父代码组驱动子代,子代组驱动子子组 5)儿童组有两个不同的父组

以下是所有关系存在时所需的代码输出。

    <Codes>
      <codeGroup codeGroup="Entity">
        <CodeParent codeID="18" codeDesc="Borrower" codeGroup="Entity">
          <ChildCodes codeGroup="Fin Reporting Type">
            <CodeParent codeID="20" codeDesc="Financial Statement - Annual" codeGroup="Fin Reporting Type" />
            <CodeParent codeID="21" codeDesc="Tax Returns" codeGroup="Fin Reporting Type" />
          </ChildCodes>
          <ChildCodes codeGroup="Covenant Type">
            <CodeParent codeID="24" codeDesc="Capital Expenditures" codeGroup="Covenant Type" />
            <CodeParent codeID="25" codeDesc="Cash Flow Coverage Ratio" codeGroup="Covenant Type" />
          </ChildCodes>
        </CodeParent>
        <CodeParent codeID="17" codeDesc="Guarantor" codeGroup="Entity">
          <ChildCodes codeGroup="Fin Reporting Type">
            <CodeParent codeID="20" codeDesc="Financial Statement - Annual" codeGroup="Fin Reporting Type" />
            <CodeParent codeID="22" codeDesc="Brokerage Statements" codeGroup="Fin Reporting Type" />
          </ChildCodes>
          <ChildCodes codeGroup="Covenant Type">
            <CodeParent codeID="27" codeDesc="Current Ratio" codeGroup="Covenant Type" />
            <CodeParent codeID="28" codeDesc="Debt Service Coverage Ratio" codeGroup="Covenant Type" />
          </ChildCodes>
        </CodeParent>
      </codeGroup>
      <codeGroup codeGroup="Entity Category">
        <CodeParent codeID="4" codeDesc="Company" codeGroup="Entity Category">
          <ChildCodes codeGroup="AFS Obligor Type">
            <CodeParent codeID="9" codeDesc="American Subsidiary or Agency of Japanese TR Co" codeGroup="AFS Obligor Type">
              <ChildCodes codeGroup="test type">
                <CodeParent codeID="29" codeDesc="xyz" codeGroup="test type" />
                <CodeParent codeID="30" codeDesc="www" codeGroup="test type" />
              </ChildCodes>
            </CodeParent>
            <CodeParent codeID="11" codeDesc="Cooperative" codeGroup="AFS Obligor Type" />
            <CodeParent codeID="13" codeDesc="Corporation" codeGroup="AFS Obligor Type" />
          </ChildCodes>
        </CodeParent>
        <CodeParent codeID="8" codeDesc="Individual" codeGroup="Entity Category">
          <ChildCodes codeGroup="AFS Obligor Type">
            <CodeParent codeID="1" codeDesc="US Bancorp Employee" codeGroup="AFS Obligor Type" />
            <CodeParent codeID="3" codeDesc="US Bancorp Officer" codeGroup="AFS Obligor Type" />
          </ChildCodes>
        </CodeParent>
        <CodeParent codeID="5" codeDesc="LLC" codeGroup="Entity Category" />
        <CodeParent codeID="6" codeDesc="Trust" codeGroup="Entity Category">
          <ChildCodes codeGroup="AFS Obligor Type">
            <CodeParent codeID="1" codeDesc="US Bancorp Employee" codeGroup="AFS Obligor Type" />
          </ChildCodes>
        </CodeParent>
      </codeGroup>
      <codeGroup codeGroup="Category">
        <CodeParent codeID="31" codeDesc="cat1" codeGroup="Category" />
        <CodeParent codeID="32" codeDesc="cat2" codeGroup="Category" />
        <CodeParent codeID="33" codeDesc="cat3" codeGroup="Category" />
      </codeGroup>
      <codeGroup codeGroup="Facility">
          <CodeParent codeID="34" codeDesc="cat1" codeGroup="Facility" >
      <ChildCodes codeGroup="BorrowerType">
        <CodeParent codeID="40" codeDesc="Employee" codeGroup="BorrowerType" />
        <CodeParent codeID="41" codeDesc="Officer" codeGroup="BorrowerType" />
      </ChildCodes>
    </CodeParent>
    <CodeParent codeID="35" codeDesc="cat2" codeGroup="Facility" />
    <CodeParent codeID="36" codeDesc="cat3" codeGroup="Facility" />
  </codeGroup>
  <codeGroup codeGroup="Loan">
    <CodeParent codeID="37" codeDesc="cat1" codeGroup="Loan" >
      <ChildCodes codeGroup="BorrowerType">
        <CodeParent codeID="40" codeDesc="Employee" codeGroup="BorrowerType" />
        <CodeParent codeID="41" codeDesc="Officer" codeGroup="BorrowerType" />
      </ChildCodes>
    </CodeParent>
    <CodeParent codeID="38" codeDesc="cat2" codeGroup="Loan" />
    <CodeParent codeID="39" codeDesc="cat3" codeGroup="Loan" />
  </codeGroup>
    </Codes>