在数据库中将字符串拆分成表单(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;
相关推荐
今天_也很困6 分钟前
LeetCode热题100-560. 和为 K 的子数组
java·算法·leetcode
在繁华处20 分钟前
线程进阶: 无人机自动防空平台开发教程V2
java·无人机
A懿轩A25 分钟前
【Java 基础编程】Java 变量与八大基本数据类型详解:从声明到类型转换,零基础也能看懂
java·开发语言·python
m0_7400437327 分钟前
【无标题】
java·spring boot·spring·spring cloud·微服务
Tansmjs41 分钟前
使用Python自动收发邮件
jvm·数据库·python
m0_5613596743 分钟前
用Python监控系统日志并发送警报
jvm·数据库·python
@ chen1 小时前
Spring事务 核心知识
java·后端·spring
Dxy12393102161 小时前
MySQL INSERT ... ON DUPLICATE KEY UPDATE 与非主键唯一字段
数据库·mysql
aithinker1 小时前
使用QQ邮箱收发邮件遇到的坑 有些WIFI不支持ipv6
java
星火开发设计1 小时前
C++ 预处理指令:#include、#define 与条件编译
java·开发语言·c++·学习·算法·知识