근간에 Project를 진행하면서 Multi Row로 저장된 데이터를 한 Field로 처리할 방법을 Search하다 알게된 listagg 함수,
GROUP BY 와 함께 사용하면 같은 Key Field 값을 가진 ROW 데이터를 합칠 수 있다.

SELECT KEYFIELD, listagg( field_name, ',') within group (order by field_name)
FROM table
GROUP BY KEYFIELD

워낙 이런 Case가 많아서, 자주 사용하기 시작했는데,
오늘 listagg 함수를 사용한 Query에서 ORA-01489 에러가 발생..

찾아 보니... Oracle에서 문자열 Concatenate를 4000 byte 까지 밖에 지원하지 않는 것이다.
크.. 언제적 제약사항이 아직도 발목을 잡는 건지..

Googling을 해 보았더니.. StackOverflow에 관련 내용도 있고,
여러 내용을 리뷰해 보니, Query Level에서 이 문제를 해결할 방법은 아래와 같이 XML TYPE으로 변경해서 Aggregation 하는 방법 밖에는 없다.
http://stackoverflow.com/questions/14864055/listagg-function-and-ora-01489-result-of-string-concatenation-is-too-long

select tm.product_id, 
       rtrim(extract(xmlagg(xmlelement(e, tm.book_id || '(' || tm.score || '),')), 
               '/E/text()').getclobval(), ',')
  from tl_product_match tm
 where tm.book_id is not null 
 group by tm.product_id;

문제는.. XML로 변환 하고, Aggregation 한후 정규식으로 XML TAG를 제거 하고, 이를 다시 CLOB으로 변경하니, Performance가 엄청 좋지 않다는 점..

지금 Project는 Java Program 단에서 해결해 낼 수 있을 것 같긴 한데..
Oracle도 예전 코드들 때문에 이런 제약사항에 시달리는 걸 보면..
너무 앞장서서 나가는 것도 생각 만큼 좋지는 않은 듯...

'개발자세상 > Database관련' 카테고리의 다른 글

UPSERT ? INSERT ON DUPLICATE KEY UPDATE  (0) 2016.09.24
Open Cursor issue  (0) 2014.10.25
Oracle TEMP 파일 삭제  (0) 2013.09.23
오라클 DB에서 테이블마다 용량 구하기  (0) 2013.08.10
Overlap 데이터 구하기  (0) 2013.08.04
Posted by headiron
,