Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как мога да задам израз на свойството FileSpec на Foreach File enumerator?

От проучването как работи цикълът ForEach в SSIS (с оглед на създаването на моя собствена за разрешаване на проблема) изглежда, че начинът, по който работи (доколкото успях да видя така или иначе), е първо да изброя колекцията от файлове, преди да бъде поставена каквато и да е маска посочени. Трудно е да се каже какво точно се случва, без да се види базовият код за цикъла ForEach, но изглежда, че го прави по този начин, което води до ниска производителност при работа с над 100k файла.

Въпреки че решението на @Siva е фантастично подробно и определено е подобрение спрямо първоначалния ми подход, то по същество е същият процес, с изключение на използването на задача за изразяване за тестване на името на файла, а не задача за скрипт (това изглежда предлага известно подобрение).

Така че реших да възприема напълно различен подход и вместо да използвам базиран на файл цикъл ForEach, да изброя сам колекцията в скриптова задача, да приложа моята логика за филтриране и след това да повторя останалите резултати. Ето какво направих:

В моята скриптова задача използвам асинхронния DirectoryInfo.EnumerateFiles метод, който е препоръчителният подход за големи колекции от файлове, тъй като позволява поточно предаване, вместо да се налага да чакате да бъде създадена цялата колекция, преди да приложите някаква логика.

Ето кода:

public void Main()
{
    string sourceDir = Dts.Variables["SourceDirectory"].Value.ToString();
    int minJobId = (int)Dts.Variables["MinIndexId"].Value;

    //Enumerate file collection (using Enumerate Files to allow us to start processing immediately
    List<string> activeFiles = new List<string>();

    System.Threading.Tasks.Task listTask = System.Threading.Tasks.Task.Factory.StartNew(() =>
    {
         DirectoryInfo dir = new DirectoryInfo(sourceDir);
         foreach (FileInfo f in dir.EnumerateFiles("*.txt"))
         {
              FileInfo file = f;
              string filePath = file.FullName;
              string fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
              int jobId = Convert.ToInt32(fileName.Substring(0, fileName.IndexOf(".txt")));

              if (jobId > minJobId)
                   activeFiles.Add(filePath);
         }
    });

    //Wait here for completion
    System.Threading.Tasks.Task.WaitAll(new System.Threading.Tasks.Task[] { listTask });
    Dts.Variables["ActiveFilenames"].Value = activeFiles;
    Dts.TaskResult = (int)ScriptResults.Success;
}

И така, аз изброявам колекцията, прилагайки моята логика при откриване на файлове и незабавно добавяйки пътя на файла към моя списък за изход. След като завърша, присвоявам това на променлива на SSIS Object с име ActiveFilenames който ще използвам като колекция за моя цикъл ForEach.

Конфигурирах цикъла ForEach като ForEach From Variable Enumerator , който сега обхожда много по-малка колекция (Постфилтриран List<string> в сравнение с това, което мога само да предположа, че е нефилтриран List<FileInfo> или нещо подобно във вградения ForEach File Enumerator на SSIS .

Така че задачите в моя цикъл могат просто да бъдат посветени на обработката на данните, тъй като те вече са били филтрирани, преди да попаднат в цикъла. Въпреки че изглежда не се различава много от моя първоначален пакет или от примера на Siva, в производството (за този конкретен случай, така или иначе) изглежда, че филтрирането на колекцията и асинхронното изброяване осигурява огромен тласък в сравнение с използването на вградения ForEach файл Изброител.

Ще продължа да изследвам контейнера за цикъл ForEach и ще видя дали мога да репликирам тази логика в персонализиран компонент. Ако проработя, ще публикувам връзка в коментарите.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Добавете нова колона на таблица към конкретна редна позиция в Microsoft SQL Server

  2. Намиране на галета за вложени набори

  3. Обхват на временните таблици в SQL Server

  4. Какво е най-добре да проверите дали елементът съществува или не:Изберете Count(ID)OR Exist(...)?

  5. Как мога да разделя стойността на колоната на различни колони в SQL