我在网络上有一个包含文件的文件夹,我正在将文件从一个文件夹移动到另一个文件夹。但我只想移动新文件,所以只复制目标文件夹中不存在的文件。如何?我已经有了for each
循环容器和文件系统任务。我正在使用变量。现在,每次执行包时,它都会将所有文件从一个文件夹复制到下一个文件夹。是否有某种条件工具可以插入其中?我不太擅长编写脚本,所以如果这是唯一的解决方案,我可能需要你的帮助。
2 回答
这是一个可能的选项,您可以使用Foreach 循环容器、脚本任务和文件系统任务来实现此目的。以下示例显示了如何做到这一点。该示例是使用 SSIS 2008 R2 创建的。
分步过程:
在路径中创建两个名为Source和Destination
C:\temp\
的文件夹,如屏幕截图 # 1所示。在文件夹路径中放置一个名为Sample_File_01.txt
C:\temp\Source\
的示例文件,并将另一个文件夹C:\temp\Destination\
留空。仅当文件不存在时,SSIS 包才会将文件从源文件夹复制到目标文件夹。请参阅屏幕截图# 2和# 3。在 SSIS 包上,创建 7 个变量,如屏幕截图 # 4所示。将变量DestinationFolder设置为 value
C:\temp\Destination\
。将变量SourceFolder设置为 valueC:\temp\Source\
。将变量FilePattern设置为 value*.*
。您可以根据需要更改这些变量的值。选择变量SourceFilePath并按F4按钮打开
Properties
窗口。将属性EvaluateAsExpression更改为并将属性Expression设置为 value 。参考截图# 5。True
@[User::SourceFolder] + @[User::FileName]
选择变量DestinationFilePath并按F4按钮打开
Properties
窗口。将属性EvaluateAsExpression更改为并将属性Expression设置为 value 。参考截图# 6。True
@[User::DestinationFolder] + @[User::FileName]
在 SSIS 包的Control Flow选项卡上,放置 a
Foreach Loop container
并配置容器的属性,如屏幕截图 # 7和 # 8所示。确保您选择Name and extension
了Collection部分的单选按钮。在 Foreach 循环容器中,放置一个
Script Task
. 双击脚本任务并单击Edit Script
按钮。将脚本任务中的 Main() 方法替换为“脚本任务代码”部分下给出的代码。此代码检查目标文件是否已存在,然后相应地填充布尔变量DoesFileExist。在 Foreach 循环容器中,
File System Task
在脚本任务下方放置一个。将脚本任务的成功绿色箭头连接到文件系统任务。配置文件系统任务,如屏幕截图 # 9所示。仅当目标路径中不存在文件时,我们才需要执行文件系统任务。因此,我们需要更改脚本任务和文件系统任务之间的连接器。右键单击绿色连接器并选择编辑,如屏幕截图 # 10所示。
如屏幕截图 # 11所示配置优先约束。这将检查变量DoesFileExist 是否包含 value
False
,这意味着在目标中找不到文件。配置完成后,SSIS 包应如屏幕截图 # 12所示。
屏幕截图# 13显示了第一个包执行。在此执行期间,目标路径中没有文件
C:\temp\Destination\
。执行后,文件 Sample_File_01.txt 已从复制C:\temp\Source\
到C:\temp\Destination\
. 参考截图# 14。屏幕截图# 15显示了第二个包的执行。在此执行期间,没有文件被复制到目标路径
C:\temp\Destination\
。如您所见,File System Task
由于 Precedence 约束失败,因此未执行。
希望有帮助。
脚本任务代码:
只能在SSIS 2008 and above
.
public void Main()
{
Variables varCollection = null;
Dts.VariableDispenser.LockForRead("User::DestinationFilePath");
Dts.VariableDispenser.LockForWrite("User::DoesFileExist");
Dts.VariableDispenser.GetVariables(ref varCollection);
varCollection["User::DoesFileExist"].Value = Convert.ToBoolean(System.IO.File.Exists(varCollection["User::DestinationFilePath"].Value.ToString()));
Dts.TaskResult = (int)ScriptResults.Success;
}
截图#1:
截图#2:
截图#3:
截图#4:
截图#5:
截图#6:
截图#7:
截图#8:
截图#9:
截图#10:
截图 #11:
截图#12:
截图#13:
截图#14:
截图#15:
这是一个有两个假设的潜在解决方案:
- 目标文件夹中的所有文件都被此包移动。
- 文件名是唯一的。
您可以将文件名记录步骤添加到 ETL。
在数据库中创建一个新的日志表,其中包含文件名列。在包的每个循环中,将文件名写入此表。然后,您可以将其用作简单的查找表,ETL 中的某些条件逻辑使用该查找表来检查正在处理的文件名是否与现有文件匹配。
究竟如何实现日志记录步骤和条件检查(可能是数据流中的条件,在脚本任务中完成等)将取决于您的包的设计,但它应该完成您正在寻找的内容。