达梦数据库(DM Database) 里,并没有像 SPLIT 这样的内置函数(类似 MySQLSUBSTRING_INDEX 或 Oracle 的 REGEXP_SUBSTR)可以直接把字符串拆分成数组或多行。

但是你可以通过以下几种方式来实现 字符串分割 的效果:

1. 利用 INSTR + SUBSTR

手动查找分隔符位置,截取子串。例如:

-- 假设要按逗号分割
SELECT SUBSTR('A,B,C', 1, INSTR('A,B,C', ',') - 1) AS part1,
       SUBSTR('A,B,C', INSTR('A,B,C', ',') + 1, LENGTH('A,B,C')) AS part2
FROM dual;

这种方法适合已知分隔数量的场景。

2. 使用递归 CTE 模拟 Split

可以把一个字符串递归拆成多行:

WITH RECURSIVE split_cte AS (
    SELECT SUBSTR('A,B,C,D', 1, INSTR('A,B,C,D', ',') - 1) AS val,
           SUBSTR('A,B,C,D', INSTR('A,B,C,D', ',') + 1) AS rest
    FROM dual
    UNION ALL
    SELECT CASE WHEN INSTR(rest, ',') > 0
                THEN SUBSTR(rest, 1, INSTR(rest, ',') - 1)
                ELSE rest END,
           CASE WHEN INSTR(rest, ',') > 0
                THEN SUBSTR(rest, INSTR(rest, ',') + 1)
                ELSE '' END
    FROM split_cte
    WHERE rest <> ''
)
SELECT val FROM split_cte;

结果:

A
B
C
D

3. 自定义函数(推荐)

你可以用 PL/SQL过程语言(达梦兼容 Oracle PL/SQL) 写一个 Split 函数,返回表类型。

例如:

CREATE OR REPLACE FUNCTION fn_split(str VARCHAR2, delimiter VARCHAR2)
RETURN SYS.ODCIVARCHAR2LIST PIPELINED
AS
    pos INT := 1;
    idx INT;
    tmp VARCHAR2(4000);
BEGIN
    LOOP
        idx := INSTR(str, delimiter, pos);
        IF idx > 0 THEN
            tmp := SUBSTR(str, pos, idx - pos);
            PIPE ROW(tmp);
            pos := idx + LENGTH(delimiter);
        ELSE
            tmp := SUBSTR(str, pos);
            PIPE ROW(tmp);
            EXIT;
        END IF;
    END LOOP;
    RETURN;
END;

然后使用:

SELECT * FROM TABLE(fn_split('A,B,C,D', ','));

✅ 总结:

  • 达梦数据库没有现成的 SPLIT 函数。
  • 你可以用 INSTR+SUBSTR递归CTE自定义函数 实现类似功能。