SSIS:从文件夹中获取任何平面文件源,并将名称缓存为超级全局变量

时间:2011-06-03 15:59:33

标签: ssis

我在SSIS和Visual Studio 2008中工作。执行时,我需要让SSIS包执行以下任务:

  • 检查文件夹中的文件
  • 如果存在文件,请获取该文件并将其用作平面文件的来源
  • 将文件名存储到我可以在程序包的其他部分访问的全局变量中

该包将由其他一些脚本运行。因此,每次包运行时我们都需要它来检查文件。我们正在尝试阻止我们必须监视文件夹并在文件出现时手动执行包的情况。

有什么建议吗?

2 个答案:

答案 0 :(得分:7)

最简单的方法是设置一个Foreach循环容器,其中包含所有包的“工作”(可选地,您可以将其作为前驱步骤并使用它的条件表达式)。假设你有两个名为FileName的变量(你将赋值给它的那个)和一个包含我们应该看的“where”的InputFolder变量

ForEach Loop Editor

Collection tab:  
Enumerator = Foreach File Enumerators
Expression: Directory = @[User:InputFolder]
FileSpec: "YD.*"

Retrieve file name
* Fully qualified

Variable Mappings tab:  
Variable: User::FileName 
Index:  0

Collection Tab Variable Mappings Tab

您也可以通过脚本任务执行此操作,如果您想查看,请告诉我。

EDIT 此脚本再次假定您已定义变量InputFolder和FileName。创建一个脚本任务组件并将InputFolder检查为只读变量,将FileName检查为读/写变量。

using System;
using System.Data;
using System.IO;  // this needs to be added
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;

// namespace will vary 
namespace ST_bc177fa7cb7d4faca15531cb700b7f11.csproj
{
    [System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {

        #region VSTA generated code
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
        #endregion

        public void Main()
        {
            string inputFolder;
            string fileName;
            inputFolder = Dts.Variables["InputFolder"].Value.ToString();

            // File, if exists will look like YD.CCYYMMDD.hhmmss.done
            string fileMask = "YD.*.done";

            // this array will catch all the files matching a given pattern
            string[] foundFiles = null;
            foundFiles = System.IO.Directory.GetFiles(inputFolder, fileMask);

            // Since there should be only one file, we will grab the zeroeth
            // element, should it exist
            if (foundFiles.Length > 0)
            {
                fileName = foundFiles[0];

                // write the value to our global SSIS variable
                Dts.Variables["FileName"].Value = fileName;
            }

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

答案 1 :(得分:5)

这是一个可能的选择。您可以使用Foreach Loop容器来实现此目的。请找到我在下面提供的示例。希望这能给出一个想法。

分步流程:

  1. 在SSIS包中,创建3个变量显示在屏幕截图# 1 中。范围CheckFile表示包名称。变量Folder将表示您要检查文件的文件夹。 Filename表示要检查的文件名。变量FilePath将是您需要的全局变量。如果文件存在,它将填入文件路径值,否则它将为空。

  2. 在包的控制流选项卡上,放置Foreach Loop containerScript Task。 Script Task用于展示变量在Foreach循环容器执行完成后保留该值。请参阅屏幕截图# 2

  3. 配置ForEach循环容器,如屏幕截图# 3 和# 4 所示。

  4. 使用cript Task部分下的代码替换S Script task code中的 Main()方法。这是为了演示变量FilePath保留的值。

  5. 屏幕截图# 5 显示路径c:\temp\中不存在任何文件,屏幕截图# 6 显示相应的包执行。

    < / LI>
  6. 屏幕截图# 7 显示文件TestFile.txt存在于路径c:\temp\中,屏幕截图# 8 显示相应的包执行。

  7. 如果您希望在文件存在时对其进行处理,可以在Data Flow Task内放置Foreach Loop container来执行此操作。

  8. 希望有所帮助。

    脚本任务代码:

    C#代码只能在 SSIS 2008 and above ..

    中使用
    public void Main()
            {
                Variables varCollection = null;
    
                Dts.VariableDispenser.LockForRead("User::FilePath");
                Dts.VariableDispenser.GetVariables(ref varCollection);
    
                if (String.IsNullOrEmpty(varCollection["User::FilePath"].Value.ToString()))
                {
                    MessageBox.Show("File doesn't exist.");
                }
                else
                {
                    MessageBox.Show("File " + varCollection["User::FilePath"].Value.ToString() + " exists.");
                }
    
                Dts.TaskResult = (int)ScriptResults.Success;
            }
    

    屏幕截图#1:

    1

    屏幕截图#2:

    2

    屏幕截图#3:

    3

    屏幕截图#4:

    4

    屏幕截图#5:

    5

    屏幕截图#6:

    6

    屏幕截图#7:

    7

    屏幕截图#8:

    8

相关问题