2011-08-21 98 views

回答

27

下面是在Foreach loop container,Script TaskFile System Task幫助下實現此目的的一種可能的解決方案。無需文件系統任務即可完成此操作。但是,我已經使用它來利用內置的控制流任務來移動文件。該示例是使用SSIS 2005創建的。

該示例假定文件將被統一命名。因此,該示例使用格式文件DD-MM-YYYY。例如,這些文件將命名爲File 29-07-2011File 15-08-2011等。

在SSIS包上,創建以下變量。在本例中,源文件存儲在文件夾位置F:\Temp\中,文件應移至位置* F:\ Temp \ Monthwise *。在目標文件夾,會有文件夾每個月像七月,八月等

  • DestinationFolder變量會擁有像F:\Temp\Monthwise\August最終目標文件夾的價值,但這個變量將裏面的實際值被分配腳本任務。現在,讓我們分配值F:\Temp\Monthwise\。這個臨時值是爲了避免文件系統任務在設計時拋出錯誤消息。

  • DestinationRoot將包含實際的根文件夾,在該文件夾下應根據月份名稱創建像July,August這樣的文件夾。

  • 源文件夾表示最初存儲所有文件的文件夾。在此示例中,源文件夾將爲F:\Temp\

  • SourceFilePath表示實際的文件路徑。當Foreach循環容器循環遍歷每個變量時,該變量將被賦予單個文件值。爲避免文件系統任務在設計時拋出錯誤消息,讓我們給它分配一些虛擬值F:\Temp\1.txt

  • FilePattern定義了應在給定源文件夾路徑中循環的文件模式。我們分配*.*,這意味着所有的文件都將循環播放。您也可以指定*.txtFile*.txtMy*.xls等。這是符合您的要求。

  • MonthStartPosition表示月份值在文件名中的起始位置。所以,在文件名格式File 29-07-2011中,07月從第9個字符開始。因此,值9.

  • MonthLength指定要提取的字符數。這將反正是2個字符,但我不想硬編碼。所以,我創建了一個變量。

  • MonthNameFormat指定應該如何創建文件夾。值MMMM表示它將創建具有完整月份名稱的文件夾,如1月,2月等。如果我們使用值MMM,則文件夾將創建爲1月,2月等。只有文件夾不存在時纔會創建文件夾。

Variables

在SSIS包的控制流標籤上,放置一個Foreach loop container並通過使用可變FilePattern文件模式在變量SourceFolder指定的文件夾將其配置爲環路。當Foreach循環容器遍歷文件時,文件名將被分配給變量SourceFilePath。我們將使用此變量來獲取腳本任務中的月份值。

Foreach loop container General

Foreach loop container Collection

Foreach loop container Variable Mappings

在foreach循環容器,放置Script Task和腳本任務的腳本部分單擊設計腳本...按鈕打開VSTA編輯和粘貼在這些屏幕截圖之後提供的代碼。由於該示例是在VS 2005中創建的,因此代碼編寫爲VB.NET,因爲這是SSIS 2005中唯一受支持的語言。

Script Task General

Script Task Script

Script Task Code

腳本任務代碼:的代碼從變量SourceFilePath完整的文件路徑值,而僅提取文件名,將其存儲在局部變量FileName

然後檢查MonthStartPositionMonthLength變量是否分配有適當的非零值。然後提取月份值以將其存儲在本地變量MonthValue中。

Uisng MonthValue它使用DateTime函數獲取完整的月份名稱值。值1分配給日期和年份,因爲我們只需要月份名稱。

在局部變量文件夾名月份名稱與DestinationRoot值相結合,以檢查該文件夾存在與否。如果該文件夾不存在,則將創建該文件夾,以便文件系統任務不會失敗。

最後將完整的目標文件夾值分配給包變量DestinationFolder。該變量將用於文件系統任務中。

VB.NET code for SSIS 2005

Imports System 
Imports System.Data 
Imports System.Math 
Imports Microsoft.SqlServer.Dts.Runtime 

