【问题标题】:SSIS - Move List of Files from One Folder to AnotherSSIS - 将文件列表从一个文件夹移动到另一个文件夹
【发布时间】:2016-06-07 18:23:58
【问题描述】:

我有一个包含大约 10,000 个 PDF 文档的文件夹 SourceFolder。

我有一个列表 (FileList.csv),其中包含大约 1,000 个文件的名称。

我想将该列表中的文件从它们所在的文件夹移动到我创建的空文件夹 (DestFolder)。我正在使用 SSIS 2013。

作为概念验证,我使用 ForEachItem 枚举器成功配置了 ForEachLoop 容器,其中包含 FileSystem 任务,并移动了 2 个文件。

但是,我必须在 ForEachLoop Editor --> Collection --> Enumerator Configuration 窗口中手动输入文件名。

我为 FileName、SourceFolder 和 FullSourcePath 配置了变量,一切正常。

我的问题是 - 如何连接到平面文件以将文件名放入变量中?

我不允许发布图片,所以我会尝试解释我的尝试。

  1. 添加平面文件源和连接管理器并使用 CM Propoerties 中的表达式将 FileName 变量分配给连接字符串(不走运)

  2. 将 FlatFile 源输入 RecordSet 目标并将结果集分配给 ObjectVariable,并将 ForEach 循环容器配置更改为 ForEach ADO 枚举器,并将 ObjectVariable 分配给 ADO 源对象变量(不走运)。

这似乎是一个如此简单的任务,我希望我遗漏了一些明显的东西。抱歉,不包括图片。

【问题讨论】:

  • #2 应该可以正常工作。您能否提供更多关于发生了什么的详细信息,也许是 SSIS 日志?
  • 错误是“错误:变量“User::ObjectVariable”不包含有效的数据对象”。向我建议数据没有从平面文件源到记录集目标。我在它们之间放置了一个数据查看器——它什么也没显示。我可以看到来自平面文件源编辑器的列和来自连接管理器编辑器的列和数据。

标签: ssis


【解决方案1】:
  1. 创建一个 Object 类型的变量来存储您的文件名。
  2. 在脚本任务中使用文件名填充字符串数组并将其分配给对象。
  3. 在脚本任务和 foreach 容器之间创建优先约束。
  4. 在 foreach 循环容器的集合选项卡中,选择 Foreach From Variable Enumerator 作为枚举器类型。
  5. 在变量映射选项卡中选择将在枚举期间存储当前文件名的变量。

【讨论】:

  • 谢谢。根据我使用 SSIS 的 3 个月,您的回答是有道理的;-/。但是作为一个偶然的dba,我没有编写脚本的编码技能。我可以写 T-SQL。是否有使用 SQL 任务填充该变量的解决方法?无论如何,平面文件数据都来自查询...
  • 绝对可以将脚本任务替换为执行sql任务。只需将结果集分配给任务的结果集选项卡中的变量即可。
【解决方案2】:

我终于得到了这个工作,并认为我会将我的解决方案发布给可能面临同样问题的其他人。

我使用带有嵌入式查询的 SQL 任务直接从数据库中获取文件名列表。

我将它输入到一个 ForEachLoop 容器中,里面有一个文件系统任务。

我创建了以下变量:

  • 源文件夹 |字符串 | B:\桌面\源\
  • 目标文件夹 |字符串 | B:\桌面\目的地\
  • 文件名 |字符串 |
  • 文件列表 |对象 |
  • 文件全路径 |字符串 | (Expr:) @[User::SourceFolder]+@[UserFileName]

连接管理器

  • 用于数据库的 OLE DB(显然)
  • 目标文件夹 |使用类型:|现有文件夹 |浏览到文件夹
  • 源文件夹 |使用类型:|现有文件 |指向文件夹中的任何文件
  • 重要提示:在 SourceFolder 连接管理器中,设置以下表达式:
  • 连接字符串 | @[User::FileFullPath]

在SQL 任务编辑器|常规窗口:

  1. 将 ResultSet 设置为 完整结果集
  2. 将查询粘贴到 SQL 语句

在SQL 任务编辑器|结果集窗口:

  1. 结果名称 = 0
  2. 变量名称 = User::FileList

在 ForEach 循环编辑器中 |收藏窗口:

  1. 枚举器 = ForeachADO 枚举器
  2. ADO 对象源变量 = User::FileList
  3. 枚举模式 = 第一个表中的行

在 ForEach 循环编辑器中 |变量映射窗口:

  1. 变量 = 用户::文件名
  2. 索引 = 0

在 ForEach 循环编辑器属性中:

  1. 将最大错误计数设置为大于您正在循环的文件数的某个数字。 (这涵盖了您的查询生成的文件名不在您的源文件夹中的情况。我相信有一种更优雅的方法可以做到这一点,我期待有朝一日学习它!)

在文件系统任务编辑器|常规窗口:

  1. IsDestinationPathVariable = False
  2. DestinationConnection = DestFolder
  3. 操作 = 移动文件
  4. IsSourcePathVariable = 假
  5. SourceConnection = SourceFolder

在文件系统任务属性窗口中:

  1. 设置最大错误计数 > SourceFolder 中的文件数

该包现在将运行并为 FileList 中源文件夹中没有匹配文件的每个文件名生成一个错误,但它会运行并移动文件。

陷阱:

  1. 不要忘记文件路径变量末尾的“\”
  2. 不要忘记在源连接管理器属性窗口中设置表达式(见上文)。

感谢大家的帮助。

【讨论】:

    【解决方案3】:

    更快的方法来完成这个!

    放下 foreach 循环任务。 在集合下选择 Foreach 文件枚举器。 文件夹是文件所在的位置。 c:\SrcFiles 保留完全限定并放入 .txt 或任何文件扩展名 在变量映射下添加名为 FileName 字符串类型的变量并确保它在包的范围内

    将文件系统任务放入容器 源变量是文件名 目的地连接是您要移动到的位置。 d:\ReceivedFiles 覆盖目标 = True DelayValidation = True

    瞧!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-25
      • 1970-01-01
      相关资源
      最近更新 更多