问题陈述
如何动态识别文件名?
您将需要一些机制来检查文件夹的内容并查看存在的内容。具体来说,您正在“加载”目录中查找 Excel 文件。你知道文件扩展名,就是这样。
决议 A
使用 ForEach 文件枚举器。
使用FileSpec 或*.xls 或*.xlsx 上的表达式配置枚举器,具体取决于您处理的Excel 类型。
在Directory 上添加另一个表达式作为您的加载目录。
我通常创建名为 FolderInput 和 FileMask 的 SSIS 变量并在枚举器中分配它们。
现在,当您运行您的包时,枚举器将在 Diretory 中查找所有与 FileSpec 匹配的文件。
某事需要对找到的内容进行处理。您需要使用 Enumerator 返回的文件名。这是通过变量映射选项卡完成的。我创建了名为 CurrentFileName 的第三个变量,并将枚举器的结果分配给它。
如果您在 ForEach 枚举器中放置一个脚本任务,您应该能够看到 @[User::CurrentFileName] 在“Locals”窗口中的值已从 whatever 到“真实”文件名。
决议 B
使用脚本任务。
您仍然需要创建一个变量来保存当前文件名,并且同时提供 FolderInput 和 FileMask 变量可能不会有什么坏处。将前者设置为 ReadWrite,将后者设置为 ReadOnly 变量。
选择您选择的 .NET 语言。我正在使用 C#。方法System.IO.Directory.EnumerateFiles
using System;
using System.Data;
using System.IO;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
namespace ST_fe2ea536a97842b1a760b271f190721e
{
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
public void Main()
{
string folderInput = Dts.Variables["User::FolderInput"].Value.ToString();
string fileMask = Dts.Variables["User::FileMask"].Value.ToString();
try
{
var files = Directory.EnumerateFiles(folderInput, fileMask, SearchOption.AllDirectories);
foreach (string currentFile in files)
{
Dts.Variables["User::CurrentFileName"].Value = currentFile;
break;
}
}
catch (Exception e)
{
Dts.Events.FireError(0, "Script overkill", e.ToString(), string.Empty, 0);
}
Dts.TaskResult = (int)ScriptResults.Success;
}
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
}
}
决策树
鉴于上述问题的两种解决方案,您如何选择?通常,人们会说“它取决于”,但它将取决于的唯一可能时间是在多个文件确实存在的情况下进程是否应该停止/出错加载文件夹。这就是 ForEach 枚举器比脚本任务更麻烦的情况。否则,正如我在最初的回复中所说,这会增加您的项目的开发、测试和维护成本,而没有明显的收益。
零碎物品
进一步解决问题中的细微差别:配置 Excel - 您需要更具体地说明什么不起作用。 Siva 的 SO 答案和链接的 blogspot 文章都展示了如何使用我调用的变量的值 CurrentFileName 来确保 Excel 文件指向“正确”文件。
您需要将连接管理器和数据流的 DelayValidation 设置为 True,因为当包开始执行时,变量的设计时值将无效。请参阅此answer for a longer explanation,但 Siva 在他们的 SO 回答中再次指出了这一点。