SSIS一个平面文件源3列成2个联合所有

时间:2014-09-04 16:34:52

标签: sql-server-2008-r2 ssis

我有一个分隔的平面文件,有3列:

NEW #     DETAIL    OLD #
------    ------    ------
111111    AAAA      123456
222222    BBBB
333333    CCCC      987654

我需要输出

#         DETAIL   
------    ------
111111    AAAA      
222222    BBBB
333333    CCCC      
123456    AAAA
987654    CCCC

我需要忽略OLD#列中的空值。

我不确定实现这一目标的最佳方法。如果您有多个来源,Union All和/或merge似乎可以正常工作。

1 个答案:

答案 0 :(得分:1)

一般概念是您需要Unpivot。 Jason Strate用他的31 days of SSIS series发表了一篇非常好的文章。

基本思想是你要保留DETAIL列,让其他两个流进去。 Unpivot是规范化数据的本机操作。

来源

我使用了一个查询,因为它更容易上瘾,我连续添加了一个明确的NULL值。

SELECT
*
FROM
(
    VALUES
    ('111111','AAAA','123456')
,   ('222222','BBBB','')
,   ('333333','CCCC','987654')
,   ('444444','DDDD',NULL)
) D([NEW #], [DETAIL],[OLD #]); 

Unpviot

操作将取消数据的转移。这消除了NULL值,但保留了空字符串。这可能是您想要的结果,也可能不是。

enter image description here

结果

此时,您可以看到我们有空字符串行。你可以用两种方式解决这个问题,我会让你选择你的方法。

  • 上游 - 将空字符串清空为NULL以进行删除
  • 下游 - 使用条件拆分删除具有空数字值的行

enter image description here

BIML

商业智能标记语言Biml描述了商业智能平台。在这里,我们将用它来描述ETL。 BIDS Helper,是Visual Studio / BIDS / SSDT的免费补充,它解决了许多缺点。具体来说,我们将使用将描述ETL的Biml文件转换为SSIS包的能力。这样做的另一个好处是为您提供了一种机制,使您能够准确生成我正在描述的解决方案,而不是点击许多繁琐的对话框。

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <OleDbConnection ConnectionString="Provider=SQLNCLI11;Data Source=localhost\dev2014;Integrated Security=SSPI;Initial Catalog=tempdb" Name="CM_OLE" />
    </Connections>
    <Packages>
        <Package 
            ConstraintMode="Linear" 
            Name="so_25670727">
            <Tasks>
                <Dataflow Name="DFT Combine all">
                    <Transformations>
                        <!--
                        Generate some source data. Added a row with an explicit NULL
                        as no real testing is done unless we have to deal with NULLs
                        -->
                        <OleDbSource ConnectionName="CM_OLE" Name="OLE_SRC Query">
                            <DirectInput>
SELECT
*
FROM
(
    VALUES
    ('111111','AAAA','123456')
,   ('222222','BBBB','')
,   ('333333','CCCC','987654')
,   ('444444','DDDD',NULL)
) D([NEW #], [DETAIL],[OLD #]);                                
                            </DirectInput>
                        </OleDbSource>
                        <!--
                        Unpivot the data. Combine NEW # and OLD # into a single column called Number.
                        A "Pivot Key Value" column will also be generated that identifies where the value came
                        from.
                        -->
                        <Unpivot Name="UP Detail">
                            <Columns>
                                <Column SourceColumn="DETAIL" TargetColumn="DETAIL"/>
                                <Column SourceColumn="NEW #" TargetColumn="Number" PivotKeyValue="NEW #"/>
                                <Column SourceColumn="OLD #" TargetColumn="Number" PivotKeyValue="OLD #"/>
                            </Columns>
                        </Unpivot>
                        <!--
                        Put something here so we can attach a data viewer
                        Notice, the NULL does not show in the output but the empty string does.
                        Depending on your tolerance, you will want to either
                        * Upstream - scrub empty strings to NULL for elimination 
                        * Upstream - convert NULL to empty string for preservation
                        * Downstream - use a Conditional Split to remove the rows with empty Number columns
                        -->
                        <DerivedColumns Name="DER DataViewer">
                        </DerivedColumns>
                    </Transformations>
                </Dataflow>
            </Tasks>
        </Package>
    </Packages>
</Biml>