1. 변경 대상은 항상 1ROW 인가요?
- 2행 이상 한번에 주어지는 경우는 없는지?
2. 변경 항목의 명칭 및 개수가?
- {이름} {1} {결과} 3개 항목 고정인가요?
- 혹시 명칭이나 개수가 가변인지?
-- 그냥..
with t(m,p) as (
select '{이름}님 {1}번째 결과 {결과}입니다' , '홍길동,2,성공'
from dual
)
SELECT REPLACE(
REPLACE(
REPLACE(M,'{이름}',REGEXP_SUBSTR(P,'[^,]+',1,1))
,'{1}',REGEXP_SUBSTR(P,'[^,]+',1,2))
,'{결과}',REGEXP_SUBSTR(P,'[^,]+',1,3)
) AS TXT
FROM T
문제는 단건을 기준으로 올린겁니다. 다건인 경우엔 아직 저도 생각을 안해봤숩니다. 한번 고민해봐야겠네요.. 그리고 아찌님꺼는 인풋이 가변인걸 고려해야하고 {와}사이에 들어가는건 의미있는 단어가 아닙니다. {로 시작해서 }로 끝나는걸 기준으로 한단어씩 들어가는 기대했습니다
WITH t AS
(
SELECT '{이름}님 {1}번째 결과 {결과}입니다' m
, '홍길동,2,성공' p
FROM dual
)
SELECT m
FROM t
MODEL
DIMENSION BY (1 rn)
MEASURES (CAST(m AS VARCHAR2(99)) m, p)
RULES ITERATE (9) UNTIL INSTR(m[1], '{') = 0
( m[1] = REGEXP_REPLACE(m[1], '[{][^}]+[}]'
, REGEXP_SUBSTR(p[1], '[^,]+', 1, ITERATION_NUMBER + 1)
, 1, 1)
)
;
모델절로 구현하셨네요. 새로운 방법이네요. 한가지 수정사항은 m컬럼에 { 이 문자는 표현이 안되네요 {..} 이 형식은 표현 안되는게 맞지만 { 은 출력되어야 합니다
문제 출제시 여러 제약 사항이나 예외사항 들은 사전에 충분히 고지가 되어야 할 것입니다.
예외사항이 있다면 그에 대한 예시도 필요할 것입니다.
만약 구분자에 해당하는 중괄호가 짝이 맞지 않는다면? 여러가지 문제가 초래될 것 같습니다.
구분자가 일반 문자로 허용된다면? 예외적인 상황이 상당히 많을 것으로 생각되네요.
구분자가 일반 문자로 허용되지 않는다는 가정 하에 문제를 풀었습니다.
우선, 언급하신 부분에 대한 예시자료를 보여주세요.
With t(m,p) as (
select '{이름}님 {1}번째 결과 {결과}입니다' , '홍길동,2,성공' from dual UNION ALL
select '{아무개}님 {?}결과 ' , '홍길동,성공' from dual
)
SELECT GB
, MAX(M) M
, MAX(P) P
, LISTAGG(REPLACE('{'||STR,V1,V2 ) ) WITHIN GROUP (ORDER BY LV ) STR
FROM (
SELECT A.*
, LV
, REGEXP_SUBSTR(A.M , '[{](.*?)[}]' , 1 ,B.LV ) V1
, REGEXP_SUBSTR(A.P , '[^,]+' , 1 ,B.LV ) V2
, REGEXP_SUBSTR(A.M , '[^{]+' , 1 ,B.LV ) STR
FROM (SELECT ROWNUM GB , T.* FROM T ) A
, (SELECT LEVEL LV FROM DUAL CONNECT BY LEVEL <= (SELECT MAX(REGEXP_COUNT(m,'{')) FROM T ) ) B
WHERE REGEXP_COUNT(A.M,'{') >= LV
) Z
GROUP BY GB
문장이 { 로 시작하지 않는 경우, { 가 중간부터 나오는 경우. 결과가 이상해짐.
헉,,,,,,,,,,,
예시만 보다가..
-- 중괄호가 짝이 맞지 않는 경우도 있다고 가정 --
WITH t(lv, m, p) AS
(
SELECT 1 lv
, '{이름}님 {1}번{째 {결과 {결과}입}니{다' m
, '홍길동,2,성공' p
FROM dual
UNION ALL
SELECT lv + 1 lv
, REGEXP_REPLACE(m, '[{][^{}]+[}]'
, REGEXP_SUBSTR(p, '[^,]+', 1, lv)
, 1, 1) m
, p
FROM t
WHERE lv <= REGEXP_COUNT(p, '[^,]+')
)
SELECT m
FROM t
WHERE lv = REGEXP_COUNT(p, '[^,]+') + 1
;
음...괄호가 다양하게 중첩되는 경우 원치 않는 결과가 나올 수 있겠네요.
예를 들어
'{ㅁㅁ{ㅂㅂ}ㅅㅅ}{ㅇㅇ}', 'A,B' 이런 자료가 있을 경우
제일 처음 {ㅂㅂ} 를 A 로 바꾸게 되면 {ㅁㅁAㅅㅅ}{ㅇㅇ} 이 되고
두번째 것을 찾을 때 엉뚱하게 {ㅁㅁAㅅㅅ} 을 찾게 되네요.
WITH t AS
(
SELECT '{ㅁㅁ{ㅂㅂ}ㅅㅅ}{ㅇㅇ}{ㅇㅇ}' m
, 'A,B,C' p
FROM dual
)
SELECT x
FROM t
MODEL
DIMENSION BY (1 rn)
MEASURES (m, p, CAST(m AS VARCHAR2(99)) x)
RULES ITERATE (9) UNTIL REGEXP_SUBSTR(p[1], '[^,]+', 1, ITERATION_NUMBER + 1) IS NULL
( x[1] = REGEXP_REPLACE(x[1]
, REPLACE(REPLACE(
REGEXP_SUBSTR(m[1], '[{][^}{]+[}]', 1, ITERATION_NUMBER + 1)
, '{', '\{'), '}', '\}')
, REGEXP_SUBSTR(p[1], '[^,]+', 1, ITERATION_NUMBER + 1)
, 1, 1)
)
;
정답은 언제 올려주시나요?
-- 단건
with t(m,p) as
(
select '{이름}님 {1}번째 결과 {결과}입니다.'
, '홍길동,3,성공'
from dual
), t1(m,p,s) as
(
select m
, p
, 1
from t
union all
select regexp_replace(m,'{([^{}]*[^{}])}',regexp_substr(p,'([^,]*)(,|$)',1,1,'i',1),s,1)
, case when instr(p,',') > 0 then substr(p,instr(p,',')+1) end
, regexp_instr(m,'{([^{}]*[^{}])}',s)
from t1
where p is not null
)
select m
from t1
where p is null;
-- 다건
with t(m,p) as
(
select '{이름}님 {1}번째 결과 {결과}입니다.','홍길동,3,성공' from dual union all
select '{이름}님 {1}번째 결과 {결과}입니다.({사유})','홍길순,2,실패,요건미달' from dual union all
select '{이름}님 {결과}입니다.','홍길동,완료' from dual
)
select listagg(regexp_substr(a.m,'([^ˇ]*)(ˇ|$)',1,b.no,'i',1)||regexp_substr(a.p,'[^,]+',1,b.no))
within group (order by b.no) as m
from (select regexp_replace(m,'{([^{}]*[^{}])}','ˇ') m
, p
from t) a
inner join (select level no from dual connect by level <= 10) b
on b.no <= regexp_count(a.m,'ˇ') + 1
group by
a.m;
아.. CTE...
WITH t AS
(
SELECT '{ㅁㅁ{ㅂㅂ}ㅅㅅ}{ㅇㅇ}{ㅇㅇ}' m, 'A,B,C' p FROM dual
UNION ALL SELECT '{이름}님 {1}번째 결과 {결과}입니다.', '홍길동,3,성공' FROM dual
UNION ALL SELECT '{이름}님 {1}번째 결과 {결과}입니다.({사유})', '홍길순,2,실패,요건미달' FROM dual
UNION ALL SELECT '{이름}님 {결과}입니다.', '홍길동,완료' FROM dual
)
SELECT m
FROM t
MODEL
DIMENSION BY (ROWNUM rn)
MEASURES (REGEXP_REPLACE(m, '{[^}{]+}', '♪') m, p)
RULES ITERATE (9)
( m[ANY] = REGEXP_REPLACE(m[CV()], '♪'
, REGEXP_SUBSTR(p[CV()], '[^,]+', 1, ITERATION_NUMBER + 1)
, 1, 1)
)
;
WITH t AS
(
SELECT '{ㅁㅁ{ㅂㅂ}ㅅㅅ}{ㅇㅇ}{ㅇㅇ}' m, 'A,B,C' p FROM dual
UNION ALL SELECT '{이름}님 {1}번째 결과 {결과}입니다.', '홍길동,3,성공' FROM dual
UNION ALL SELECT '{이름}님 {1}번째 결과 {결과}입니다.({사유})', '홍길순,2,실패,요건미달' FROM dual
UNION ALL SELECT '{이름}님 {결과}입니다.', '홍길동,완료' FROM dual
)
, t1 (m, p) AS
(
SELECT REGEXP_REPLACE(m, '{[^}{]+}', '♪') m
, p
FROM t
UNION ALL
SELECT REGEXP_REPLACE(m, '♪', REGEXP_SUBSTR(p, '[^,]+'), 1, 1)
, REGEXP_REPLACE(p, '^,?[^,]+') p
FROM t1
WHERE INSTR(m, '♪') > 0
)
SELECT *
FROM t1
WHERE INSTR(m, '♪') = 0
;