지금까지 미국산 알티베이스를 주로 써왔는데 알티베이스의 경우 iloader 툴이 fmt파일을 없는 경우 formout 옵션을 통해 만들 수가 있다.

그렇게 써오던 중 오라클은 sqlldr에서 동일한 기능이 없다는 것을 알게 되었음.

작업할 테이블이 한두개면야 만들어서 쓰겠는데...이번에 작업할 테이블 개수가 대략 수백개에 달했다.

분명 이런거 자동으로 해주는 툴이 있거나 쉘로 짜서 올려놓은 분이 있을거라 생각했는데 검색에 실패함...ㅜ

그래서 직접 짜보는 sqlldr용 컨트롤 파일 작성기!

먼저 테이블명과 컬럼을 수집할 대상이 있다면 좋겠지만 난 없지만 다행이도 전체 테이블을 대상으로 함. 그렇기에 질의를 통해 이를 해결함.

#!/bin/sh echo "set pagesize 10000;" > login.sql echo "set linesize 1024;" >> login.sql echo "set heading off;" >> login.sql echo "set feedback off;" >> login.sql function scan_tbl() { sqlplus -S scott/tiger << EOF select table_name from user_tables order by table_name; --select table_name, owner from all_tables where owner = 'SCOTT' order by table_name; quit; EOF } function scan_col() { sqlplus -S scott/tiger << EOF --select wm_concat(column_name) from user_tab_columns where table_name ='$1' order by COLUMN_ID; select listagg(column_name, ',') within group(order by column_id) from user_tab_columns where table_name ='$1'; quit; EOF } for TBL_NAME in `scan_tbl` do #echo "TABLE_NAME=[${TBL_NAME}]" echo "load data" > ${TBL_NAME}.ctl echo "infile ${TBL_NAME}.dat" >> ${TBL_NAME}.ctl echo "into table ${TBL_NAME}" >> ${TBL_NAME}.ctl echo "fields terminated by '^'" >> ${TBL_NAME}.ctl echo "optionally enclosed by '\"'" >> ${TBL_NAME}.ctl echo "TRAILING NULLCOLS" >> ${TBL_NAME}.ctl echo "(" >> ${TBL_NAME}.ctl echo `scan_col ${TBL_NAME}` >> ${TBL_NAME}.ctl echo ")" >> ${TBL_NAME}.ctl done

어렵지 않은 코드이니 직관적으로 이해하기 쉬운 수준이다.

단점은 오라클 11g이상에서만 동작한다. 이유는 LISTAGG 함수 때문...11g이하에선 WM_CONCAT을 사용해야 하는데 컬럼 순서 오더링이 보장되지 않는다...WM_CONCAT에 대해 잘 아시는 분이라면 해결하실 듯...

추가로 처음에 테이블 리스트를 조회하는데 한번 그리고 테이블 당 한번씩 컬럼 정보를 조회하기 위해서 데이터베이스에 연결을 한다. 이부분에서 지연이 발생한다. 컬럼 정보를 한방에 받아오고 나눠서 쓰거나 분석해서 쓰면 훨씬 빨라지리라 예상한다.

제약으로는 이미 받아져 있는 데이터파일을 올릴 경우 모든 컬럼이 있어야 하고, 컬럼 순서가 동일해야 한다는 정도이다.

그 외에는 딱히 생각나는게 없네...