在数据库中将字符串拆分成表单(SQL和HANA版本)

SQL Server版本

复制代码
CREATE FUNCTION [dbo].[IPS_SplitToTable]
(
    @InputString NVARCHAR(MAX),
    @RowSplit CHAR(1)=';',  --拆分行的标识符
    @ColSplit CHAR(1)=','   --拆分列的标识符
)
RETURNS @ResultTable TABLE 
(
    LineNum INT,
    Value1 NVARCHAR(MAX),
    Value2 NVARCHAR(MAX)
)
AS
BEGIN
    -- 临时表存储按分号拆分的行
    DECLARE @Rows TABLE (RowNumber INT IDENTITY(1,1), RowData NVARCHAR(MAX));
    
    -- 按分号拆分字符串得到行
    INSERT INTO @Rows (RowData)
    SELECT value 
    FROM STRING_SPLIT(@InputString, @RowSplit)
    WHERE value <> ''; -- 排除空行
    
    -- 声明变量
    DECLARE @TotalRows INT = (SELECT COUNT(*) FROM @Rows);
    DECLARE @CurrentRow INT = 1;
    DECLARE @RowData NVARCHAR(MAX);
    DECLARE @Pos INT;
    
    -- 使用循环处理每一行
    WHILE @CurrentRow <= @TotalRows
    BEGIN
        -- 获取当前行数据
        SELECT @RowData = RowData 
        FROM @Rows 
        WHERE RowNumber = @CurrentRow;
        
        -- 查找逗号位置
        SET @Pos = CHARINDEX(@ColSplit, @RowData);
        
        -- 插入结果表
        INSERT INTO @ResultTable (LineNum, Value1, Value2)
        VALUES (
            @CurrentRow,
            -- 第一列:从开头到第一个逗号
            CASE WHEN @Pos > 0 THEN SUBSTRING(@RowData, 1, @Pos - 1) ELSE @RowData END,
            -- 第二列:从第一个逗号后到结尾
            CASE WHEN @Pos > 0 THEN SUBSTRING(@RowData, @Pos + 1, LEN(@RowData) - @Pos) ELSE NULL END
        );
        
        -- 移动到下一行
        SET @CurrentRow = @CurrentRow + 1;
    END
    
    RETURN;
END

HANA版本

复制代码
CREATE FUNCTION "IPS_SplitToTable"
(
  InputStr NVARCHAR(100000),
  Split CHAR(1) DEFAULT ',',      --拆分行,默认以逗号分开 
  ColSplit CHAR(1) DEFAULT NULL    --拆分列,默认以横线分开
)
RETURNS TABLE("Val1" NVARCHAR(500),"Val2" NVARCHAR(500))
AS
BEGIN

  DECLARE InputStr2 NVARCHAR(100000);  
  
  InputStr2=:InputStr||',';

  --构建临时表结构
  TMP_DATA=SELECT :InputStr2 AS "Value" FROM DUMMY WHERE 1=2;
  
  WHILE LOCATE(:InputStr2,:Split) <> 0 DO
    IF SUBSTRING(:InputStr2,1,LOCATE(:InputStr2,:Split)-1) <> '' THEN
      TMP_DATA=
        SELECT "Value" FROM :TMP_DATA
        UNION ALL
        SELECT SUBSTRING(:InputStr2,0,LOCATE(InputStr2,:Split)-1) AS "Value" FROM DUMMY;
    END IF;
    InputStr2 := SUBSTRING(:InputStr2,LOCATE(:InputStr2,:Split)+1,LENGTH(:InputStr2)-LOCATE(:InputStr2,:Split));
  END WHILE;  
  
  IF ColSplit IS NULL THEN
    RETURN SELECT CAST("Value" AS NVARCHAR(500)) AS "Val1",CAST(NULL AS NVARCHAR(500)) AS "Val2" FROM :TMP_DATA;
  ELSE
    RETURN SELECT CAST(CASE WHEN LOCATE("Value",:ColSplit)=0 THEN "Value" ELSE SUBSTR_BEFORE("Value",:ColSplit) END AS NVARCHAR(500)) AS "Val1",
                  CAST(SUBSTR_AFTER("Value",:ColSplit) AS NVARCHAR(500)) AS "Val2" 
           FROM :TMP_DATA; 
  END IF;
END;
相关推荐
独泪了无痕5 小时前
探索Pinyin4j-Java中的拼音转换利器
java·后端
道尔柯南6 小时前
C++ string 类详解:从常用接口到深拷贝,彻底掌握字符串处理
android·java·c++
Nturmoils6 小时前
集中式与分布式怎么选:从订单读写看 KingbaseES 的架构边界
数据库
xiaomuzuirenzhen7 小时前
大专电子商务从事电商运营分析师需要考证吗?
大数据·数据库
kingx37 小时前
Bugku 3122 谷歌小恐龙题解:纯离线逆向 Vault 的 AES-GCM 加密资源(附 Python 解密器)
java·逆向·ctf·bugku·aes-gcm
翔云1234569 小时前
RocksDB中,客户端每写入一次数据,需要访问几次磁盘
运维·数据库·mysql
DevOpenClub9 小时前
职教高考控制线 API:招生类别枚举、筛选与空分数含义
java·数据库·高考
露天赏雪10 小时前
第3篇:Sentinel熔断降级实战:大模型接口抖动时的服务兜底方案
java·开发语言·人工智能·spring boot·spring·servlet·sentinel
天天被压力10 小时前
【A股分钟级高频数据完全手册 #06】北交所分钟级数据接口:京市股票Pro版最新分时
java·人工智能·python
GeW10 小时前
新质生产力路线图解读:数据库性能优化与Linux调优专场
linux·数据库