고정문자텍스트파일을 받았는데요
통으로 clob 컬럼에 적재를 하고요. 고정문자텍스트 레이아웃을 받은 내용으로 문자를 잘랐는데요..
substr, substrb 모두 문자가 제대로 잘리지 않네요..
엑셀에서는 midb 함수를 이용하면 잘 잘리는데 말이죠..
엑셀에서 midb 와 오라클의 substrb 같은 기능 아닌가요? 바이트로 계산하여 문자를 자르는..
엑셀에서 lenb 값과 오라클에서 lengthb 값도 다르더군요..
원인이 무엇일까요.. 답변 부탁드립니다 !~
우선 답변 감사합니다. 실제데이터 양식 알려드리겠습니다..
00000000000 0000 00000000000000 000 00000000000000000 0000 00000 00000000 가가가가가가가가가가 가가가가가 나나 다다다00000000 가가 가가가 0000000000000000000 가가가 000000000000 ZZZZZZZZZ00 00000000000000 가가가00000000000000ZZZZZZZZZ000 ZZZZZZZZZ00 ZZZZZZ000 ZZZZZZ0000000.0000000000000000000000.00000000000000000000000.000000000
실제데이터고요. 텍스트파일을 받아서 db clob 컬럼에 적재하였습니다.
결과값은 "나나", "다다다"(앞뒤로 공백은 존재해도 됩니다. 데이터가 그렇게 되어있습니다.) 를 받고 싶습니다..
엑셀 midb 함수를 사용하면 제대로 나오는데 디비에서는 전혀 다른 결과를 가져오네요..결과값을 못 얻네요..
사용 쿼리입니다.
SELECT
SUBSTRB(TO_CHAR(DATA),492, 6) AS "나나"
, SUBSTRB(TO_CHAR(DATA),498, 19) AS "다다다"
FROM DATA_TABLE
;
홈런쓰님 UTF8/AL32UTF8은 한글 한 글자가 3BYTE 입니다. 그러면 원하시는 결과를 얻으려면.. 어떻게 해야할까요? 산수가 잘 안 되네요;
그리고 또 한 가지.. 데이터가 4000 BYTE가 넘으면 홈런쓰님이 작성하신 방법은 아예 오류가 날테고 제가 알려드린 방법(substrb(dbms_lob.substr(컬럼,10),1,10))도 4000BYTE 이전까지 SUBSTRB하면 오류가 안 나겠지만 그 이상이 되면 오류가 나겠네요. 혹시나 4000BYTE 넘는 데이터가 있나요? 있다면 4000BYTE 이후로 SUBSTRB 할 케이스가 있으신지.. CLOB을 쓰신 걸로 봐서는 있을 것 같은데..
제 환경에서는 또 다르게 나오네요.
한글이 3Byte 여서 그런 것인데...
-- Version : Oracle Database 11g Express Edition Release 11.2.0.2.0 -- nls_characterset : AL32UTF8 -- nls_nchar_characterset : AL16UTF16 WITH data_table AS ( SELECT TO_CLOB( '00000000000 0000 00000000000000 000 00000000000000000 0000 00000 00000000 가가가가가가가가가가 가가가가가 나나 다다다00000000 가가 가가가 0000000000000000000 가가가 000000000000 ZZZZZZZZZ00 00000000000000 가가가00000000000000ZZZZZZZZZ000 ZZZZZZZZZ00 ZZZZZZ000 ZZZZZZ0000000.0000000000000000000000.00000000000000000000000.000000000' ) AS data FROM dual ) SELECT SUBSTRB(TO_CHAR(data), 492, 6) x , SUBSTRB(TO_CHAR(data), 498, 19) x , SUBSTRB(TO_NCHAR(data), 492, 6) y , SUBSTRB(TO_NCHAR(data), 498, 19) y FROM data_table ; -- 결과 : ' 가 ', ' 가가 나나 ', ' ', ' '
WITH data_table AS ( -- 원본 테이블 SELECT 1 no, TO_CLOB( '00000000000 0000 00000000000000 000 00000000000000000 0000 00000 00000000 가가가가가가가가가가 가가가가가 나나 다다다00000000 가가 가가가 0000000000000000000 가가가 000000000000 ZZZZZZZZZ00 00000000000000 가가가00000000000000ZZZZZZZZZ000 ZZZZZZZZZ00 ZZZZZZ000 ZZZZZZ0000000.0000000000000000000000.00000000000000000000000.000000000' ) AS data FROM dual ) , code_table AS ( -- 잘라올 항목들의 시작위치와 길이를 코드화 SELECT 1 cd, 492 a, 6 b FROM dual UNION ALL SELECT 2, 498, 19 FROM dual ) SELECT * FROM (SELECT a.no , c.cd , LISTAGG(v) WITHIN GROUP(ORDER BY lv) v FROM (SELECT no , lv , SUBSTR(v, lv, 1) v , SUM(LEAST(LENGTHB(SUBSTR(v, lv, 1)), 2)) OVER(PARTITION BY no ORDER BY lv) - LEAST(LENGTHB(SUBSTR(v, lv, 1)), 2) + 1 x FROM (SELECT no, TO_CHAR(data) v FROM data_table) , (SELECT LEVEL lv FROM dual CONNECT BY LEVEL <= 999) WHERE lv <= LENGTH(v) ) a , code_table c WHERE a.x BETWEEN c.a AND c.a + c.b - 1 GROUP BY a.no, c.cd ) PIVOT (MIN(v) FOR cd IN (1, 2)) ;
substrb(convert(to_char(컬럼), 'KO16KSC5601','AL32UTF8'),1,10) 잘될지는 모르겠습니다.
convert라고 characterset 바꿔주는 함수가 10g부터 있었네요.
CONVERT( '대상 문자열', '타겟 캐릭터셋', '소스 캐릭터셋')
http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions034.htm#SQLRF00620