共享驱动器批量导入Excel时,如何跳过锁定文件或只读打开?
处理SSIS批量导入Excel时锁定文件的解决方案
方案1:跳过锁定文件,继续处理后续文件(无脚本实现)
- 配置For Each Loop容器错误处理
- 右键点击For Each Loop容器,选择编辑,切换到「选项」标签页
- 将「最大错误计数」设为大于待处理文件总数的数值(比如1000)
- 勾选「失败时继续」选项
- 配置数据流任务错误属性
- 右键点击数据流任务,选择属性
- 在属性窗口将
FailPackageOnFailure和FailParentOnFailure均设置为False
- 可选:记录错误文件
- 切换到「Event Handlers」标签页,为数据流任务添加OnError事件处理
- 添加执行SQL任务,将当前文件名变量
@[User::CurrentFileName]插入到自定义日志表中,方便后续排查重导
方案2:以只读模式打开Excel文件
无脚本实现:修改连接字符串
- 打开Excel连接管理器的属性面板,找到
ConnectionString属性 - 在连接字符串的
Extended Properties部分添加ReadOnly=1参数:// 针对.xlsx文件的示例连接字符串 Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\共享路径\文件.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;ReadOnly=1";// 针对.xls文件的示例连接字符串 Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\共享路径\文件.xls;Extended Properties="Excel 8.0;HDR=YES;ReadOnly=1";
脚本辅助实现(只读参数失效时备选)
- 在For Each Loop容器内、数据流任务前添加脚本任务
- 设置脚本任务的只读变量为
@[User::CurrentFileName],可写变量为@[User::IsFileLocked](需提前创建布尔型全局变量) - 编辑脚本(选择C#),插入以下带注释的代码:
using System; using System.IO; using Microsoft.SqlServer.Dts.Runtime; public class ScriptMain { public void Main() { // 从SSIS变量获取当前待处理的文件路径 string targetFile = Dts.Variables["User::CurrentFileName"].Value.ToString(); bool fileLocked = false; try { // 尝试以独占读写模式打开文件,失败则说明文件被锁定 using (FileStream stream = File.Open(targetFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { // 打开成功则直接关闭流,无后续操作 stream.Close(); } } catch (IOException) { // 捕获IO异常,标记文件为锁定状态 fileLocked = true; } // 将判断结果赋值给SSIS变量,供后续流程使用 Dts.Variables["User::IsFileLocked"].Value = fileLocked; // 标记脚本任务执行成功 Dts.TaskResult = (int)ScriptResults.Success; } // 定义脚本执行结果枚举,匹配SSIS内置状态 enum ScriptResults { Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success, Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure }; } - 为数据流任务添加优先约束,设置条件为
@[User::IsFileLocked] == False,仅当文件未被锁定时才执行导入
内容的提问来源于stack exchange,提问作者Henrov
相关产品推荐
相关产品推荐

