在数据库中将字符串拆分成表单(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 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
俊昭喜喜里5 天前
java中的继承和多态的区别
java
小羊没烦恼!5 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕5 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码5 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖5 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时5 天前
01-06-A-JVM排查实战详解
java·jvm
这个DBA有点耶5 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
vipxieliang5 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
DBA_G5 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库