Public Class ScriptMain 

    Public Sub Main() 

     Dim varCollection As Variables = Nothing 
     Dts.VariableDispenser.LockForRead("User::SourceFilePath") 
     Dts.VariableDispenser.LockForRead("User::DestinationRoot") 
     Dts.VariableDispenser.LockForRead("User::MonthStartPosition") 
     Dts.VariableDispenser.LockForRead("User::MonthLength") 
     Dts.VariableDispenser.LockForRead("User::MonthNameFormat") 
     Dts.VariableDispenser.LockForWrite("User::DestinationFolder") 
     Dts.VariableDispenser.GetVariables(varCollection) 

     Dim SourceFilePath As String = varCollection("User::SourceFilePath").Value.ToString() 
     Dim FileName As String = SourceFilePath.Substring(SourceFilePath.LastIndexOf("\") + 1) 
     Dim DestinationRoot As String = varCollection("User::DestinationRoot").Value.ToString() 
     Dim MonthStartPosition As Integer = Convert.ToInt32(varCollection("User::MonthStartPosition").Value) 
     Dim MonthLength As Integer = Convert.ToInt32(varCollection("User::MonthLength").Value) 
     Dim MonthValue As Integer = 0 
     Dim MonthNameFormat As String = varCollection("User::MonthNameFormat").Value.ToString() 
     Dim FolderName As String = String.Empty 
     Dim MonthwiseDirectory As String = String.Empty 

     If MonthStartPosition > 0 AndAlso MonthLength > 0 Then 
      MonthValue = Convert.ToInt32(FileName.Substring(MonthStartPosition - 1, MonthLength)) 
     End If 

     If FileName.Length > 0 AndAlso MonthValue > 0 Then 
      FolderName = New DateTime(1, MonthValue, 1).ToString(MonthNameFormat) 
     End If 

     MonthwiseDirectory = System.IO.Path.Combine(DestinationRoot, FolderName) 

     If Not System.IO.Directory.Exists(MonthwiseDirectory) Then 
      System.IO.Directory.CreateDirectory(MonthwiseDirectory) 
     End If 

     varCollection("User::DestinationFolder").Value = MonthwiseDirectory 

     Dts.TaskResult = Dts.Results.Success 
    End Sub 

End Class 

C# code for SSIS 2008 and above

public void Main() 
{ 
    Variables varCollection = null; 
    Dts.VariableDispenser.LockForRead("User::SourceFilePath"); 
    Dts.VariableDispenser.LockForRead("User::DestinationRoot"); 
    Dts.VariableDispenser.LockForRead("User::MonthStartPosition"); 
    Dts.VariableDispenser.LockForRead("User::MonthLength"); 
    Dts.VariableDispenser.LockForRead("User::MonthNameFormat"); 
    Dts.VariableDispenser.LockForWrite("User::DestinationFolder"); 
    Dts.VariableDispenser.GetVariables(ref varCollection); 

    string SourceFilePath = varCollection["User::SourceFilePath"].Value.ToString(); 
    string FileName = SourceFilePath.Substring(SourceFilePath.LastIndexOf('\\') + 1); 
    string DestinationRoot = varCollection["User::DestinationRoot"].Value.ToString(); 
    int MonthStartPosition = Convert.ToInt32(varCollection["User::MonthStartPosition"].Value); 
    int MonthLength = Convert.ToInt32(varCollection["User::MonthLength"].Value); 
    int MonthValue = 0; 
    string MonthNameFormat = varCollection["User::MonthNameFormat"].Value.ToString(); 
    string FolderName = string.Empty; 
    string MonthwiseDirectory = string.Empty; 

    if (MonthStartPosition > 0 && MonthLength > 0) 
    { 
     MonthValue = Convert.ToInt32(FileName.Substring(MonthStartPosition - 1, MonthLength)); 
    } 

    if (FileName.Length > 0 && MonthValue > 0) 
    { 
     FolderName = new DateTime(1, MonthValue, 1).ToString(MonthNameFormat); 
    } 

    MonthwiseDirectory = System.IO.Path.Combine(DestinationRoot, FolderName); 

    if (!System.IO.Directory.Exists(MonthwiseDirectory)) 
    { 
     System.IO.Directory.CreateDirectory(MonthwiseDirectory); 
    } 

    varCollection["User::DestinationFolder"].Value = MonthwiseDirectory; 

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

在foreach循環容器,放置文件系統任務腳本任務後。如屏幕截圖所示配置文件系統任務。

File System Task

一旦包裝任務被配置爲,控制流選項卡應該看起來像如下所示。

Control Flow

我們來測試包。在此之前,源文件夾F:\ Temp的內容如下所示。這些文件是虛擬的。因此,大小爲0 KB。

F Temp Folder

下面的屏幕截圖示出了包裝的成功執行。

Success

下面的截圖顯示瞭如何將文件已經被移動到已根據本月名稱來創建相應的目標文件夾。下面顯示了各個文件夾的內容。

希望有所幫助。

F Temp

F Temp Monthwise

F Temp Monthwise August

F Temp Monthwise January

F Temp Monthwise July

相關問題