在 GBase 8s 中实现 split_part 函数:两种实用方法

发布: (2026年3月30日 GMT+8 23:41)
3 分钟阅读
原文: Dev.to

Source: Dev.to

split_part 是什么?

split_part 函数按照分隔符拆分字符串,并返回第 n 个字段。

示例

split_part('aa,bb,cc,dd', ',', 3) → 'cc'

方法一:使用 SUBSTRING_INDEX

GBase 8s 提供 SUBSTRING_INDEX,它可以在指定出现次数之前提取子串。这使得实现非常直接。

-- drop if exists
DROP FUNCTION IF EXISTS split_part2;

CREATE FUNCTION split_part2(
    str_in LVARCHAR(2048),
    separator_in CHAR(1),
    field_in INT
) RETURNING VARCHAR(255);

    DEFINE str_len INT;
    DEFINE pos_curr INT;
    DEFINE count_field INT;
    DEFINE pos_char CHAR(1);

    IF field_in  count_field THEN
        RETURN NULL;
    ELSE
        -- Take the first `field_in` segments, then the last one
        RETURN SUBSTRING_INDEX(
            SUBSTRING_INDEX(str_in, separator_in, field_in),
            separator_in,
            -1
        );
    END IF;

END FUNCTION;

优点

  • 逻辑简单,使用内置函数,易于阅读。

方法二:纯字符解析

该实现不依赖 SUBSTRING_INDEX——手动扫描字符串以定位目标字段。

DROP FUNCTION IF EXISTS split_part;

CREATE FUNCTION split_part(
    str_in LVARCHAR(2048),
    separator_in CHAR(1),
    field_in INT
) RETURNING VARCHAR(255);

    DEFINE res VARCHAR(255);
    DEFINE str_len INT;
    DEFINE pos_curr INT;
    DEFINE substr_start INT;
    DEFINE substr_length INT;
    DEFINE pos_char CHAR(1);

    IF field_in <= 0 THEN RETURN ''; END IF;

    LET res = '';
    LET substr_start = 0;
    LET substr_length = 0;
    LET str_len = LENGTH(str_in);

    FOR pos_curr = 1 TO str_len
        LET pos_char = SUBSTR(str_in, pos_curr, 1);
        IF pos_char = separator_in THEN
            LET field_in = field_in - 1;
        END IF;

        -- Locate start of the target field
        IF field_in = 1 AND substr_start = 0 THEN
            LET substr_start = pos_curr + DECODE(pos_char, separator_in, 1, 0);
        END IF;

        -- Locate end of the target field
        IF field_in <= 0 THEN
            LET substr_length = pos_curr;
            EXIT FOR;
        END IF;
    END FOR;

    -- Handle edge cases (field is the last one or string ends)
    IF substr_length = 0 THEN
        LET substr_length = str_len + 1;
    END IF;
    IF substr_start = 0 THEN
        LET substr_start = str_len + 1;
    END IF;
    IF substr_length < substr_start THEN
        LET substr_length = 0;
    ELSE
        LET substr_length = substr_length - substr_start;
    END IF;

    RETURN NVL(SUBSTRING(str_in FROM substr_start FOR substr_length), '');

END FUNCTION;

优点

  • 不依赖 SUBSTRING_INDEX;完全可移植的逻辑。

示例用法

取字符串 'aa,bb,cc,dd' 并获取第三个字段:

SELECT split_part2('aa,bb,cc,dd', ',', 3) FROM dual;
SELECT split_part('aa,bb,cc,dd', ',', 3) FROM dual;

两条查询均返回:

cc

小结

  • GBase 8s 没有原生的 split_part,但上述两种实现弥补了这一缺失。
  • 方法 1 更短更简洁——适用于大多数场景。
  • 方法 2 则不依赖任何特定的内置函数,具有更好的独立性。
  • 两个函数均已测试,可直接在你的 GBase 8s 环境中使用。
0 浏览
Back to Blog

相关文章

阅读更多 »

修改表

1. 将 customers 表的 email 列设为 NOT NULL:ALTER TABLE customers ALTER COLUMN email SET NOT NULL; 2. 确保 users 表的 username 唯一:ALTER TABLE …

CA 40 – 修改表

在 customers 表中将 email 设置为 NOT NULL,SQL:ALTER TABLE customers ALTER COLUMN email SET NOT NULL;确保以后插入的行必须包含 email 值。Make usern...

ALTER 查询

在本次作业中,我使用 ALTER TABLE 对现有表进行修改。这帮助我了解了如何在不重新创建表的情况下更新约束。任务……