오라클에서 nested table 사용하기.
이런식으로 ordbms 의 기능을 처음으로 쓰게 될 줄은 몰랐지만, 어쨌든 inverted index의 대용임. 이런게 있으니 편리하긴 편리하군…
type만든다.
CREATE TYPE ID_LOC AS OBJECT (ID VARCHAR2(11), LOC NUMBER) /
type의 table만든다.
CREATE TYPE ID_LOC_LIST AS TABLE OF ID_LOC /
nested table 만든다.
CREATE TABLE K0_2 OF K0_TYPE NESTED TABLE IDLOC STORE AS K0_2_IDLOC STORAGE(MAXEXTENTS UNLIMITED) PCTFREE 0 NOLOGGING /
k0에서 k0_2 로 로드하는 프로그램 만든다. 코드중 multiset은 하나의 항목이 아니라 다수의 항목임을 뜻하고, cast는 multiset으로 넘겨져온 id_loc를 id_loc_list로 캐스팅함.
CREATE OR REPLACE PROCEDURE POPULATE_K0_2 AS CURSOR C IS SELECT T1.TYPESTR, T1.TYPELEN, T1.LOOKAHEAD, CAST( MULTISET( SELECT ID, LOC FROM K0 T2 WHERE T1.TYPESTR = T2.TYPESTR AND T1.TYPELEN = T2.TYPELEN AND T1.LOOKAHEAD = T2.LOOKAHEAD) AS ID_LOC_LIST) ID_LOC FROM ( SELECT TYPESTR, TYPELEN, LOOKAHEAD FROM K0 GROUP BY TYPESTR, TYPELEN, LOOKAHEAD ) T1; R C%ROWTYPE; INSERT_CNT PLS_INTEGER := 0; BEGIN OPEN C; DBMS_OUTPUT.PUT_LINE('CURSOR OPENED.'); LOOP INSERT_CNT := INSERT_CNT + 1; DBMS_OUTPUT.PUT_LINE(INSERT_CNT); FETCH C INTO R; IF C%NOTFOUND THEN EXIT; END IF; INSERT INTO K0_2 VALUES(R.TYPESTR, R.TYPELEN, R.LOOKAHEAD, R.ID_LOC); COMMIT; END LOOP; CLOSE C; END; /
매번 commit해서인지 너무 느리다. 한 50개마다 커밋했어야하는데.. 덕분에 10시간은 넘게 실행중인거 같음.. 처음엔 커밋을 아예 안했더니 롤백 세그먼트 200개 넘어가면서 아무런 반응도 없어서 고쳐놨더니 오히려 더 상황이 나빠짐 -_-;
나중에 bulk insert를 쓰던지 parallel 로 하던지 어떻게든 고쳐놔야함..
for 레코드 in 커서 loop 문법 안쓰고 loop, if..%NOTFOUND.., end loop 한거는 어찌 디버깅하다가보니까 그냥 이렇게 된 것임.