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

如何解析SQL Server表单元格中存储的INI格式长文本?

用T-SQL解析INI文本为结构化表

要实现将SQL Server表中存储的INI格式文本拆分为Block, Key, Value的结构化数据,可借助以下T-SQL核心特性:

  • STRING_SPLIT():将多行INI文本按换行符拆分为单独行
  • 递归CTE:跟踪当前遍历到的INI块(Block)名称
  • 字符串处理函数(CHARINDEX()、SUBSTRING()、TRIM()、LEFT()、RIGHT()):提取块名、键名和对应值
  • CROSS APPLY:关联原表和拆分后的行数据

具体实现步骤与代码

假设你的原表名为INI_Source,结构为id INT, rawINI NVARCHAR(MAX),以下是完整实现代码:

  1. 先将rawINI按换行符拆分为单行记录,同时保留原表的id用于关联:
-- 临时存储拆分后的每一行INI内容
DROP TABLE IF EXISTS #SplitLines;
SELECT 
    s.id,
    LTRIM(RTRIM(value)) AS LineContent,
    -- 生成行号,保证INI内容的顺序
    ROW_NUMBER() OVER(PARTITION BY s.id ORDER BY (SELECT NULL)) AS LineNum
INTO #SplitLines
FROM INI_Source s
CROSS APPLY STRING_SPLIT(s.rawINI, CHAR(13)+CHAR(10)) -- 按Windows换行符拆分
WHERE LTRIM(RTRIM(value)) <> ''; -- 过滤空行
  1. 用递归CTE遍历每行,跟踪当前Block并提取Key-Value:
WITH INIParser AS (
    -- 锚点成员:初始化第一行的Block(如果第一行是Block)
    SELECT 
        id,
        LineNum,
        -- 提取Block名称:去掉前后的[]
        CASE 
            WHEN LineContent LIKE '[%]' THEN TRIM('[]' FROM LineContent)
            ELSE NULL 
        END AS CurrentBlock,
        -- 非Block行的Key和Value
        CASE 
            WHEN LineContent NOT LIKE '[%]' AND CHARINDEX('=', LineContent) > 0 
            THEN LEFT(LineContent, CHARINDEX('=', LineContent)-1)
            ELSE NULL 
        END AS KeyName,
        CASE 
            WHEN LineContent NOT LIKE '[%]' AND CHARINDEX('=', LineContent) > 0 
            THEN SUBSTRING(LineContent, CHARINDEX('=', LineContent)+1, LEN(LineContent))
            ELSE NULL 
        END AS KeyValue
    FROM #SplitLines
    WHERE LineNum = 1

    UNION ALL

    -- 递归成员:逐行处理,继承上一行的Block(如果当前行不是新Block)
    SELECT 
        sl.id,
        sl.LineNum,
        CASE 
            WHEN sl.LineContent LIKE '[%]' THEN TRIM('[]' FROM sl.LineContent)
            ELSE ip.CurrentBlock 
        END AS CurrentBlock,
        CASE 
            WHEN sl.LineContent NOT LIKE '[%]' AND CHARINDEX('=', sl.LineContent) > 0 
            THEN LEFT(sl.LineContent, CHARINDEX('=', sl.LineContent)-1)
            ELSE NULL 
        END AS KeyName,
        CASE 
            WHEN sl.LineContent NOT LIKE '[%]' AND CHARINDEX('=', sl.LineContent) > 0 
            THEN SUBSTRING(sl.LineContent, CHARINDEX('=', sl.LineContent)+1, LEN(sl.LineContent))
            ELSE NULL 
        END AS KeyValue
    FROM #SplitLines sl
    JOIN INIParser ip ON sl.id = ip.id AND sl.LineNum = ip.LineNum + 1
)
-- 最终筛选出Key-Value行,整理为目标结构
SELECT 
    CurrentBlock AS Block,
    KeyName AS [Key],
    KeyValue AS Value
FROM INIParser
WHERE KeyName IS NOT NULL -- 只保留Key-Value行,过滤Block行
ORDER BY id, LineNum;

关键细节说明

  • 过滤空行:避免处理INI文本中的无效空行
  • 行号排序:保证INI内容的顺序和原文本一致,避免Block和Key对应错误
  • 边界处理:兼容Key3=这类无值的键,此时Value字段为NULL
  • Block继承:递归CTE会自动将后续的Key-Value行关联到最近的Block

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:33:09