sql >> Databasteknik >  >> RDS >> Sqlserver

Hur importerar man textfiler med samma namn och schema men olika kataloger till databasen?

Ja. Du kommer att vilja använda en Foreach File Container och markera sedan alternativet Traverse Subfolder.

Redigera

Mitt svar var uppenbarligen inte tillräckligt krångligt, så acceptera den här fungerande koden som illustrerar vad mitt korta ursprungliga svar stod.

Källdata

Jag skapade 3 mappar enligt beskrivningen ovan för att innehålla filerna sample1.txt och sample2.txt

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

Innehållet i filen finns nedan. Varje version av filen i varje mapp har ID-värdet ökat tillsammans med textvärdena som ändrats för att bevisa att den har hämtat den nya filen.

ID,value
1,ABC

Paketgenerering

Den här delen förutsätter att du har BIDS Helper installerat. Det krävs inte för lösningen utan ger helt enkelt ett gemensamt ramverk som framtida läsare kan använda för att reproducera denna lösning

Jag skapade en BIML-fil med följande innehåll. Även om jag har steget skapa tabellen där, behövde jag köra det på målservern innan jag genererade paketet.

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

Högerklicka på biml-filen och välj Generate SSIS Package . Vid det här laget bör du ha ett paket med namnet so_19957451 lagt till ditt nuvarande SSIS-projekt.

Paketkonfiguration

Det finns inget behov av någon konfiguration eftersom det redan har gjorts via BIML men moar skärmdumpar ger bättre svar.

Detta är grundpaketet

Här är mina variabler

Konfiguration av Foreach Loop, som kallas i MSDN-artikeln samt min anteckning om att välja undermappen Traverse

Tilldela värdet som genereras per slinga till variabeln Aktuell

Den platta filkällan har ett uttryck som tillämpas på egenskapen ConnectionString för att säkerställa att den använder variabeln @User::CurrentFileName. Detta ändrar källan per körning av loopen.

Körningsresultat

Resultat från databasen

Matcha utdata från paketkörningen




  1. MySQL-prestanda:Konvertera MySQL till MariaDB

  2. Laravel 5.4 Kombinerar två kollektioner

  3. Ansluter till MySQL från andra maskiner

  4. Få bara poster skapade idag i laravel