10
votes

Importer le fichier CSV le plus récent sur SQL Server dans SSIS

J'ai un dossier dans lequel je reçois des fichiers .csv pour chaque demi-heure avec des timbres horodataires. Maintenant, je dois prendre le dernier fichier à partir des fichiers disponibles et l'importer dans SQL Server.

Par exemple

Dans mon dossier source, j'ai

Test_01112012_120122.CSV
Test_01112012_123022.CSV
Test_01112012_123555.CSV

Maintenant, je dois récupérer le dernier fichier et importer ce fichier dans SQL Server à l'aide de SSIS.

Merci
Satish


0 commentaires

3 Réponses :


-1
votes

Jetez un coup d'œil à cet article pour la liste de répertoires dans TSQL http://www.simple-talk.com/sql/t-sql-programmer/the-tsql-of-text-files/

Ensuite, vous pouvez trouver le dernier en les commandant.


0 commentaires

3
votes

En supposant que vous vouliez utiliser c #, pour obtenir le fichier le plus récent dans un répertoire donné, vous pouvez utiliser une méthode comme celle-ci ...

private static FileInfo GetLatestFile(string directoryName, string fileExtension)
{
    DirectoryInfo directoryInfo = new DirectoryInfo(directoryName);
    return directoryInfo.GetFiles(fileExtension)
         .OrderByDescending(q => q.LastWriteTimeUtc)
         .FirstOrDefault();
}


4 commentaires

Je voudrais connaître cette approche dans les SSIS.


Si la balise C # est supprimée?


Comment puis-je utiliser votre code pour ma question ici: Stackoverflow.com/Questtions/22969449/...


@ Sikni8, vous devez probablement utiliser un utilitaire C # pour lire le système de fichiers et peupler directement une table. Ensuite, lisez de la table



15
votes

Le code de @garry Vass ou une comme elle est nécessaire, même si vous utilisez SSIS comme outil d'importation.

Au sein du SSIS, vous devrez mettre à jour la chaîne de connexion à votre gestionnaire de connexion à votre fichier plat pour pointer vers le nouveau fichier. ERGO, vous devez déterminer quel est le fichier le plus récent. p>

Recherche du fichier le plus récent h2>

si vous le faites par attributs de fichier (le code de Garry) ou la découpage et la dés des noms de fichiers dépendent de vos règles de gestion. Est-ce toujours le fichier (attribut) le plus récemment modifié (attribut) ou doit-il être basé sur le nom du fichier interprété comme une séquence? Ceci compte si le Test_01112012012_120122.CSV code> avait une erreur dedans et le contenu est mis à jour. La date modifiée modifiera, mais le nom du fichier ne sera pas et que ces modifications ne seraient pas transmises dans la base de données. P>

Je vous suggère de créer 2 variables de type chaîne et scopé au package nommé RootFolder code> et actuelFile code>. En option, vous pouvez créer un appelé FileMASK si vous limitez-le à un type particulier comme *. CSV code>. RootFolder Code> Ce serait le dossier de base que vous prévoyez de trouver des fichiers dans C: \ ssisdata \ myProject code>. CurrentFile CODE> sera attribué une valeur d'un script du chemin d'accès parfaitement qualifié au fichier le plus récemment modifié. Je trouve utile à ce point d'affecter une valeur de temps de conception au courant actuel, généralement au fichier le plus ancien de la collection. P>

Faites glisser une tâche de script sur le flux de contrôle et défini comme utilisateur lisonlyvariable :: Rorofolder (éventuellement utilisateur :: Filemask). Votre readwriteVariable serait utilisateur :: actuelFile. Éditer le script p>

Ce script irait à l'intérieur du script de catégorie "Code> Public Partial :. .. Code> Bretelles P>

    /// <summary>
    /// This verbose script identifies the most recently modified file of type fileMask
    /// living in RootFolder and assigns that to a DTS level variable.
    /// </summary>
    public void Main()
    {
        string fileMask = "*.csv";
        string mostRecentFile = string.Empty;
        string rootFolder = string.Empty;

        // Assign values from the DTS variables collection.
        // This is case sensitive. User:: is not required
        // but you must convert it from the Object type to a strong type
        rootFolder = Dts.Variables["User::RootFolder"].Value.ToString();

        // Repeat the above pattern to assign a value to fileMask if you wish
        // to make it a more flexible approach

        // Determine the most recent file, this could be null
        System.IO.FileInfo candidate = ScriptMain.GetLatestFile(rootFolder, fileMask);

        if (candidate != null)
        {
            mostRecentFile = candidate.FullName;
        }

        // Push the results back onto the variable
        Dts.Variables["CurrentFile"].Value = mostRecentFile;

        Dts.TaskResult = (int)ScriptResults.Success;
    }

    /// <summary>
    /// Find the most recent file matching a pattern
    /// </summary>
    /// <param name="directoryName">Folder to begin searching in</param>
    /// <param name="fileExtension">Extension to search, e.g. *.csv</param>
    /// <returns></returns>
    private static System.IO.FileInfo GetLatestFile(string directoryName, string fileExtension)
    {
        System.IO.DirectoryInfo directoryInfo = new System.IO.DirectoryInfo(directoryName);

        System.IO.FileInfo mostRecent = null;

        // Change the SearchOption to AllDirectories if you need to search subfolders
        System.IO.FileInfo[] legacyArray = directoryInfo.GetFiles(fileExtension, System.IO.SearchOption.TopDirectoryOnly);
        foreach (System.IO.FileInfo current in legacyArray)
        {
            if (mostRecent == null)
            {
                mostRecent = current;
            }

            if (current.LastWriteTimeUtc >= mostRecent.LastWriteTimeUtc)
            {
                mostRecent = current;
            }
        }

        return mostRecent;

        // To make the below code work, you'd need to edit the properties of the project
        // change the TargetFramework to probably 3.5 or 4. Not sure
        // Current error is the OrderByDescending doesn't exist for 2.0 framework
        //return directoryInfo.GetFiles(fileExtension)
        //     .OrderByDescending(q => q.LastWriteTimeUtc)
        //     .FirstOrDefault();
    }

    #region ScriptResults declaration
    /// <summary>
    /// This enum provides a convenient shorthand within the scope of this class for setting the
    /// result of the script.
    /// 
    /// This code was generated automatically.
    /// </summary>
    enum ScriptResults
    {
        Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
        Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
    };
    #endregion

}


3 commentaires

Merci Garry et Billinkc, cet article était très utile et j'aimerais poser une autre chose, comment obtenir ce dernier nom de fichier généré dans la tâche de script à larguer dans ma table de destination dans SQL Server.


Utilisez cette variable dans une tâche de colonne dérivée. Je vais y répondre sur votre autre question aussi Stackoverflow.com/Questions/8877695/...


Comment puis-je réaliser cela ici: Stackoverflow.com/questions/22969449/...