SQL*Loader之CASE4

CASE4

1. SQL脚本

[oracle@node3 ulcase]$ cat ulcase4.sql

set termout off

rem host write sys$output "Building case 4 demonstration tables.  Please wait"

drop table emp;

create table emp
       (empno number(4) not null,
        ename char(10),
        job char(9),
        mgr number(4),
        hiredate date,
        sal number(7,2),
        comm number(7,2),
        deptno number(2));

create unique index empix on emp(empno);

exit

2. 控制文件

[oracle@node3 ulcase]$ cat ulcase4.ctl

-- NAME
-- ulcase4.ctl - SQL*Loader Case Study 4: Loading Combined Physical Records
--
-- DESCRIPTION
-- This case study demonstrates the following:
-- Combining multiple physical records to form one logical
-- record with CONTINUEIF.
--
-- Inserting negative numbers.
--
-- Using REPLACE to indicate that the table should be emptied
-- before the new data is inserted.
--
-- Specifying a discard file in the control file using DISCARDFILE.
--
-- Specifying a maximum number of discards using DISCARDMAX.
--
-- Rejecting records due to duplicate values in a unique index
-- or due to invalid data values.
--
-- TO RUN THIS CASE STUDY:
-- 1. Before executing this control file, log in to SQL*Plus as
--    scott/tiger. Enter @ulcase4 to execute the SQL script for
--    this case study. This prepares and populates tables and
--    then returns you to the system prompt.
--
-- 2. At the system prompt, invoke the case study as follows:
-- sqlldr USERID=scott/tiger CONTROL=ulcase4.ctl LOG=ulcase4.log
--
-- NOTES ABOUT THIS CONTROL FILE
-- DISCARDFILE specifies a discard file named ulcase4.dsc.
--
-- DISCARDMAX specifies a maximum of 999 discards allowed before
-- terminating the run. For all practical purposes, this allows
-- all discards for this test case. In real-world situations,
-- there may well be more than 999 discarded records.
--
-- REPLACE specifies that if there is data in the table being loaded,
-- then SQL*Loader should delete that data before loading new data.
--
-- CONTINUEIF specifies that if an asterisk is found in column 1
-- of the current record, then the next physical record after that
-- record should be appended to it from the logical record. Note that
-- column 1 in each physical record should then contain either an
-- asterisk or a nondata value.
--
-- The data file (ulcase4.dat) for this case study shows asterisks
-- in the first position and, though not visible, a newline character
-- is in position 20. Note that clark's commission is -10, and
-- SQL*Loader loads the value, converting it to a negative number.
--
-- The resulting log file will show that the last two records are
-- rejected, given two assumptions. If a unique index is created on
-- column empno, then the record for chin will be rejected because
-- his empno is identical to chan's. If empno is defined as NOT NULL,
-- then chen's record will be rejected because it has no value for
-- empno.

--
LOAD DATA
INFILE "ulcase4.dat"
DISCARDFILE "ulcase4.dsc"
DISCARDMAX 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)

3. 数据文件

[oracle@node3 ulcase]$ cat ulcase4.dat

*7782 CLARK      MA
 NAGER   7839  2572.50   -10    2512-NOV-85
*7839 KING       PR
 ESIDENT       5500.00          2505-APR-83
*7934 MILLER     CL
 ERK     7782   920.00          2508-MAY-80
*7566 JONES      MA
 NAGER   7839  3123.75          2517-JUL-85
*7499 ALLEN      SA
 LESMAN  7698  1600.00   300.00 25 3-JUN-84
*7654 MARTIN     SA
 LESMAN  7698  1312.50  1400.00 2521-DEC-85
*7658 CHAN       AN
 ALYST   7566  3450.00          2516-FEB-84
*     CHEN       AN
 ALYST   7566  3450.00          2516-FEB-84
*7658 CHIN       AN
 ALYST   7566  3450.00          2516-FEB-84

执行后结果:

[oracle@node3 ulcase]$ sqlplus scott/tiger @ulcase4.sql

