Describe SQLLoader사용방법 here {{{ ============ SQL * Loader ============ 이 툴을 만지리라 생각하셨다면..이미 테이블에 대한 설계가 끝난 상태일 것입니다.. 난 아닌디....하시는 분은... 머..기냥 보시구여.. SQL*Loader라는 툴은 테이블에 데이타를 집어 넣는 것입니다... 문자형에서 숫자형...이미지 까지 집어 넣을 수 있습니다.. 집어 넣는거야..insert문을 쓰거나 해서 집어 넣을 가 있습니다.. 그러나 1만건...10만건 또는 그 이상의 데이타를 집어 넣으려면.... 테이블은 만들었는데...데이타는 엑셀파일로 되어있다...쩝.. 보통의 노가다로는 해결할 수 없습니다... 그래서 등장한 툴이 바로 SQL*Loader입니다... 아주 멋진 툴입니다...막바로..기냥 테이블에 데이타를 때려 부울수가 있게 해주는 툴입니다.. 이것도 기냥하는 것은 아닙니다.. 5가지 파일을 만들어 주어야 합니다... 다음은 그 파일과 설명입니다.. control file : 데이타 적재를 위한 제어 파일 data file : 데이타를 담고 있는 파일 log file : 로그 파일 bad file : 적재되지 못한 데이타들 discard file : 적재되지 못한 데이타들에 대한 정보를 저장 일단..대량의 데이타를 넣는 다는 것도 상당히 문제를 일으킬 수 있습니다... 만약 시스템이 어떤 서비스를 가동중인 상태에서 이런 대량의 데이타를 적재시키는 작업을 한다면.. 여러가지를 고려해 주어야합니다... 근데...일반적인 이미지나..큰 텍스트가 아닌 데이타를 적재시킬때...그렇게 오래 걸리지는 않더군여... 약...2만건을 적재시키는데...15초 정도 걸리더라구여...일반 pc에서 말입니다.. 헐헐~ 암튼...여러가지 고려사항이 있습니다.. 그 고려상항에 맞추라고 오라클에서는 두가지의 데이타 로드 방법을 제공하고 있습니다.. - 일반 경로를 이용한 방법 -인덱스화된 테이블의 데이타 로드시 사용 -인덱스화 되지 않은 테이블에 대한 로드시 사용 -클러스트화된 테이블의 데이타 로드시 사용 -NET*에 의해 로더할 때 사용 -SQL 함수를 데이타 필드에 적용할 때 사용 - 직접 경로를 이용한 방법 -내부적으로 처리되기 때문에 SQL문이 사용되지 않는다. -오직 한번만 테이블과 인덱스에 잠금이 발생 -버퍼를 사용하지 않아 일반경로를 이용한 방법보다 빠르게 실행 -노아카이브로그 모드에서 사용할때 테이블에 발생하는 모든 로그 정보를 저장하지 않는다. 두가지 방법의 비교 일반경로 직접경로 ---------------------------------- ------------------------------------------- committ문으로 데이타 저장 하나의 블록이 모두 사용되면 저장 리두로그 정보가 항상 생성 노아카이브로그 --> 리두로그 정보 생성안됩 아카이브로그 --> 리두로그 정보 생성 테이블의 모든 제약조건 적용 기본키, 유일키, not null 제약만 적용 클러스트도 로드 가능 클러스트 로드 불가능 로드중에도 insert 트리거 사용 가능 로더중에 insert 트리거 사용 불가능 다른 사용자가 로드되는 테이블 다른 사용자가 로드되는 테이블 사용할 수 없음 사용가능 자...이제는 SQL*Loader 를 사용해 봅시다... ======================================================================================== C:\>sqlldr SQL*Loader: Release 8.1.6.0.0 - Production on 화 Jan 29 15:49:42 2002 (c) Copyright 1999 Oracle Corporation. All rights reserved. 사용법: SQLLOAD 키워드=값 [,키워드=값,...] 적절한 키워드: userid -- ORACLE username/password control -- Control file name log -- Log file name bad -- Bad file name data -- Data file name discard -- Discard file name discardmax -- Number of discards to allow (기본값 all) skip -- Number of logical records to skip (기본값 0) load -- Number of logical records to load (기본값 all) errors -- Number of errors to allow (기본값 50) rows -- Number of rows in conventional path bind array or between direct p ath data saves (기본값: 규약 경로 64, 직접 경로 전체) bindsize -- Size of conventional path bind array in bytes (기본값 65536) silent -- Suppress messages during run (header,feedback,errors,discards,partitions) direct -- use direct path (기본값 FALSE) parfile -- parameter file: name of file that contains parameter specifications parallel -- do parallel load (기본값 FALSE) file -- File to allocate extents from skip_unusable_indexes -- disallow/allow unusable indexes or index partitions (기본값 FALSE) skip_index_maintenance -- do not maintain indexes, mark affected indexes as unusable (기본값 FALSE) commit_discontinued -- commit loaded rows when load is discontinued (기본값 FALSE) readsize -- Size of Read buffer (기본값 1048576) 주: 명령줄 매개변수는 위치 혹은 키워드로 지정될 수 있습니다 전자의 경우의 예는 'sqlload scott/tiger foo'; 후자의 경우의 예는 'sqlload control=foo userid=scott/tiger'. 하나는 이전 위치에 의해 매개변수를 지정할 수 있으나 매개변수가 키워드에 의해 지정한 이후에는 할 수 없습니다. 예를 들어, 'sqlload scott/tiger control=foo logfile=log'는 허용되지만, 'sqlload scott/tiger control=foo log'는 매개변수 'log'의 위치가 맞더라도 허용되지 않습니다 ======================================================================================== 그냥 명령 프롬프트에서 sqlldr라구만 쳐보면 이런 설명이 나옵니다.. 유닉스도 마찬가지구여... 유닉스도 함 볼까요?? ======================================================================================== /data2/lgeds>sqlldr SQL*Loader: Release 8.1.6.0.0 - Production on Tue Jan 29 15:48:24 2002 (c) Copyright 1999 Oracle Corporation. All rights reserved. Usage: SQLLOAD keyword=value [,keyword=value,...] Valid Keywords: userid -- ORACLE username/password control -- Control file name log -- Log file name bad -- Bad file name data -- Data file name discard -- Discard file name discardmax -- Number of discards to allow (Default all) skip -- Number of logical records to skip (Default 0) load -- Number of logical records to load (Default all) errors -- Number of errors to allow (Default 50) rows -- Number of rows in conventional path bind array or between direct path data saves (Default: Conventional path 64, Direct path all) bindsize -- Size of conventional path bind array in bytes (Default 65536) silent -- Suppress messages during run (header,feedback,errors,discards,partitions) direct -- use direct path (Default FALSE) parfile -- parameter file: name of file that contains parameter specifications parallel -- do parallel load (Default FALSE) file -- File to allocate extents from skip_unusable_indexes -- disallow/allow unusable indexes or index partitions (Default FALSE) skip_index_maintenance -- do not maintain indexes, mark affected indexes as unusable (Default FALSE ) commit_discontinued -- commit loaded rows when load is discontinued (Default FALSE) readsize -- Size of Read buffer (Default 1048576) PLEASE NOTE: Command-line parameters may be specified either by position or by keywords. An example of the former case is 'sqlload scott/tiger foo'; an example of the latter is 'sqlload control=foo userid=scott/tiger'. One may specify parameters by position before but not after parameters specified by keywords. For example, 'sqlload scott/tiger control=foo logfile=log' is allowed, but 'sqlload scott/tiger control=foo log' is not, even though the position of the parameter 'log' is correct. ======================================================================================== 아차차차차차~~!! 빼먹을 뻔했슴다... 나중에 로더를 사용해서 데이타를 적재시키는데... sqlldr userid=scott/tiger control='C:\control.ctl' 의 식으로 하게 되는데.. 주의할 것은 errors 라는 옵션을 충분히 주라는 얘기입니다.. 기본값으로 50으로 설정되어 있어서 데이타 파일의 적절하지 않은 데이타가 50건이 넘으면 데이타 적재를 하다가 멈춰버리니까여... 제가 이걸 몰라서 엄청난 삽질을 한 경험이 있답니다.. 대량의 데이타 적재시 반드시 errors의 값을 충분히 설정해 주시기 바랍니다.. 자...이제 실제로 해봅시다... 먼저 컨트롤 파일을 하나 만들기 전에... 테스트를 위한 사용자를 하나 생성해 봅시다.... SQL> create user loader identified by loader 2 default tablespace users; 사용자가 생성되었습니다. SQL> grant connect, resource to loader; 권한이 부여되었습니다. 다음으로 오라클 셋업할때 샘플로 주어진 것으로 실습할꺼니까... scott.emp파일에 대한 똑같은 구조를 가지는 테이블을 만들어 봅시다.. SQL> connect scott/tiger 연결되었습니다. SQL> grant select on emp to loader; 권한이 부여되었습니다. SQL> create table emp 2 as 3 select * from scott.emp 4 where 1=0; ------------> 여기서 where 1=0 한것은 테이블의 구조만 복사하기 위한 것이다.. 테이블이 생성되었습니다. 예제는 $ORACLE_HOME/rdbms/demo에 있습니다... ulcase.* 들이 로더와 관련된 것들입니다... 겅부하기 편하게 해놨지여??? 헐헐~ 물론 mssql보다는 편하지는 않지만..쩝.. 앗~ 된장...첨에 dept테이블이 군요... 쩝... 아래 sql 스크립트를 실행합니다..쩝.. create table dept (deptno number(2), dname char(14) , loc char(13) ) ; ulcase1.ctl의 내용입니다.. LOAD DATA INFILE * INTO TABLE DEPT FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (DEPTNO, DNAME, LOC) BEGINDATA 12,RESEARCH,"SARATOGA" 10,"ACCOUNTING",CLEVELAND 11,"ART",SALEM 13,FINANCE,"BOSTON" 21,"SALES",PHILA. 22,"SALES",ROCHESTER 42,"INT'L","SAN FRAN" 이 컨트롤 파일의 내용을 살펴보자면.... LOAD DATA ----> 개나 소나 컨트롤 파일에는 첨에 다 들어 갑니다.. INFILE * ----> '*' 표시는 컨트롤 파일안에 적재할 데이타가 들어있다는 소리입니다.. 여기에 데이타파일과 컨트롤 파일이 분리 되어 있다면..데이타 파일의 경로를 입력할 도 있다.. INTO TABLE DEPT ----> dept 테이블에 적재하것다는 소리.. FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' -----> 각 필드가 ',' 로 구분하고 옵션으로 '""로 둘러 쌓고 있다는 소리.. 즉, '"'는 적재되지 않는다.. (DEPTNO, DNAME, LOC) -----> 데이타가 들어갈 컬럼명 BEGINDATA ------> 데이타가 시작된다는 의미 나머지는 데이타입니다.. 이 파일을 간단하게 c:\으로 복사하것슴다.. ============================================================================================ C:\>sqlldr userid=loader/loader control='C:\ulcase1.ctl' SQL*Loader: Release 8.1.6.0.0 - Production on 화 Jan 29 16:14:44 2002 (c) Copyright 1999 Oracle Corporation. All rights reserved. 커밋 시점에 도달 - 논리 레코드 개수 7 ============================================================================================ SQL> select count(*) from dept; COUNT(*) ---------- 7 ------------> 데이타가 들어 갔습니다.. 헐헐~ 절라 좋습니다...편리함돠...헐헐~ 여기서 알은 것은...상당히 많습니다... 일단...컨트롤 파일과 데이타만 있다면 로더의 실행은 가능합니다... 그러나...10만건..100만건 되는 데이타에 오류가 없을 수는 없는 노릇입니다.. ulcase1.ctl의 내용을 살짝 수정해 봅시다.... LOAD DATA INFILE * APPEND ---------> APPEND 라는 키워드 추가... INTO TABLE DEPT FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (DEPTNO, DNAME, LOC) BEGINDATA 12,RESEARCH,"SARATOGA" 100,"ACCOUNTING",CLEVELAND -------> 10을 100으로 고쳤음.. 11,"ART",SALEM 13,FINANCE,"BOSTON" 21,"SALES",PHILA. 22,"SALES",ROCHESTER 42,"INT'L","SAN FRAN" < 참고 사항 > replace 테이블의 기존 행을 모두 삭제(delete)하고 insert append 새로운 행을 기존의 데이타에 추가 insert 비어 있는 테이블에 넣을 때 truncate 테이블의 기존 데이타를 모두 truncate 하고 insert ================================================================================ C:\>sqlldr userid=loader/loader control='C:\ulcase1.ctl' SQL*Loader: Release 8.1.6.0.0 - Production on 화 Jan 29 16:20:18 2002 (c) Copyright 1999 Oracle Corporation. All rights reserved. 커밋 시점에 도달 - 논리 레코드 개수 7 ================================================================================ SQL> RUN 1* select count(*) from dept COUNT(*) ---------- 13 --------------> 13개입니다.. 물론 필수적으로 컨트롤 파일과 데이타가 있으면 되지만.... 데이타에 오류가 있는 경우는 문제가 됩니다.. 그러므로 다음과 같이 5가지의 파일을 모두 나열해 줍니다... ================================================================================ C:\>sqlldr userid=loader/loader control='C:\ulcase1.ctl' log='c:\ulcase1.log' ba d='c:\ulcase1.bad' discard='c:\ulcase1.dsc' SQL*Loader: Release 8.1.6.0.0 - Production on 화 Jan 29 16:23:46 2002 (c) Copyright 1999 Oracle Corporation. All rights reserved. 커밋 시점에 도달 - 논리 레코드 개수 7 ================================================================================ SQL> run 1* select count(*) from dept COUNT(*) ---------- 19 자..이제 데이타가 안들어간 것에 대한 로그와 데이타를 살펴보도록 합니다.. ulcase1.log ================================================================================ SQL*Loader: Release 8.1.6.0.0 - Production on 화 Jan 29 16:23:46 2002 (c) Copyright 1999 Oracle Corporation. All rights reserved. 제어 파일: C:\ulcase1.ctl 데이터 파일: C:\ulcase1.ctl 잘못된 파일: c:\ulcase1.bad 폐기 파일: c:\ulcase1.dsc (모든 폐기된 레코드 허용) 로드할 건수: ALL 생략 건수: 0 허용 오류수: 50 바인드 배열: 64 행, 최대 65536 바이트 계속: 지정 사항 없음 사용된 경로: 규약 테이블 DEPT, 로드되었습니다 개개의 논리 레코드로부터 이 테이블에 적당한 Insert 옵션: APPEND 열 이름 위치 Len Term Encl 데이터유형 ------------------------------ ---------- ----- ---- ---- --------------------- DEPTNO FIRST * , O(") CHARACTER DNAME NEXT * , O(") CHARACTER LOC NEXT * , O(") CHARACTER 레코드 2: 기각됨 - 테이블 DEPT, 열 DEPTNO에 오류 ORA-01438: 지정한 정도를 초과한 값이 열에 지정되었습니다 테이블 DEPT: 6 행들 로드되었습니다. 데이터 오류 때문에 1 행(이)가 로드되지 않았습니다 모든 WHEN절이 실패하여 0 행들(이)가 로드되지 않았습니다 모든 필드가 NULL이어서 0 행들(이)가 로드되지 않았습니다 바인드 배열에 할당된 영역: 49536바이트(64 행) 바인드 배열외에 메모리에 할당된 영역: 0 바이트 생략된 논리 레코드의 합계: 0 읽어낸 논리 레코드의 합계: 7 거부된 논리 레코드의 합계: 1 폐기된 논리 레코드의 합계: 0 화 Jan 29 16:23:46 2002에 실행 개시 화 Jan 29 16:23:48 2002에 실행 종료 경과 시간: 00:00:02.49 CPU 시간: 00:00:00.07 ================================================================================ ulcase1.bad ================================================================================ 100,"ACCOUNTING",CLEVELAND ================================================================================ 로그를 살펴보면... 'ORA-01438: 지정한 정도를 초과한 값이 열에 지정되었습니다' 라는 것이 보입니다.. 10이 들어가야 하는 것이 100이 들어가서 컬럼에 들어갈 수 없다는 뜻이지여...헐헐~ 자...이제 기초를 알았으니... 나머지는 컨트롤 파일에 대해서만 설명하고 SQL*Loader를 마치도록 하겠슴다.. ulcase2.ctl ================================================================================ LOAD DATA INFILE 'ulcase2.dat' --------> 데이타가 들어 있는 파일의 경로 INTO TABLE EMP ( EMPNO POSITION(01:04) INTEGER EXTERNAL, ENAME POSITION(06:15) CHAR, JOB POSITION(17:25) CHAR, MGR POSITION(27:30) INTEGER EXTERNAL, SAL POSITION(32:39) DECIMAL EXTERNAL, COMM POSITION(41:48) DECIMAL EXTERNAL, DEPTNO POSITION(50:51) INTEGER EXTERNAL) EMPNO POSITION(01:04) INTEGER EXTERNAL의 의미는 empno 커럼의 데이타는 01열에서 04열 까지이다라는 것과 integer형으로 운영체제의 파일에 컬럼의 데이타형을 맞춘다는 의미입니다... ulcase2.dat ================================================================================ 7782 CLARK MANAGER 7839 2572.50 10 7839 KING PRESIDENT 5500.00 10 7934 MILLER CLERK 7782 920.00 10 7566 JONES MANAGER 7839 3123.75 20 7499 ALLEN SALESMAN 7698 1600.00 300.00 30 7654 MARTIN SALESMAN 7698 1312.50 1400.00 30 7658 CHAN ANALYST 7566 3450.00 20 ulcase3.ctl ================================================================================ LOAD DATA INFILE * APPEND ----------> 기존의 컬럼에 데이타 추가.... INTO TABLE EMP FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' (empno, ename, job, mgr, hiredate DATE(20) "DD-Month-YYYY", -------> 날짜 형식 sal, comm, deptno CHAR TERMINATED BY ':', -------> 이 컬럼 구분의 종결자입니다...즉, 다음부터는 ':' 으로 컬럼 구분 projno, loadseq SEQUENCE(MAX,1) ) ---------> 자동생성 컬럼으로 시퀀스입니다.. BEGINDATA 7782, "Clark", "Manager", 7839, 09-June-1981, 2572.50,, 10:101 7839, "King", "President", , 17-November-1981, 5500.00,, 10:102 7934, "Miller", "Clerk", 7782, 23-January-1982, 920.00,, 10:102 7566, "Jones", "Manager", 7839, 02-April-1981, 3123.75,, 20:101 7499, "Allen", "Salesman", 7698, 20-February-1981, 1600.00, 300.00, 30:103 7654, "Martin", "Salesman", 7698, 28-September-1981, 1312.50, 1400.00, 30:103 7658, "Chan", "Analyst", 7566, 03-May-1982, 3450,, 20:101 SQL> run ---------> 데이타 적재후 결과... 1* select * from emp EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO PROJNO LOADSEQ ---------- ---------- --------- ---------- -------- ---------- ---------- ---------- ---------- ---- 7782 Clark Manager 7839 81/06/09 2572.5 10 101 1 7839 King President 81/11/17 5500 10 102 2 7934 Miller Clerk 7782 82/01/23 920 10 102 3 7566 Jones Manager 7839 81/04/02 3123.75 20 101 4 7499 Allen Salesman 7698 81/02/20 1600 300 30 103 5 7654 Martin Salesman 7698 81/09/28 1312.5 1400 30 103 6 7658 Chan Analyst 7566 82/05/03 3450 20 101 7 7 개의 행이 선택되었습니다. ulcase4.ctl ================================================================================ LOAD DATA INFILE "ulcase4.dat" DISCARDFILE "ulcase4.dis" DISCARDMAX 999 ----------> 디스카드 파일은 최대 999까지 허용 REPLACE CONTINUEIF (1) = '*' -----------> 널값은 '*'로 대체한다... INTO TABLE EMP ( EMPNO POSITION(01:04) INTEGER EXTERNAL, ENAME POSITION(06:15) CHAR, JOB POSITION(17:25) CHAR, MGR POSITION(27:30) INTEGER EXTERNAL, SAL POSITION(32:39) DECIMAL EXTERNAL, COMM POSITION(41:48) DECIMAL EXTERNAL, DEPTNO POSITION(50:51) INTEGER EXTERNAL, HIREDATE POSITION(52:60) INTEGER EXTERNAL) ulcase5.ctl ================================================================================ LOAD DATA INFILE 'ulcase5.dat' BADFILE 'ulcase5.bad' DISCARDFILE 'ulcase5.dis' REPLACE INTO TABLE EMP (EMPNO POSITION(1:4) INTEGER EXTERNAL, ENAME POSITION(6:15) CHAR, DEPTNO POSITION(17:18) CHAR, MGR POSITION(20:23) INTEGER EXTERNAL) INTO TABLE PROJ -- PROJ has two columns, both not null: EMPNO and PROJNO WHEN PROJNO != ' ' (EMPNO POSITION(1:4) INTEGER EXTERNAL, PROJNO POSITION(25:27) INTEGER EXTERNAL) -- 1st proj INTO TABLE PROJ WHEN PROJNO != ' ' (EMPNO POSITION(1:4) INTEGER EXTERNAL, PROJNO POSITION(29:31) INTEGER EXTERNAL) -- 2nd proj INTO TABLE PROJ WHEN PROJNO != ' ' (EMPNO POSITION(1:4) INTEGER EXTERNAL, PROJNO POSITION(33:35) INTEGER EXTERNAL) -- 3rd proj ulcase5.dat ================================================================================ 1234 BAKER 10 9999 101 102 103 1234 JOKER 10 9999 777 888 999 2664 YOUNG 20 2893 425 abc 102 5321 OTOOLE 10 9999 321 55 40 2134 FARMER 20 4555 236 456 2414 LITTLE 20 5634 236 456 40 6542 LEE 10 4532 102 321 14 2849 EDDS xx 4555 294 40 4532 PERKINS 10 9999 40 1244 HUNT 11 3452 665 133 456 123 DOOLITTLE 12 9940 132 1453 MACDONALD 25 5532 200 결국 두개의 테이블에 하나의 데이타 파일가지고 데이타를 적재 시킨 것입니다.. 눈여겨 볼 것은 when 을 사용한 것인데... 이것으로...데이타 파일에 있는 마지막에서 5번째 컬럼의 데이타에서부터... 7번째 컬럼의 데이타까지 모두 proj 테이블의 projno 컬럼에 적재 시킨것이 보입니다... 데이타 적재 결과......... SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------- ---------- ---------- ---------- 1234 BAKER 9999 10 1234 JOKER 9999 10 5321 OTOOLE 9999 10 2134 FARMER 4555 20 2414 LITTLE 5634 20 6542 LEE 4532 10 4532 PERKINS 9999 10 1244 HUNT 3452 11 123 DOOLITTLE 9940 12 1453 MACDONALD 5532 25 10 개의 행이 선택되었습니다. SQL> select * from proj; EMPNO PROJNO ---------- ---------- 1234 101 1234 777 5321 321 2134 236 2414 236 6542 102 4532 40 1244 665 1234 102 1234 888 5321 55 2134 456 2414 456 6542 321 1244 133 1453 200 1234 103 1234 999 5321 40 2414 40 6542 14 1244 456 123 132 23 개의 행이 선택되었습니다. ulcase6.dat ================================================================================ load data infile 'ulcase6.dat' replace into table emp sorted indexes (empix) -----------> 인덱스로 정렬하여 적재합니다...직접경로일때만 사용가능.. (empno position(1:4), ename position(6:15), job position(17:25), mgr position(27:30) nullif mgr=blanks, --------> 널값이면 공백으로 넣는다..(공백은 널과 틀리다..) sal position(32:39) nullif sal=blanks, comm position(41:48) nullif comm=blanks, deptno position(50:51) nullif empno=blanks) 머...이정도 까지 하겠슴다... 아래는....오라클의 Bulletin 에 있는 내용입니다.. 참고하시기 바랍니다... IMAGE FILE 을 LOAD하기 ====================== 300,000 byte의 binary(image)file을 load하기 위해서는 아래와 같은 control file을 작성한다. options (bindsize=350000) load data infile image.gif "fix 60000" replace concatenate 5 into table xx (f1 raw(300000)) * bindsize option은 SQL*Loder가 보통 64K인 buffer를 더 크게 잡게 해 준다. * "fix 60000"은 o/s에 연관된 명령으로서 SQL*Loder가 data file에서 60,000 bytes를 읽게 하고, 이것을 하나의 physical record로 취급하게 한다. 이것은 보통 record delimiter로 사용되는 linefeed character를 찾지 않게 한다. * concatenate 5는 SQL*Loder가 다섯 개의 physical record로서 한개의 database record를 만드는 것을 말한다. 이 logical record가 database 안에 long raw column으로 직접 들어가게 된다. SQL*Loder가 한번에 file을 single record처럼( "fix 300000"을 사용해서) 읽게 할 수는 없다. 왜냐하면 이것은 file로 부터 읽어내는 record size에 대해서 operating system이 가지는 한계인 64K에 걸릴 수 있기 때문이다. 만약 이와 같은 작업을 할 경우에는 SQL*Loder-510 error가 발생된다. "fix n" option은 UNIX, PC 모두에서 사용될 수 있다. VMX에서는 "fix=n"즉 "fix=60000"이다. 300,000 byte을 한 record로 지정하였기 때문에 모든 image의 크기가 같기 전에는한 file에 하나의 image를 load할 수 있을 뿐이다. 이것은 원하는 image 마다 적절한 option을 가진 서로 다른 control file을 가지고 있어야 한다는 것이다. 그리고 실제 data보다 control file의 raw 길이를 명시해준 값이 크다면 남는 길이 만큼 SQL*Loder가 쓰레기 값을 채워 넣게 될 것이다. LOADER 를 통한 LONGRAW DATA 올리는 예제 ======================================= CREATE TABLE MYPICS (image long raw); Table created. LOAD DATA INFILE NX6.jpg "fix 65535" CONCATENATE 10 INTO TABLE MYPICS fields terminated by ':' (IMAGE raw (120000)) The command line would look like this sqlldr userid=scott/tiger control=image.ctl bindsize=250000 logfile=logimg 이미 Row 가 존재하는 Table 인 경우 Append 를 사용하여 추가한다. (IMAGE2.CTL) LOAD DATA INFILE NX6.jpg "fix 65535" APPEND CONCATENATE 10 INTO TABLE MYPICS fields terminated by ':' (IMAGE raw (120000)) sqlldr userid=scott/tiger control=image2.ctl bindsize=250000 log=log2imp ================================================================== SQL*LOADER(8i) variable size field를 여러 table에 load하기 (FILLER) ================================================================== SQL*LOADER 에서 variable length record와 variable size field를 가진 data file 을 여러 table에 load하는 방법을 소개하고자 한다. ( 8i new feature인 FILLER 절 사용) SQL*LOADER SYNTAX ------------------ 여러 table에 load하고자 할때에는 control file에 아래와 같이 하면 된다. ... INTO TABLE emp ... INTO TABLE emp1 ... fixed length field을 가진 data file을 여러 table에 같은 data을 load하고자 한다면 아래와 같다. ... INTO TABLE emp (empno POSITION(1:4) INTEGER EXTERNAL, ... INTO TABLE emp1 (empno POSITION(1:4) INTEGER EXTERNAL, ... 위와 같이 양쪽 table의 empno field에 각각의 load할 data로부터 1-4까지를 load 할수 있다. 그러나 field의 길이가 가변적이라면 위와 같이 POSITION절을 각 field에 사용할 수 없다. 예제 1> create table one ( field_1 varchar2(20), field_2 varchar2(20), empno varchar(10) ); create table two ( field_3 varchar2(20), empno varchar(10) ); load할 record가 comma로 나누어지며 길이가 가변적이라고 가정하자. << data.txt >> - load할 data file "this is field 1","this is field 2",12345678,"this is field 4" << test.ctl >> - control file load data infile 'data.txt' discardfile 'discard.txt' into table one replace fields terminated by "," optionally enclosed by '"' ( field_1, field_2, empno ) into table two replace fields terminated by "," optionally enclosed by '"' ( field_3, dummy1 filler position(1), dummy2 filler, empno ) dummy1 field는 filler로 선언되었다. filler로 선언하면 table에 load하지 않는다. two라는 table에는 dummy1이라는 field는 없으며 position(1)은 current record의 처음부터 시작해서 첫번째 field을 dummy1 filler item에 load한다는 것을 말한다. 그리고 두번째 field을 dummy2 filler item에 load한다. 세번째 field인, one이라는 table에 load되었던 employee number는 two라는 table에도 load되는 것이다, << 실행 >> $sqlload scott/tiger control=test.ctl data=data.txt log=test.log bindsize=300000 $sqlplus scott/tiger SQL> select * from one; FIELD_1 FIELD_2 EMPNO -------------------- -------------------- ---------- this is field 1 this is field 2 12345678 SQL> select * from two; FIELD_3 EMPNO -------------------- ---------- this is field 4 12345678 예제 2> create table testA (c1 number, c2 varchar2(10), c3 varchar2(10)); << data1.txt >> - load할 data file 7782,SALES,CLARK 7839,MKTG,MILLER 7934,DEV,JONES << test1.ctl >> LOAD DATA INFILE 'data1.txt' INTO TABLE testA REPLACE FIELDS TERMINATED BY "," ( c1 INTEGER EXTERNAL, c2 FILLER CHAR, c3 CHAR ) << 실행 >> $ sqlload scott/tiger control=test1.ctl data=data1.txt log=test1.log $ sqlplus scott/tiger SQL> select * from testA; C1 C2 C3 ---------- ---------- ---------- 7782 CLARK 7839 MILLER 7934 JONES 아~~ 머...퍼서 하고..이미 만들어진 예제로 했지만... 이것도 정말 눈알 빠지것슴다...헐헐~~ }}} ---- 와... 대단하시네요 정말 많은 도움되었습니다 좋은 자료 감사합니다^^ -- 조건희 2017-04-02 22:26:01 ---- 와... 대단하시네요. 이 글에 댓글을 달다니요. 2001년인가? 그쯤에 쓴 글인거 같은데요...ㅎ -- 이재학 2017-04-02 23:30:27 ---- 저도 도움 많이 받고 있습니다! -- 우병일 2017-04-06 19:42:26 ---- 잘 읽고 갑니다~~~ -- 마루 2017-08-11 15:10:43 ---- 정말 고마운 자료 입니다. 퍼갑니다. -- 이진규 2018-02-08 21:04:20 ---- 잘 읽고 가요 잘 정리되어있어 도움이 많이 되었습니다 -- 이수 2022-07-10 22:43:11