sql >> Database >  >> RDS >> Sqlserver

Hoe importeer ik tekstbestanden met dezelfde naam en hetzelfde schema, maar met verschillende mappen in de database?

Ja. U wilt een Foreach-bestandscontainer gebruiken en vink vervolgens de optie Submap doorkruisen aan.

Bewerken

Blijkbaar was mijn antwoord niet cromulent genoeg, dus accepteer alstublieft deze werkende code die illustreert wat mijn korte originele antwoord vermeldde.

Brongegevens

Ik heb 3 mappen gemaakt zoals hierboven beschreven om bestanden sample1.txt te bevatten en sample2.txt

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

De inhoud van het bestand staat hieronder. Elke versie van het bestand in elke map heeft de ID-waarde verhoogd, samen met de tekstwaarden gewijzigd om te bewijzen dat het nieuwe bestand is opgepikt.

ID,value
1,ABC

Pakketgeneratie

Dit deel gaat ervan uit dat je BIDS Helper hebt geïnstalleerd. Het is niet vereist voor de oplossing, maar biedt eenvoudig een gemeenschappelijk raamwerk dat toekomstige lezers kunnen gebruiken om deze oplossing te reproduceren

Ik heb een BIML-bestand gemaakt met de volgende inhoud. Ook al heb ik daar de tabel voor het maken van een tabel, ik moest die op de doelserver laten draaien voordat ik het pakket kon genereren.

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

Klik met de rechtermuisknop op het biml-bestand en selecteer Generate SSIS Package . Op dit moment zou u een pakket met de naam so_19957451 moeten hebben toegevoegd aan uw huidige SSIS-project.

Pakketconfiguratie

Er is geen configuratie nodig omdat het al via BIML is gedaan, maar moar screenshots zorgen voor betere antwoorden.

Dit is het basispakket

Hier zijn mijn variabelen

Configuratie van de Foreach Loop, zoals genoemd in het MSDN-artikel, evenals mijn opmerking om de submap Traverse te selecteren

Wijs de gegenereerde waarde per lus toe aan de variabele Stroom

Op de platte bestandsbron is een expressie toegepast op de eigenschap ConnectionString om ervoor te zorgen dat de variabele @User::CurrentFileName wordt gebruikt. Dit verandert de bron per uitvoering van de lus.

Uitvoeringsresultaten

Resultaten uit de database

Overeenkomen met de uitvoer van de pakketuitvoering




  1. Alleen-lezen weergaven maken in SQL Server

  2. linker join met lege rijen uit de rechtertabel mysql

  3. Hoe decimaal op te slaan in MySQL?

  4. Hoe to_timestamp() werkt in PostgreSQL