SQL查询中如何定位字符串最后一个点、左移8位提取文档名年份
适配可变文件扩展名的文档名年份提取实现
核心优化逻辑
原有代码采用固定长度偏移提取年份的方案,默认假设文件扩展名固定为3个字符,当扩展名长度变化时(如.docx)会出现位置偏移。优化方案通过逆向定位文档名中最后一个点的位置,消除扩展名长度对提取位置的影响,完全匹配提出的定位规则。
关键函数说明
OleDb连接Access/Jet数据库时,可直接使用引擎原生支持的InStrRev函数实现反向字符定位:
- 函数作用:从字符串末尾开始检索指定字符的出现位置,返回该字符在字符串中的索引值
- 基础写法:
InStrRev([Document Name], ".")- 对任意命名结构的文档名,返回的都是最后一个点的位置,和扩展名长度无关
提取规则计算
按照预设的定位逻辑,基于最后一个点的位置计算年份提取的起始索引:
- 最后一个点的位置固定在8位日期段(格式为YYYYMMDD)和文件扩展名之间
- 从最后一个点的位置向左偏移8个字符,即为8位日期段的起始位置
- 从该起始位置取4个字符,即为需要的四位年份值
- 计算式:
InStrRev([Document Name], ".") - 8即为年份提取的起始索引
- 计算式:
替换后的完整运行代码
Dim sSQL = "SELECT Mid([Document Name], InStrRev([Document Name], '.') - 8, 4) As [Year], Count([Year]) As [Totals] FROM Archief Group By Mid([Document Name], InStrRev([Document Name], '.') - 8, 4) Order By Mid([Document Name], InStrRev([Document Name], '.') - 8, 4) DESC ;" Dim dt As New DataTable Using cmd As New OleDb.OleDbCommand(sSQL, con3) Using reader = cmd.ExecuteReader dt.Load(reader) End Using End Using
兼容性验证
- 对3位扩展名文档名
MYDOCUMENT.NAME.20210317.DOC:计算得到最后一个点位置为25,起始索引为25-8=17,提取结果为"2021",和原逻辑的正确输出完全一致 - 对4位扩展名文档名
MYDOCUMENT.NAME.20210317.DOCX:最后一个点的位置仍为25,提取结果同样为"2021",消除了固定偏移带来的计算偏差
注意事项
- 逻辑生效的前提是文档命名严格遵循「自定义前缀.YYYYMMDD格式8位日期.扩展名」的结构,确保最后一个点紧邻日期段的右侧
- 该方案可兼容任意长度的文件扩展名,无需根据扩展名长度调整硬编码的偏移值
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

