8

我需要将多个具有相同名称和相同模式的 txt 文件导入 SQL Server 2008 数据库中的同一个表中。我遇到的问题是它们都在不同的目录中:

TEST
     201304
            sample1.txt
            sample2.txt
     201305
            sample1.txt
            sample2.txt
     201306
            sample1.txt
            sample2.txt

SSIS中有什么方法可以设置吗?

4

1 回答 1

19

是的。您将需要使用Foreach 文件容器,然后检查 Traverse Subfolder 选项。

编辑

显然我的回答不够好​​,所以请接受这个工作代码,它说明了我简短的原始答案所说的内容。

源数据

我如上所述创建了 3 个文件夹来包含文件sample1.txtsample2.txt

C:\>MKDIR SSISDATA\SO\TEST\201304
C:\>MKDIR SSISDATA\SO\TEST\201305
C:\>MKDIR SSISDATA\SO\TEST\201306

该文件的内容如下。每个文件夹中文件的每个版本都具有递增的 ID 值以及更改的文本值,以证明它已拾取新文件。

ID,value
1,ABC

包生成

这部分假设您已经安装了BIDS Helper。它不是解决方案所必需的,只是提供了一个未来读者可以用来重现此解决方案的通用框架

我创建了一个包含以下内容的 BIML 文件。即使我在那里有表创建步骤,我也需要在生成包之前在目标服务器上运行它。

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <!-- Create a basic flat file source definition -->
    <FileFormats>
        <FlatFileFormat
            Name="FFFSrc"
            CodePage="1252"
            RowDelimiter="CRLF"
            IsUnicode="false"
            FlatFileType="Delimited"
            ColumnNamesInFirstDataRow="true"
        >
            <Columns>
                <Column
                    Name="ID"
                    DataType="Int32"
                    Delimiter=","
                    ColumnType="Delimited"
                />
                <Column
                    Name="value"
                    DataType="AnsiString"
                    Delimiter="CRLF"
                    InputLength="20"
                    MaximumWidth="20"
                    Length="20"
                    CodePage="1252"
                    ColumnType="Delimited"
                    />
            </Columns>
        </FlatFileFormat>
    </FileFormats>

    <!-- Create a connection that uses the flat file format defined above-->
    <Connections>
        <FlatFileConnection
            Name="FFSrc"
            FileFormat="FFFSrc"
            FilePath="C:\ssisdata\so\TEST\201306\sample1.txt"
            DelayValidation="true"
        />
        <OleDbConnection
            Name="tempdb"
            ConnectionString="Data Source=localhost\dev2012;Initial Catalog=tempdb;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;"
        />

    </Connections>

    <!-- Create a package to illustrate how to apply an expression on the Connection Manager -->
    <Packages>
        <Package
            Name="so_19957451"
            ConstraintMode="Linear"
        >
            <Connections>
                <Connection ConnectionName="tempdb"/>
                <Connection ConnectionName="FFSrc">
                    <Expressions>
                        <!-- Assign a variable to the ConnectionString property. 
                        The syntax for this is ConnectionManagerName.Property -->
                        <Expression PropertyName="FFSrc.ConnectionString">@[User::CurrentFileName]</Expression>
                    </Expressions>
                </Connection>
            </Connections>

            <!-- Create a single variable that points to the current file -->
            <Variables>
                <Variable Name="CurrentFileName" DataType="String">C:\ssisdata\so\TEST\201306\sample1.txt</Variable>
                <Variable Name="FileMask" DataType="String">*.txt</Variable>
                <Variable Name="SourceFolder" DataType="String">C:\ssisdata\so\TEST</Variable>
                <Variable Name="RowCountInput" DataType="Int32">0</Variable>
                <Variable Name="TargetTable" DataType="String">[dbo].[so_19957451]</Variable>
            </Variables>

            <!-- Add a foreach file enumerator. Use the above -->
            <Tasks>
                <ExecuteSQL 
                    Name="SQL Create Table"
                    ConnectionName="tempdb">
                    <DirectInput>
                        IF NOT EXISTS (SELECT * FROM sys.tables T WHERE T.name = 'so_19957451' and T.schema_id = schema_id('dbo'))
                        BEGIN
                            CREATE TABLE dbo.so_19957451(ID int NOT NULL, value varchar(20) NOT NULL);
                        END
                    </DirectInput>
                </ExecuteSQL>
                <ForEachFileLoop
                    Name="FELC Consume files"
                    FileSpecification="*.csv"
                    ProcessSubfolders="true"
                    RetrieveFileNameFormat="FullyQualified"
                    Folder="C:\"
                    ConstraintMode="Linear"
                >
                    <!-- Define the expressions to make the input folder and the file mask 
                    driven by variable values -->
                    <Expressions>
                        <Expression PropertyName="Directory">@[User::SourceFolder]</Expression>
                        <Expression PropertyName="FileSpec">@[User::FileMask]</Expression>
                    </Expressions>
                    <VariableMappings>
                        <!-- Notice that we use the convention of User.Variable name here -->
                        <VariableMapping
                            Name="0"
                            VariableName="User.CurrentFileName"
                        />
                    </VariableMappings>
                    <Tasks>
                        <Dataflow Name="DFT Import file" DelayValidation="true">
                            <Transformations>
                                <FlatFileSource Name="FFS Sample" ConnectionName="FFSrc"/>
                                <RowCount Name="RC Source" VariableName="User.RowCountInput"/>
                                <OleDbDestination 
                                    Name="OLE_DST"
                                    ConnectionName="tempdb">
                                    <TableFromVariableOutput VariableName="User.TargetTable"/>                                  
                                </OleDbDestination>
                            </Transformations>
                        </Dataflow>
                    </Tasks>
                </ForEachFileLoop>
            </Tasks>
        </Package>
    </Packages>
