External 테이블

  • oracle 9i r1 에서 처음도입
  • 운영체제의 파일을 마치 데이터베이스의 읽기 전ㅇ요 테이블인 것처럼 처리하도록 해준다.
  • 10g 이상에서는 데이터 로딩, 언로딩을 손쉽게 할 수 있는 툴로 사용된다.

SQLLDR 이 external 테이블보다 먼저선택되는 경우

  • 네트워크를 통해 데이터를 로드해야하는 경우(external테이블에서는 DB서버 내에 입력파일이 있어야 한다.)
  • 여러 사용자가 동일 external 테이블에 서로 다른 입력 파일을 동시에 처리해야 하는 경우

external 테이블이 SQLLDR보다 우선시되는 핵심기능

  • 복잡한 where 조건을 사용할 수 있다.(SQLLDR는 WHEN 절이 있으나 and식과 =식(,<,>,or,is null등은 안됨)만 사용할 수 있다.)
  • 데이터 병합(MERGE)을 할 수 있따.
  • 로드처리시에 external 테이블과 다른테이블을 조인할 수 있다.
  • Create table 또는 INSERT문 내에 ORDER BY문을 포함해서 데이터를 정렬할 수 있다.
  • INSERT를 사용해서 여러 테이블에 쉽게 입력할 수 있다.(SQLLDR도 가능하나 복잡하다.)
  • SQL만 알고있으면 사용하기 쉽다.(SQLLDR은 복잡하다)

# External 테이블 설정

h5. TEST
h4. control 파일(demo1.ctl) 생성
{code:sql}
LOAD DATA
INFILE *
INTO TABLE dept
FIELDS TERMINATED BY ','
(
deptno
,dname
,loc
)
BEGINDATA
10,ACCOUNTING,NEW YORK
20,RESEARCH,DALLAS
30,SALES,CHICAGO
40,OPERATIONS,BOSTON
{code}
h4. external테이블을 위한 CREATE TABLE문을 생성
{code:sql}
C:\book\ch15>sqlldr hun/imsi00 demo1.ctl external_table=generate_only

SQL*Loader: Release 11.2.0.3.0 - Production on 금 11월 30 19:01:17 2012

Copyright © 1982, 2011, Oracle and/or its affiliates. All rights reserved

C:\book\ch15>


external_table 파라미터
1. NOT_USED : 기본값
2. EXECUTER : SQLLDR가 SQL INSERT문을 생성하지 않고 실행
3. GENEATE_ONLY  : 이값은 SQLLDR가 데이터를 실제로 로드하지 않으나 로그파일  실행 할 수있는 SQL DDL과 DML문을 생성한다.
|
|h4. demo1.log file
{code:sql}

SQL*Loader: Release 11.2.0.3.0 - Production on 금 11월 30 19:13:56 2012

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved

제어 파일:    demo1.ctl
데이터 파일:    demo1.ctl
  부적합한 파일:     demo1.bad
  폐기 파일:    지정 사항 없음

 (모든 폐기된 레코드 허용)

로드할 건수: ALL
생략 건수:  0
허용 오류수:  50
계속:    지정 사항 없음
사용된 경로:      외부 테이블

테이블 DEPT, 로드되었습니다 개개의 논리 레코드로부터
이 테이블에 적당한 Insert 옵션: INSERT

   열 이름                        위치    Len   Term Encl 데이터유형
------------------------------ ---------- ----- ---- ---- ------------------
DEPTNO                              FIRST     *   ,       CHARACTER         
DNAME                                NEXT     *   ,       CHARACTER         
LOC                                  NEXT     *   ,       CHARACTER         



파일에 CREATE DIRECTORY 명령문이 필요함                         --SQLLDR는 external 테이블 스크립트를 생성하는 동안 데이터베이스에
--------------------------------------------------------------  --접속해서이미 존재하는 디렉토리가 적합한디 아닌지를 보기위해 
CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000 AS 'C:\book\ch15'   --데이터 딕셔너리를 조회
 																																--적합한 디렉토리가 없을때 CREATE DIRECTORY 문을 생성하고
                                                                                                                                            
