Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie importiere ich Textdateien mit demselben Namen und Schema, aber unterschiedlichen Verzeichnissen in die Datenbank?

Ja. Sie sollten einen Foreach-Dateicontainer verwenden und aktivieren Sie dann die Option Unterordner durchsuchen.

Bearbeiten

Anscheinend war meine Antwort nicht aussagekräftig genug, also akzeptieren Sie bitte diesen funktionierenden Code, der veranschaulicht, was meine kurze ursprüngliche Antwort aussagte.

Quelldaten

Ich habe wie oben beschrieben 3 Ordner erstellt, um die Dateien sample1.txt zu enthalten und sample2.txt

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

Der Inhalt der Datei ist unten. Bei jeder Version der Datei in jedem Ordner wird der ID-Wert zusammen mit den geänderten Textwerten erhöht, um zu beweisen, dass die neue Datei aufgenommen wurde.

ID,value
1,ABC

Paketerstellung

Dieser Teil geht davon aus, dass Sie BIDS Helper haben Eingerichtet. Es ist für die Lösung nicht erforderlich, sondern stellt einfach ein allgemeines Framework bereit, das zukünftige Leser verwenden können, um diese Lösung zu reproduzieren.

Ich habe eine BIML-Datei mit folgendem Inhalt erstellt. Obwohl ich dort den Tabellenerstellungsschritt habe, musste ich diesen auf dem Zielserver ausführen lassen, bevor ich das Paket generieren konnte.

<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>

Klicken Sie mit der rechten Maustaste auf die biml-Datei und wählen Sie Generate SSIS Package . An dieser Stelle sollte Ihrem aktuellen SSIS-Projekt ein Paket namens so_19957451 hinzugefügt worden sein.

Paketkonfiguration

Es ist keine Konfiguration erforderlich, da dies bereits über BIML erfolgt ist, aber mehr Screenshots liefern bessere Antworten.

Dies ist das Basispaket

Hier sind meine Variablen

Konfiguration der Foreach-Schleife, wie im MSDN-Artikel genannt, sowie mein Hinweis zur Auswahl des Unterordners Traverse

Weisen Sie der Variable Current

den pro Schleife erzeugten Wert zu

Die Flatfilequelle hat einen Ausdruck, der auf die ConnectionString-Eigenschaft angewendet wird, um sicherzustellen, dass sie die Variable @User::CurrentFileName verwendet. Dies ändert die Quelle pro Ausführung der Schleife.

Ausführungsergebnisse

Ergebnisse aus der Datenbank

Übereinstimmung mit der Ausgabe der Paketausführung