Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment importer des fichiers texte avec le même nom et schéma mais des répertoires différents dans la base de données ?

Oui. Vous voudrez utiliser un Foreach File Container puis cochez l'option Parcourir le sous-dossier.

Modifier

Apparemment, ma réponse n'était pas assez cromulante, alors veuillez accepter ce code de travail qui illustre ce que ma brève réponse originale a déclaré.

Données sources

J'ai créé 3 dossiers comme décrit ci-dessus pour contenir les fichiers sample1.txt et sample2.txt

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

Le contenu du fichier est ci-dessous. Chaque version du fichier dans chaque dossier a la valeur ID incrémentée ainsi que les valeurs de texte modifiées pour prouver qu'il a récupéré le nouveau fichier.

ID,value
1,ABC

Génération de packages

Cette partie suppose que vous avez BIDS Helper installée. Il n'est pas nécessaire pour la solution mais fournit simplement un cadre commun que les futurs lecteurs pourraient utiliser pour reproduire cette solution

J'ai créé un fichier BIML avec le contenu suivant. Même si j'ai l'étape de création de table là-dedans, j'avais besoin de l'exécuter sur le serveur cible avant de générer le package.

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

Faites un clic droit sur le fichier biml et sélectionnez Generate SSIS Package . À ce stade, vous devriez avoir un package nommé so_19957451 ajouté à votre projet SSIS actuel.

Configuration du paquet

Aucune configuration n'est nécessaire, car cela a déjà été fait via BIML, mais les captures d'écran moar apportent de meilleures réponses.

C'est le forfait de base

Voici mes variables

Configuration de la boucle Foreach, comme indiqué dans l'article MSDN ainsi que ma note de sélection du sous-dossier Traverse

Affectez la valeur générée par boucle à la variable Courant

La source du fichier plat a une expression appliquée à la propriété ConnectionString pour s'assurer qu'elle utilise la variable @User::CurrentFileName. Cela change la source par exécution de la boucle.

Résultats d'exécution

Résultats de la base de données

Faites correspondre la sortie de l'exécution du package