외부 테이블의 CREATE TABLE 문:                                  --CREATE TABLE문을 생성한다.
--------------------------------------------------------------                                     
CREATE TABLE "SYS_SQLLDR_X_EXT_DEPT"                            
(                                                                   
  "DEPTNO" NUMBER(2),                                           -- 데이터 타입은 DD에서 가져온 것
  "DNAME" VARCHAR2(14),                                         
  "LOC" VARCHAR2(13)                                            
)                                                               
ORGANIZATION external 																					-- organization external절은 오라클에게 일반 테이블이 아님을 알려준다.
  DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
  ACCESS PARAMETERS 																						-- 데이터베이스에서 입력 파일을 처리하는 방법을 설명
  (
    RECORDS DELIMITED BY NEWLINE CHARACTERSET KO16MSWIN949      -- SQLLDR에서와 같이 레코드는 기본값에 의해 개행문자로 종료된다.
    BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'demo1.bad'						-- BADFILE : 실패처리된 레코드를 기록하는파일
    LOGFILE 'demo1.log_xt'                                      
    READSIZE 1048576																						-- 입력데이터 파일을 읽기위해 사용하는 기본버퍼
    SKIP 10																											-- 입력파일내의 건너뛰어야 할 레코드 수(INFILE*)
    FIELDS TERMINATED BY "," LDRTRIM                            -- ,구분
    REJECT ROWS WITH ALL NULL FIELDS 														-- 로우전체가 비어있을경우 external 테이블에 로드되지 않고 bad파일에 로그를 남긴다.
    (
      "DEPTNO" CHAR(255)
        TERMINATED BY ",",
      "DNAME" CHAR(255)
        TERMINATED BY ",",
      "LOC" CHAR(255)
        TERMINATED BY ","
    )
  )
  location 																											-- 대상파일이름을 오라클에 알려주는 역할
  (
    'demo1.ctl'
  )
)REJECT LIMIT UNLIMITED


INSERT 문이 내부 테이블 로드에 사용됨:
------------------------------------------------------------------------
INSERT /*+ append */ INTO DEPT 
(
  DEPTNO,
  DNAME,
  LOC
)
SELECT 
  "DEPTNO",
  "DNAME",
  "LOC"
FROM "SYS_SQLLDR_X_EXT_DEPT"


이전 명령문이 생성한 객체를 정리하기 위한 명령문:               -- 로그파일에서 로그가 완료된 후 SQLLDR가 생성한 객체를 제거하는데 사용되는 명령
------------------------------------------------------------------------
DROP TABLE "SYS_SQLLDR_X_EXT_DEPT"
DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000



금 11월 30 19:13:56 2012에 실행 개시
금 11월 30 19:13:56 2012에 실행 종료

경과 시간:        00:00:00.03
CPU 시간:         00:00:00.00

# 오류 처리

  • BADFILE로 확인

# EXternal 테이블을 사용해서 다른 파일을 로드

  • 하나의 파일명 demo1.ctl로만 데이터를 로딩했었다가 demo2.ctl로 데이터로드를 하게 될 경우
{code:sql}
alter table SYS_SQLLDR_X_EXT_DEPT
location('demo2.dat');
{code}

# External 테이블의 다중 사용자 문제

  • 다중사용자 문제는 실제로 많이 발생하지는 않지만, 두 세션 모두 동일 시간대에 location 변경을 할 가능성이 존재한다.
{code:sql}
RECORDS DELIMITED BY NEWLINE CHARACTERSET WE8IS08859P1
BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'demo1%p.bad' -- demo1[PID].bad 파일로 떨어짐
LOGFILE 'demo1.log_xt'
{code}
* %p : PID
* %a : 병렬 실행 서버 에이전트 ID ex)001,002,003

# External 테이블 정리

  • 오라클9i이상에서 SQLLDR의 대부분을 대체하는 새로운 기능
  • SQLLDR의 컨트롤 파일을 변환해서 사용하는기술, BAD파일을 통해 오류감지하고 처리하는기술및 다중사용자 문제를 알아보았다.