스크립트 태스크를 사용하여 ForEach 루프에 대한 목록 수집
적용 대상: Azure Data Factory의 SQL Server SSIS Integration Runtime
변수 열거자의 Foreach는 변수에 전달된 목록의 항목을 열거하고 각 항목에 대해 동일한 작업을 수행합니다. 스크립트 태스크에서 사용자 지정 코드를 사용하여 이 용도로 목록을 채울 수 있습니다. 이 열거자에 대한 자세한 내용은 Foreach 루프 컨테이너를 참조하세요.
참고 항목
여러 패키지에서 더 쉽게 다시 사용할 수 있는 작업을 만들려면 이 스크립트 태스크 샘플의 코드를 사용자 지정 작업의 시작점으로 사용하는 것이 좋습니다. 자세한 내용은 사용자 지정 작업 개발을 참조하세요.
설명
다음 예제에서는 System.IO 네임스페이스의 메서드를 사용하여 사용자가 변수에 지정한 날짜보다 오래되었거나 최신인 컴퓨터의 Excel 통합 문서 목록을 수집합니다. C 드라이브의 디렉터리에서 .xls 확장명이 있는 파일을 재귀적으로 검색하고 각 파일이 마지막으로 수정된 날짜를 검사하여 파일이 목록에 속하는지 여부를 확인합니다. ArrayList에 정규화 파일을 추가하고 나중에 Foreach 루프 컨테이너에서 사용할 수 있도록 ArrayList를 변수에 저장합니다. Foreach 루프 컨테이너는 변수 열거자의 Foreach를 사용하도록 구성됩니다.
참고 항목
변수 열거자의 Foreach와 함께 사용하는 변수는 Object 형식이어야 합니다. 변수에 배치하는 개체는 System.Collections.IEnumerable, System.Runtime.InteropServices.ComTypes.IEnumVARIANT, System.ComponentModel IListSource 또는 Microsoft.SqlServer.Dts.Runtime.Wrapper.ForEachEnumeratorHost 인터페이스 중 하나를 구현해야 합니다. Array 또는 ArrayList는 일반적으로 사용됩니다. ArrayList에는 System.Collections 네임스페이스에 대한 참조 및 Imports 문이 필요합니다.
FileAge
패키지 변수에 각기 다른 양수 및 음수 값을 사용하여 이 태스크를 시험해 볼 수 있습니다. 예를 들어 5를 입력하여 지난 5일 동안 만든 파일을 검색하거나 -3을 입력하여 3일 전에 만든 파일을 검색할 수 있습니다. 드라이브에 검색할 폴더가 많은 경우 이 태스크를 수행하는 데 1~2분 정도 소요될 수 있습니다.
이 스크립트 태스크 예제를 구성하려면
정수
FileAge
형식이라는 패키지 변수를 만들고 양수 또는 음수 정수 값을 입력합니다. 값이 양수이면 코드는 만든 날짜 또는 수정한 날짜가 지정된 일 수를 경과하지 않은 파일을 검색하고, 값이 음수이면 지정된 일 수를 경과한 파일을 검색합니다.나중에 Foreach가 변수 열거자에서 사용할 수 있도록 스크립트 태스크에서 수집한 파일 목록을 받을 개체 형식의 패키지 변수
FileList
를 만듭니다.FileAge
스크립트 태스크의 ReadOnlyVariables 속성에 변수를 추가하고 ReadWriteVariables 속성에 변수를 추가FileList
합니다.코드에서 System.Collections 및 System.IO 네임스페이스를 가져옵니다.
코드
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.Collections
Imports System.IO
Public Class ScriptMain
Private Const FILE_AGE As Integer = -50
Private Const FILE_ROOT As String = "C:\"
Private Const FILE_FILTER As String = "*.xls"
Private isCheckForNewer As Boolean = True
Dim fileAgeLimit As Integer
Private listForEnumerator As ArrayList
Public Sub Main()
fileAgeLimit = DirectCast(Dts.Variables("FileAge").Value, Integer)
' If value provided is positive, we want files NEWER THAN n days.
' If negative, we want files OLDER THAN n days.
If fileAgeLimit < 0 Then
isCheckForNewer = False
End If
' Extract number of days as positive integer.
fileAgeLimit = Math.Abs(fileAgeLimit)
listForEnumerator = New ArrayList
GetFilesInFolder(FILE_ROOT)
' Return the list of files to the variable
' for later use by the Foreach from Variable enumerator.
System.Windows.Forms.MessageBox.Show("Matching files: " & listForEnumerator.Count.ToString, "Results", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
Dts.Variables("FileList").Value = listForEnumerator
Dts.TaskResult = ScriptResults.Success
End Sub
Private Sub GetFilesInFolder(ByVal folderPath As String)
Dim localFiles() As String
Dim localFile As String
Dim fileChangeDate As Date
Dim fileAge As TimeSpan
Dim fileAgeInDays As Integer
Dim childFolder As String
Try
localFiles = Directory.GetFiles(folderPath, FILE_FILTER)
For Each localFile In localFiles
fileChangeDate = File.GetLastWriteTime(localFile)
fileAge = DateTime.Now.Subtract(fileChangeDate)
fileAgeInDays = fileAge.Days
CheckAgeOfFile(localFile, fileAgeInDays)
Next
If Directory.GetDirectories(folderPath).Length > 0 Then
For Each childFolder In Directory.GetDirectories(folderPath)
GetFilesInFolder(childFolder)
Next
End If
Catch
' Ignore exceptions on special folders such as System Volume Information.
End Try
End Sub
Private Sub CheckAgeOfFile(ByVal localFile As String, ByVal fileAgeInDays As Integer)
If isCheckForNewer Then
If fileAgeInDays <= fileAgeLimit Then
listForEnumerator.Add(localFile)
End If
Else
If fileAgeInDays > fileAgeLimit Then
listForEnumerator.Add(localFile)
End If
End If
End Sub
End Class
using System;
using System.Data;
using System.Math;
using Microsoft.SqlServer.Dts.Runtime;
using System.Collections;
using System.IO;
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
private const int FILE_AGE = -50;
private const string FILE_ROOT = "C:\\";
private const string FILE_FILTER = "*.xls";
private bool isCheckForNewer = true;
int fileAgeLimit;
private ArrayList listForEnumerator;
public void Main()
{
fileAgeLimit = (int)(Dts.Variables["FileAge"].Value);
// If value provided is positive, we want files NEWER THAN n days.
// If negative, we want files OLDER THAN n days.
if (fileAgeLimit<0)
{
isCheckForNewer = false;
}
// Extract number of days as positive integer.
fileAgeLimit = Math.Abs(fileAgeLimit);
listForEnumerator = new ArrayList();
GetFilesInFolder(FILE_ROOT);
// Return the list of files to the variable
// for later use by the Foreach from Variable enumerator.
System.Windows.Forms.MessageBox.Show("Matching files: "+ listForEnumerator.Count, "Results",
MessageBoxButtons.OK, MessageBoxIcon.Information);
Dts.Variables["FileList"].Value = listForEnumerator;
Dts.TaskResult = (int)ScriptResults.Success;
}
private void GetFilesInFolder(string folderPath)
{
string[] localFiles;
DateTime fileChangeDate;
TimeSpan fileAge;
int fileAgeInDays;
try
{
localFiles = Directory.GetFiles(folderPath, FILE_FILTER);
foreach (string localFile in localFiles)
{
fileChangeDate = File.GetLastWriteTime(localFile);
fileAge = DateTime.Now.Subtract(fileChangeDate);
fileAgeInDays = fileAge.Days;
CheckAgeOfFile(localFile, fileAgeInDays);
}
if (Directory.GetDirectories(folderPath).Length > 0)
{
foreach (string childFolder in Directory.GetDirectories(folderPath))
{
GetFilesInFolder(childFolder);
}
}
}
catch
{
// Ignore exceptions on special folders, such as System Volume Information.
}
}
private void CheckAgeOfFile(string localFile, int fileAgeInDays)
{
if (isCheckForNewer)
{
if (fileAgeInDays <= fileAgeLimit)
{
listForEnumerator.Add(localFile);
}
}
else
{
if (fileAgeInDays > fileAgeLimit)
{
listForEnumerator.Add(localFile);
}
}
}
}