[oracle@node3 ulcase]$ sqlldr userid=scott/tiger control=ulcase4.ctl

SQL> select * from emp;

EMPNO ENAME  JOB       MGR   HIREDATE  SAL     COMM DEPTNO
----- ------ --------- ----- --------- ------- ----- ------
 7782 CLARK  MANAGER   7839  12-NOV-85 2573     -10  25

 7839 KING   PRESIDENT       05-APR-83 5500          25

 7934 MILLER CLERK      7782 08-MAY-80  920          25
  
 7566 JONES  MANAGER    7839 17-JUL-85 3124          25 

7499 ALLEN SALESMAN 7698 03-JUN-84 1600 300 25 7654 MARTIN SALESMAN 7698 21-DEC-85 1313 1400 25 7658 CHAN ANALYST 7566 16-FEB-84 3450 25 7 rows selected.

不难发现,数据文件中有9条数据,但是最后插入的只有7条数据。执行sqlldr时,如果没有显性指定日志文件名,则会隐性创建一个同名日志,后缀为.log。

我们不妨来看看日志文件的记录

[oracle@node3 ulcase]$ cat ulcase4.log 

SQL*Loader: Release 11.2.0.1.0 - Production on Thu Sep 18 23:41:36 2014

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

Control File:   ulcase4.ctl
Data File:      ulcase4.dat
  Bad File:     ulcase4.bad
  Discard File: ulcase4.dsc 
 (Allow 999 discards)

Number to load: ALL
Number to skip: 0
Errors allowed: 50
Bind array:     64 rows, maximum of 256000 bytes
Continuation:   1:1 = 0X2a(character '*'), in current physical record
Path used:      Conventional

Table EMP, loaded from every logical record.
Insert option in effect for this table: REPLACE

   Column Name                  Position   Len  Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
EMPNO                                 1:4     4           CHARACTER            
ENAME                                6:15    10           CHARACTER            
JOB                                 17:25     9           CHARACTER            
MGR                                 27:30     4           CHARACTER            
SAL                                 32:39     8           CHARACTER            
COMM                                41:48     8           CHARACTER            
DEPTNO                              50:51     2           CHARACTER            
HIREDATE                            52:60     9           CHARACTER            

Record 8: Rejected - Error on table EMP, column EMPNO.
ORA-01400: cannot insert NULL into ("SCOTT"."EMP"."EMPNO")

Record 9: Rejected - Error on table EMP.
ORA-00001: unique constraint (SCOTT.EMPIX) violated


Table EMP:
  7 Rows successfully loaded.
  2 Rows not loaded due to data errors.
  0 Rows not loaded because all WHEN clauses were failed.
  0 Rows not loaded because all fields were null.


Space allocated for bind array:                   4608 bytes(64 rows)
Read   buffer bytes: 1048576

Total logical records skipped:          0
Total logical records read:             9
Total logical records rejected:         2
Total logical records discarded:        0

Run began on Thu Sep 18 23:41:36 2014
Run ended on Thu Sep 18 23:41:36 2014

Elapsed time was:     00:00:00.29
CPU time was:         00:00:00.07

可见,第8行记录因违法empno的非空约束,第9行记录因违反唯一索引而抛弃。

抛弃的两条记录可在控制文件指定的DISCARDFILE "ulcase4.dsc"中找到

[oracle@node3 ulcase]$ cat ulcase4.bad

*     CHEN       AN
 ALYST   7566  3450.00          2516-FEB-84
*7658 CHIN       AN
 ALYST   7566  3450.00          2516-FEB-84

 总结:在本例中,

      1> 指定了discard file,discardmax指定丢弃到该文件的记录最多为999条。

      2> The REPLACE option executes a SQL DELETE FROM TABLE statement. All rows in the table are deleted and the new data is loaded. The REPLACE method is a table replacement, not a replacement of individual rows. SQL*Loader does not update existing records, even if they have null columns. --replace会删除所有数据,而不会更新既存的数据。    

posted @ 2014-09-19 11:34  iVictor  阅读(444)  评论(0编辑  收藏  举报