Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak zaimportować pliki tekstowe o tej samej nazwie i schemacie, ale różnych katalogach do bazy danych?

TAk. Będziesz chciał użyć kontenera plików Foreach a następnie zaznacz opcję Traverse Subfolder.

Edytuj

Najwyraźniej moja odpowiedź nie była wystarczająco zwięzła, więc zaakceptuj ten działający kod, który ilustruje to, co stwierdziła moja krótka pierwotna odpowiedź.

Dane źródłowe

Utworzyłem 3 foldery, jak opisano powyżej, aby zawierały pliki sample1.txt i sample2.txt

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

Zawartość pliku znajduje się poniżej. Każda wersja pliku w każdym folderze ma zwiększony identyfikator wraz ze zmienionymi wartościami tekstowymi, aby udowodnić, że pobrał nowy plik.

ID,value
1,ABC

Generowanie pakietów

Ta część zakłada, że ​​masz BIDS Helper zainstalowany. Nie jest to wymagane dla rozwiązania, ale po prostu zapewnia wspólną strukturę, z której mogą korzystać przyszli czytelnicy, aby odtworzyć to rozwiązanie

Utworzyłem plik BIML z następującą zawartością. Mimo że mam tam krok tworzenia tabeli, musiałem go uruchomić na serwerze docelowym przed wygenerowaniem pakietu.

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

Kliknij prawym przyciskiem myszy plik biml i wybierz Generate SSIS Package . W tym momencie do bieżącego projektu SSIS powinien zostać dodany pakiet o nazwie so_19957451.

Konfiguracja pakietu

Nie ma potrzeby żadnej konfiguracji, ponieważ zostało to już wykonane za pomocą BIML, ale zrzuty ekranu zapewniają lepsze odpowiedzi.

To jest pakiet podstawowy

Oto moje zmienne

Konfiguracja pętli Foreach, jak wspomniano w artykule MSDN, a także w mojej notatce dotyczącej wyboru podfolderu Traverse

Przypisz wartość generowaną na pętlę do zmiennej Bieżący

Źródło pliku płaskiego ma wyrażenie zastosowane do właściwości ConnectionString, aby upewnić się, że używa zmiennej @User::CurrentFileName. Zmienia to źródło po wykonaniu pętli.

Wyniki wykonania

Wyniki z bazy danych

Dopasuj wynik wykonania pakietu




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zoptymalizować działanie Upsert (aktualizacja i wstawianie) w pakiecie SSIS?

  2. Pliki FILESTREAM pozostają po usunięciu wiersza

  3. Zabezpieczenia IIS7, SQL 2008 i ASP.NET MVC

  4. Lokalne i globalne tabele tymczasowe w SQL Server

  5. Wykonanie zapytania SSRS nie powiodło się dla zbioru danych