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

SSIS派生列:从单列提取数值填充至两列的技术问题

解决SSIS中提取Mbc/abc对应纯数值的问题

嘿,我来帮你搞定这个字符串提取的麻烦!你之前的表达式问题出在两个地方:一是固定长度截取会把后面的非数字字符带进来,二是只能提取第一个匹配项,没法收集所有数值,也没处理无匹配的空值场景。下面给你两种靠谱的解决方案,优先推荐脚本组件,因为它能完美应对你的需求:

方案一:用Script Component(C#)—— 最灵活可靠的选择

这个方式能精准提取所有Mbc/abc后面的纯数值,自动拼接成你要的格式,还能处理无匹配时的Null填充,特别适合你数千条记录的场景:

  1. 在Data Flow里拖一个Script Component,选「Transformation」类型
  2. 进入组件编辑后,在「Input Columns」里勾选你的ProductDetails列
  3. 切换到「Inputs and Outputs」,给Output 0添加两个新列:
    • MbcValues,数据类型选DT_WSTR(长度设个足够的,比如50)
    • AbcValues,同样选DT_WSTR
  4. 点击「Edit Script」,把默认代码替换成以下C#代码:
using System;
using System.Text.RegularExpressions;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    // 预编译正则,匹配"Mbc "或"abc "后面的纯数值(支持整数、小数)
    private readonly Regex _mbcRegex = new Regex(@"Mbc\s+(\d+\.?\d*)", RegexOptions.Compiled);
    private readonly Regex _abcRegex = new Regex(@"abc\s+(\d+\.?\d*)", RegexOptions.Compiled);

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        // 处理空输入的情况
        if (Row.ProductDetails_IsNull || string.IsNullOrWhiteSpace(Row.ProductDetails))
        {
            Row.MbcValues_IsNull = true;
            Row.AbcValues_IsNull = true;
            return;
        }

        // 提取所有Mbc对应的数值,用空格拼接
        var mbcMatches = _mbcRegex.Matches(Row.ProductDetails);
        if (mbcMatches.Count == 0)
        {
            Row.MbcValues_IsNull = true;
        }
        else
        {
            string mbcResult = string.Join(" ", mbcMatches.Cast<Match>().Select(m => m.Groups[1].Value));
            Row.MbcValues = mbcResult;
        }

        // 提取所有abc对应的数值,用空格拼接
        var abcMatches = _abcRegex.Matches(Row.ProductDetails);
        if (abcMatches.Count == 0)
        {
            Row.AbcValues_IsNull = true;
        }
        else
        {
            string abcResult = string.Join(" ", abcMatches.Cast<Match>().Select(m => m.Groups[1].Value));
            Row.AbcValues = abcResult;
        }
    }
}

为啥这个方案好用?

  • 正则表达式精准定位关键词后的纯数值,不会把后面的字母带进来
  • 自动收集所有匹配项,用空格拼成你要的格式(比如6.5 1 2.5)
  • 空输入或者无匹配时,自动把输出列设为Null
  • 预编译正则,处理数千条记录也不会慢

方案二:纯SSIS表达式(适合不想用脚本的场景)

如果你坚持用表达式,那得结合TOKEN、FINDSTRING这些函数,但要注意这个方式只能处理固定数量的匹配项(比如你预估最多3个Mbc),扩展性差一些。举个提取Mbc列的例子:

-- 先判断有没有Mbc,没有的话返回Null
ISNULL(FINDSTRING(ProductDetails, "Mbc", 1)) ? NULL(DT_WSTR,50) : 
-- 提取第一个Mbc后的数值
SUBSTRING(ProductDetails, FINDSTRING(ProductDetails, "Mbc", 1)+4, 
    FINDSTRING(SUBSTRING(ProductDetails, FINDSTRING(ProductDetails, "Mbc", 1)+4, 100), " ", 1)-1) + 
-- 有第二个Mbc就追加
(TOKENCOUNT(ProductDetails, "Mbc") >1 ? " " + SUBSTRING(ProductDetails, FINDSTRING(ProductDetails, "Mbc", 2)+4, 
    FINDSTRING(SUBSTRING(ProductDetails, FINDSTRING(ProductDetails, "Mbc", 2)+4, 100), " ", 1)-1) : "") + 
-- 有第三个Mbc就追加
(TOKENCOUNT(ProductDetails, "Mbc") >2 ? " " + SUBSTRING(ProductDetails, FINDSTRING(ProductDetails, "Mbc", 3)+4, 
    FINDSTRING(SUBSTRING(ProductDetails, FINDSTRING(ProductDetails, "Mbc", 3)+4, 100), " ", 1)-1) : "")

abc列的表达式只要把所有Mbc换成abc就行。但这种方式要提前知道最多有多少个匹配,不然会漏,而且处理复杂字符串容易出问题,所以还是优先用脚本组件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:18:47