You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSIS脚本任务处理目录时触发调用目标运行时异常求助

SSIS脚本任务遍历目录写入SQL报错问题解决方案

报错核心原因

  • 逻辑顺序错误:代码先执行Directory.GetFiles(DirPath, "*"),后判断目录是否存在。如果目标目录不存在,第一步就会抛出异常,根本走不到后面的判断分支,且该行代码无实际使用,属于冗余逻辑。
  • SQL拼接语法错误:直接拼接文件路径、名称到SQL语句中,如果文件名/路径包含单引号(例如员工'报销表.xlsx),会直接导致SQL语法错误,触发执行异常。
  • 权限不足:遍历第5个目录时,可能遇到当前SSIS运行账号无读取权限的子文件夹/文件,触发权限异常直接中断任务。
  • 路径过长:Windows默认限制路径长度不超过260字符,如果目录下有超长路径的文件/文件夹,.NET Framework默认会抛出路径无效异常。
  • 逻辑缺陷:现有代码仅遍历子目录下的文件,根目录下的文件不会被写入SQL表。

修复后代码

public void Main()
{
    SqlConnection myADONETConnection = null;
    try
    {
        // 初始化数据库连接
        myADONETConnection = (SqlConnection)(Dts.Connections["DBConn"].AcquireConnection(Dts.Transaction) as SqlConnection);
        SqlCommand sqlCmd = new SqlCommand();
        sqlCmd.Connection = myADONETConnection;
        // 预定义参数化SQL,避免拼接语法错误和注入风险
        sqlCmd.CommandText = "Insert into dbo.FileInformation_6 Values(@FullName, @FileName, @LastAccessTime, @CreationTime, @FileSize)";

        string DirPath = Dts.Variables["User::VarDirectoryPath"].Value.ToString();

        // 先判断目录是否存在,再执行后续操作
        if (!Directory.Exists(DirPath))
        {
            MessageBox.Show("目录不存在:" + DirPath);
            Dts.TaskResult = (int)ScriptResults.Failure;
            return;
        }

        // 处理根目录下的文件
        string[] rootFiles = Directory.GetFiles(DirPath);
        foreach (string rootFile in rootFiles)
        {
            ProcessFile(rootFile, sqlCmd);
        }

        // 遍历所有子目录
        string[] folders = Directory.GetDirectories(DirPath, "*", SearchOption.AllDirectories);
        foreach (string foldername in folders)
        {
            try
            {
                string[] fnames = Directory.GetFiles(foldername);
                foreach (string filename in fnames)
                {
                    ProcessFile(filename, sqlCmd);
                }
            }
            catch (Exception ex)
            {
                // 跳过无法访问的文件夹,可根据需要改为记录日志
                MessageBox.Show($"跳过无法处理的文件夹 {foldername},错误:{ex.Message}");
                continue;
            }
        }

        Dts.TaskResult = (int)ScriptResults.Success;
    }
    catch (Exception globalEx)
    {
        // 捕获全局异常,方便定位问题
        MessageBox.Show($"任务运行错误:{globalEx.Message}\n堆栈:{globalEx.StackTrace}");
        Dts.TaskResult = (int)ScriptResults.Failure;
    }
    finally
    {
        // 释放数据库连接
        if (myADONETConnection != null)
        {
            Dts.Connections["DBConn"].ReleaseConnection(myADONETConnection);
        }
    }
}

// 抽离文件处理公共方法,避免重复代码
private void ProcessFile(string filePath, SqlCommand sqlCmd)
{
    try
    {
        FileInfo file = new FileInfo(filePath);
        // 清空上一次的参数值
        sqlCmd.Parameters.Clear();
        sqlCmd.Parameters.AddWithValue("@FullName", file.FullName);
        sqlCmd.Parameters.AddWithValue("@FileName", file.Name);
        sqlCmd.Parameters.AddWithValue("@LastAccessTime", file.LastAccessTime);
        sqlCmd.Parameters.AddWithValue("@CreationTime", file.CreationTime);
        sqlCmd.Parameters.AddWithValue("@FileSize", file.Length / 1024);
        sqlCmd.ExecuteNonQuery();
    }
    catch (Exception ex)
    {
        // 跳过无法处理的文件,可根据需要改为记录日志
        MessageBox.Show($"跳过无法处理的文件 {filePath},错误:{ex.Message}");
    }
}

额外优化建议

  • 生产环境建议将MessageBox.Show替换为SSIS日志记录,避免弹窗阻塞任务运行
  • 如果需要支持超长路径,可在项目属性中开启.NET 4.6.2以上版本的长路径支持,同时修改Windows组策略关闭长路径限制
  • 可以批量插入数据代替单条插入,提升大量文件时的执行效率

内容的提问来源于stack exchange,提问作者Dhipthee Pujar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 21:15:05