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

SSIS移动文件时为文件名添加日期报错求助

解决SSIS中移动并重命名CSV文件时的SUBSTRING长度错误问题

错误原因分析

你遇到的The length -1 is not valid for Function SUBSTRING错误,本质是当文件名中没有.(比如无扩展名的文件)时,FINDSTRING(@[User::ProcessedFileName],".",1)会返回0,此时FINDSTRING(...) -1就变成了-1,而SUBSTRING的长度参数要求必须是非负数,所以触发了这个报错。


方案一:修复原表达式,兼容无扩展名的情况

可以通过添加判断逻辑,确保当找不到.时,SUBSTRING的长度参数合法。修改后的表达式如下:

@[User::ArchiveFilePath] 
+ SUBSTRING(
    @[User::ProcessedFileName],
    1,
    CASE WHEN FINDSTRING(@[User::ProcessedFileName],".",1) > 0 THEN FINDSTRING(@[User::ProcessedFileName],".",1) - 1 ELSE LEN(@[User::ProcessedFileName]) END
) 
+ "-" 
+ (DT_STR, 2, 1252)RIGHT("0" + (DT_STR, 2, 1252)Month(@[System::StartTime]),2) 
+ (DT_STR, 4, 1252)Year(@[System::StartTime]) 
+ CASE WHEN FINDSTRING(@[User::ProcessedFileName],".",1) > 0 THEN SUBSTRING(
    @[User::ProcessedFileName],
    FINDSTRING(@[User::ProcessedFileName],".",1),
    LEN(@[User::ProcessedFileName])
) ELSE "" END

这里做了两处关键优化:

  • 用CASE判断是否找到.,如果没找到,就取整个文件名作为前缀部分
  • 月份部分添加了RIGHT("0" + ...,2),确保单月份(比如1月)会显示为01,保持格式统一

方案二:使用TOKEN函数简化逻辑(更推荐)

SSIS的TOKEN函数可以按指定分隔符拆分字符串,比嵌套FINDSTRING+SUBSTRING更直观,也不容易出错。表达式如下:

@[User::ArchiveFilePath]
+ TOKEN(@[User::ProcessedFileName], ".", 1)
+ "-"
+ (DT_STR, 2, 1252)RIGHT("0" + (DT_STR, 2, 1252)Month(@[System::StartTime]),2)
+ (DT_STR, 4, 1252)Year(@[System::StartTime])
+ IIF(TOKENCOUNT(@[User::ProcessedFileName], ".") > 1, "." + TOKEN(@[User::ProcessedFileName], ".", TOKENCOUNT(@[User::ProcessedFileName], ".")), "")

解释:

  • TOKEN(@[User::ProcessedFileName], ".", 1):获取.之前的文件名部分
  • TOKENCOUNT(@[User::ProcessedFileName], "."):统计文件名中.的数量,判断是否有扩展名
  • 如果有扩展名,就拼接.和最后一个分隔后的部分(避免文件名中有多个.的情况,比如file.v2.csv会保留.csv)

方案三:用脚本任务实现(最灵活)

如果你的命名规则后续可能有更复杂的变化,用C#/VB脚本任务会更灵活,也更容易调试。示例C#代码如下:

string processedFileName = Dts.Variables["User::ProcessedFileName"].Value.ToString();
string archivePath = Dts.Variables["User::ArchiveFilePath"].Value.ToString();
DateTime startTime = (DateTime)Dts.Variables["System::StartTime"].Value;

// 拆分文件名和扩展名
string fileNameWithoutExt = Path.GetFileNameWithoutExtension(processedFileName);
string fileExt = Path.GetExtension(processedFileName);

// 拼接新文件名
string newFileName = $"{fileNameWithoutExt}-{startTime:MMyyyy}{fileExt}";
string fullArchivePath = Path.Combine(archivePath, newFileName);

// 赋值给变量
Dts.Variables["User::ArchiveFilePathandName"].Value = fullArchivePath;

Dts.TaskResult = (int)ScriptResults.Success;

这种方式的优势是:

  • 利用.NET的Path类,自动处理各种边界情况(比如无扩展名、多个.、路径分隔符差异)
  • 代码可读性更高,调试起来更方便
  • 后续修改命名规则只需调整字符串拼接逻辑即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:28:05