GBase 8s에서 split_part 함수 구현: 두 가지 실용적인 접근법
Source: Dev.to
split_part 은 무엇을 하나요?
split_part 함수는 구분자를 기준으로 문자열을 나누고 n번째 필드를 반환합니다.
예시
split_part('aa,bb,cc,dd', ',', 3) → 'cc'
방법 1: 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;
장점
- 로직이 단순하고 내장 함수를 사용하므로 읽기 쉽습니다.
방법 2: 순수 문자 파싱
이 버전은 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 환경에서 바로 사용할 수 있습니다.