Ralph Kimball在他的
准备工作
在使用外部表之前,首先要建立DIRECTORY对象。同时给需要进行外部表操作的用户赋予适当的权限。
SQL> CREATE OR REPLACE DIRECTORY source_dir as '/home/oracle/backup';
Directory created
SQL> CREATE OR REPLACE DIRECTORY target_dir as '/home/oracle/backup/target';
Directory created
SQL> CREATE OR REPLACE DIRECTORY log_dir as '/home/oracle/backup/log';
Directory created
SQL> grant read on directory source_dir to test;
授权成功.
SQL> grant read on directory target_dir to test;
授权成功.
SQL> grant read on directory log_dir to test;
授权成功.
SQL>grant connect, dba to test identified by test;
授权成功.
数据抽取— ORACLE_LOADER
平文件的数据源一般有两种格式:定长格式或者分隔符格式,ORACLE_LOADER对这两种格式都提供支持。如果是分隔符格式的源文件,使用关键字FIELDS TERMINATED BY指定分隔符;如果是定长格式文件,使用关键字POSITION指定数据列的位置。
$ pwd
/home/oracle/backup
$ ls
target log product1.dat
$ cat product1.dat
1,Bicycle,JiangSu
2,Camps,ZheJiang
3,Wearings,SiChuan
4,Gloves,SiChuan
5,Food,YunNan
6,Shoes,NULL
$
使用EXTERNAL ORGANIZATIONAL关键字构建外部表,注意DRIVER关键字指定了ORACLE_LOADER驱动;DEFAULT DIRECTORY子句指定了默认的操作目录;在ACCESS PARAMETERS子句中定义了分隔符、坏文件、LOG文件;LOCATION关键字指定了外部表依存的数据文件,如果存在多个文件,使用逗号分隔。
SQL> ed
Wrote file afiedt.buf
CREATE TABLE stenny_ext_product
(product_id NUMBER(4),
product_name VARCHAR2(20),
location VARCHAR2(25)
)
ORGANIZATION EXTERNAL
(
TYPE ORACLE_LOADER
DEFAULT DIRECTORY source_dir
ACCESS PARAMETERS
(
records delimited by newline
badfile log_dir:'bad_product.dat'
logfile log_dir:'product.log'
fields terminated by ','
missing field values are null
( product_id, product_name, location )
)
LOCATION ('product1.dat')
)
REJECT LIMIT UNLIMITED
SQL> /
Table created
SQL> select * from stennY_ext_product;
PRODUCT_ID PRODUCT_NAME LOCATION
---------- -------------------- -------------------------
1 Bicycle JiangSu
2 Camps ZheJiang
3 Wearings SiChuan
4 Gloves SiChuan
5 Food YunNan
6 Shoes NULL
6 rows selected
SQL>
经过上面的步骤,我们将数据库之外的一个平文件通过访问驱动程序ORACLE_LOADER与一个数据库表STENNY_EXT_PRODUCT建立了映射关系。我们对这个外部表可以进行排序,表连接等只读操作。
SQL> ed
Wrote file afiedt.buf
SQL> /
Table created
SQL> select * from tgt_product;
PRODUCT_ID PRODUCT_NAME LOC_ID
---------- -------------------- ----------
1 Bicycle 1
2 Camps 2
3 Wearings 3
4 Gloves 3
5 Food 4
SQL>
同时,在target_dir目录下可以看到创建的TGT_PRODUCT.DMP文件,该文件可以被加载到真正的目标数据库,但是必须使用ORACLE_DATAPUMP访问驱动程序。
定时调度 – DBMS_SCHEDULER
首先我们将使用proc_file_watcher存储过程每5分钟对某一个目录进行扫描等待文件。如果文件存在,调用proc_txn_product对文件进行处理,否则睡眠5分钟。这个文件扫描过程在周二早上4点钟被激活,如果超过8点文件还是没有到,可以抛出用户异常或者调用UTL_SMTP包发邮件通知相关责任人。
create or replace procedure proc_file_watcher is
v_exists boolean;
v_file_length number;
v_blocksize number;
begin
<
if to_char(sysdate, 'hh24') >= '08' then
--³¬Ê±£¬¿ÉÒÔµ÷ÓÃUTL_SMTP
null;
else
utl_file.fgetattr('SOURCE_DIR',
'product1.dat',
v_exists,
v_file_length,
v_blocksize);
if v_exists then
dbms_output.put_line('File there!');
proc_txn_product;
else
dbms_output.put_line('404 Error');
dbms_lock.sleep(300);
goto L_sleeping_child;
end if;
end if;
end proc_file_watcher;
现在,我们只需要将这个文件扫描程序加入调度,每个周二早上4点钟开始运行即可。
--创建程序
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM(program_name => 'TEST.STP_PROC_FILE_WATCHER',
program_action => 'TEST.PROC_FILE_WATCHER',
program_type => 'STORED_PROCEDURE',
comments => 'Firing the ETL process if file arrives',
enabled => TRUE);
END;
BEGIN
SYS.DBMS_SCHEDULER.CREATE_SCHEDULE(repeat_interval => 'FREQ=WEEKLY;BYDAY=TUE;BYHOUR=8;BYMINUTE=0;BYSECOND=0',
start_date => to_timestamp_tz('2011-01-27 US/Central',
'YYYY-MM-DD TZR'),
comments => 'Tuesday AM Schedule',
schedule_name => '"TEST"."SCS_TXN_PROD"');
END;
BEGIN
SYS.DBMS_SCHEDULER.CREATE_JOB(job_name => 'TEST.SCJ_TXN_PROD',
program_name => 'TEST.STP_PROC_FILE_WATCHER',
schedule_name => 'TEST.SCS_TXN_PROD',
comments => 'Start the ETL process on Tuesday',
auto_drop => FALSE,
enabled => TRUE);
END;
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9399028/viewspace-686396/ ,如需转载,请注明出处,否则将追究法律责任。