</Biml>

右键单击 biml 文件并选择Generate SSIS Package. 此时,您应该将一个名为 so_19957451 的包添加到您当前的 SSIS 项目中。

包配置

不需要任何配置,因为它已经通过 BIML 完成,但是 moar 屏幕截图可以提供更好的答案。

这是基本包

控制流

这是我的变量

变量

Foreach 循环的配置,如 MSDN 文章以及我的选择 Traverse 子文件夹中所述

遍历子文件夹

将每个循环生成的值赋给变量 Current

分配变量

平面文件源有一个应用于 ConnectionString 属性的表达式,以确保它使用变量 @User::CurrentFileName。这会在每次执行循环时更改源。

在此处输入图像描述

执行结果

来自数据库的结果

在此处输入图像描述

匹配包执行的输出

信息:0x402090DC at DFT Import file, FFS Sample [2]:文件“C:\ssisdata\so\TEST\201304\sample1.txt”的处理已经开始。

信息:0x402090DD at DFT Import file, FFS Sample [2]: 文件“C:\ssisdata\so\TEST\201304\sample1.txt”的处理已经结束。

信息:0x402090DC at DFT Import file, FFS Sample [2]:文件“C:\ssisdata\so\TEST\201304\sample2.txt”的处理已经开始。

信息:0x402090DD at DFT Import file, FFS Sample [2]: 文件“C:\ssisdata\so\TEST\201304\sample2.txt”的处理已经结束。

信息:0x402090DC at DFT Import file, FFS Sample [2]:文件“C:\ssisdata\so\TEST\201305\sample1.txt”的处理已经开始。

信息:0x402090DD at DFT Import file, FFS Sample [2]:文件“C:\ssisdata\so\TEST\201305\sample1.txt”的处理已经结束。

信息:0x402090DC at DFT Import file, FFS Sample [2]:文件“C:\ssisdata\so\TEST\201305\sample2.txt”的处理已经开始。

信息:0x402090DD at DFT Import file, FFS Sample [2]: 文件“C:\ssisdata\so\TEST\201305\sample2.txt”的处理已经结束。

信息:0x402090DC at DFT Import file, FFS Sample [2]:文件“C:\ssisdata\so\TEST\201306\sample1.txt”的处理已经开始。

信息:0x402090DD at DFT Import file, FFS Sample [2]:文件“C:\ssisdata\so\TEST\201306\sample1.txt”的处理已经结束。

信息:0x402090DC at DFT Import file, FFS Sample [2]:文件“C:\ssisdata\so\TEST\201306\sample2.txt”的处理已经开始。

信息:0x402090DD at DFT Import file, FFS Sample [2]: 文件“C:\ssisdata\so\TEST\201306\sample2.txt”的处理已经结束。

于 2013-11-13T15:28:14.180 回答