0

すべて関連している xml ファイルのセットを取得し、これらのファイルからレコードのサブセットを選択し、いくつかの列を変換し、別の形式を使用して単一の xml ファイルにエクスポートする必要があるタスクがあります。

私は SSIS を初めて使用しますが、これまでのところ、最初に 2 つの xml ファイルをインポートすることができました (簡単にするために、2 つのファイルから始めます)。

「アイテム」と呼ぶことができる最初のファイルには、2 番目のファイル「マイルストーン」で関連するレコードを識別するために使用される ID の中にいくつかの基本的なメタデータが含まれています。データフローでルックアップ変換を使用して「有効なレコード」をフィルタリングしました。これで、必要なレコードを取得するための有効なアイテム ID が得られました。これらの有効な ID を (Item.xml の残りの列と共に、Sort を介して、次にマージ結合に注ぎ込みます。

2 番目のファイルは 2 つの出力で構成されており、1 つには 2 つの列 (ItemID と RowID) が含まれています。2 つ目は、マイルストーン関連のすべてのデータと RowID を含みます。これらを RowID に基づいて内部マージ結合に通したので、マイルストーン データに ItemID が含まれています。次に、ItemID を使用して、両方のファイルに対して完全な外部結合マージ結合を実行します。

これにより、次のようなデータが得られます。

  • ItemID[1] - MilestoneData[2]
  • ItemID[1] - MilestoneData[3]
  • ItemID[1] - MilestoneData[4]
  • ItemID[1] - MilestoneData[5]
  • ItemID[2] - MilestoneData[6]
  • ItemID[2] - MilestoneData[7]
  • ItemID[2] - MilestoneData[8]

このデータを派生列変換に通して、実際に必要なデータの列を作成できますが、これをリレーショナルな方法で構造化する/別の xml 形式に正規化する方法がわかりません。

アイデアは、次のようなものを出力することです:

<item id="1">
      <Milestone id="2">
      <Milestone />
      <Milestone id="3">
      <Milestone />
</item>

誰かが私を正しい方向に向けることができますか?

更新: 私が持っているもののもう少し詳細な図と、私が達成したいこと:

アイテム.xml:

 <Items>
     <Item ItemID="1">
         <Title>
         Data
         </Title>
     </Item>
     <Item ItemID="2">
          ...
     </Item>
     ...
 </Items>

Milestone.xml:

  <Milestones>
  <Item ItemID="2">
       <MS id="3">
            <MS_DATA>
             Data
            </MS_DATA>
       </MS>
       <MS id="4">
            <MS_DATA>
             Data
            </MS_DATA>
       </MS>
   </Item>
   <Item ItemID="3">
       <MS id="5">
            <MS_DATA>
             Data
            </MS_DATA>
       </MS>
   </item>
 </Milestones>

XML ソースを使用するときに SSIS で表示される方法は完全に直感的ではありません。つまり、Item 行と MS 行は 2 つの別個の出力です。特定のアイテムに対応するマイルストーンを取得するために、結合を介してこれらを実行する必要がありました。ここでは問題ありません。アイテムとの完全な外部結合を実行すると、明らかにアイテムの同じデータと MS の異なるデータを含む複数の行を持つ平坦化されたテーブルが得られます。基本的に、テーブルに表示しようとしたもの、つまり一意の MilestoneData ごとに多くの冗長な Item データを取得します。

最終的には次のようになります。

 <NewItems>
 <myNewItem ItemID="2">
       <SomeDataDirectlyFromItem>
            e.g. Title
       </SomeDataDirectlyFromItem>
       <DataConstructedFromMultipleColumnsInItem>
            <MyMilestones>
                  <MS_DATA_TRANSFORMED MSID="3">
                       data
                  </MS_DATA_TRANSFORMED>
                  <MS_DATA_TRANSFORMED MSID="4">
                       data
                  </MS_DATA_TRANSFORMED>
            </MyMilestones>
       </DataConstructedFromMultipleColumnsInItem>
  <myNewItem ItemID="3">
       <SomeDataDirectlyFromItem>
            e.g. Title
       </SomeDataDirectlyFromItem>
       <DataConstructedFromMultipleColumnsInItem>
            <MyMilestones>
                  <MS_DATA_TRANSFORMED MSID="5">
                       data
                  </MS_DATA_TRANSFORMED>
            </MyMilestones>
       </DataConstructedFromMultipleColumnsInItem>
 </myNewItem>
 <myNewItem ItemID="4">
       <SomeDataDirectlyFromItem>
            e.g. Title
       </SomeDataDirectlyFromItem>
       <DataConstructedFromMultipleColumnsInItem>
            <MyMilestones></MyMilestones>
       </DataConstructedFromMultipleColumnsInItem>
 </myNewItem>
 </NewItems>
4

2 に答える 2

0

script componentコンポーネントタイプのを使用してこれを処理しようとしますtransformation。あなたは ssis に慣れていないので、これまでにこれを使用したことがないと思います。だから基本的にあなたは

  • コンポーネントが期待する入力列を定義します(つまり、次input_xmlを含む列ItemID[1] - MilestoneData[2];...
  • C# を使用して、切り貼りするロジックを作成する
  • 変換された行を配信するためにコンポーネントが使用する出力列を定義します

つまり、1 つの行が最終的に 2 回使用される可能性があるという問題に直面します。

ItemID[1] - MilestoneData[2]

結果として

<item id="1">
      <Milestone id="2">

独自のロジックを定義するa のようなものを使用しなくても、Pentaho ケトルを使用してかなり似たようなことをしました。script componentしかし、ssisにはここでのタスクが不足していると思います。

于 2012-09-24T09:22:40.390 に答える
0

XML をリレーショナル テーブル ( tempdb など) にインポートしてから、 FOR XML PATH を使用して XML を再構築するのはどうでしょうか。FOR XML PATH を使用すると、XML の外観を高度に制御できます。以下の非常に簡単な例:

CREATE TABLE #items ( itemId INT PRIMARY KEY, title VARCHAR(50) NULL )
CREATE TABLE #milestones ( itemId INT, msId INT, msData VARCHAR(50) NOT NULL, PRIMARY KEY ( itemId, msId ) )
GO

DECLARE @itemsXML XML

SELECT @itemsXML = x.y
FROM OPENROWSET( BULK 'c:\temp\items.xml', SINGLE_CLOB ) x(y)

INSERT INTO #items ( itemId, title )
SELECT 
    i.c.value('@ItemID', 'INT' ),
    i.c.value('(Title/text())[1]', 'VARCHAR(50)' )
FROM @itemsXML.nodes('Items/Item') i(c)
GO


DECLARE @milestoneXML XML

SELECT @milestoneXML = x.y
FROM OPENROWSET( BULK 'c:\temp\milestone.xml', SINGLE_CLOB ) x(y)

INSERT INTO #milestones ( itemId, msId, msData )
SELECT 
    i.c.value('@ItemID', 'INT' ),
    i.c.value('(MS/@id)[1]', 'VARCHAR(50)' ) msId,
    i.c.value('(MS/MS_DATA/text())[1]', 'VARCHAR(50)' ) msData
FROM @milestoneXML.nodes('Milestones/Item') i(c)
GO

SELECT 
    i.itemId AS "@ItemID"
FROM #items i
    INNER JOIN #milestones ms ON i.itemId = ms.itemId
FOR XML PATH('myNewItem'), ROOT('NewItems'), TYPE


DROP TABLE #items 
DROP TABLE #milestones
于 2012-09-24T16:12:30.047 に答える