Oracle通过定时任务+dblink+存储过程传数据到中间库

--- 1.先看看有没有 放临时表 的目录,没有创建下:或者改放其他目录
cd /usr/local/oracle/oradata

--- 2.将目录所有者换成oracle
chown -R oracle /usr/local/oracle/

--- 3.切换oracle用户,并管理员身份进入
su - oracle
sqlplus / as sysdba
--- 4.创建用户
create user middle_user identified by middle_user;

--- 5.创建表空间
create tablespace ts_middle_user datafile '/usr/local/oracle/oradata/middle_user_data.dbf' size 6000M autoextend on;
 
--- 6.用户关联表空间
alter user middle_user default tablespace ts_middle_user;

--- 7.给用户访问授权
grant create session,create table,create view,create sequence,unlimited tablespace,connect,resource,dba to middle_user;
-- 8.用Oracle用户创建对应 monitor目录,存放每次执行完毕的结果文件,验证每次导入是否正确
cd /usr/local/oracle
mkdir monitor

-- 9.如果monitor目录不属于以下用户,请执行
---select * from all_directories
chown -R oracle:oinstall monitor/

-- 10.登录middle_user用户
sqlplus middle_user/middle_user
-- 11.登录middle_user用户后,创建目录MONITOR
create or replace directory monitor as '/usr/local/oracle/monitor';

--12. 在中间库执行建立link的脚本,远程链接(用户、密码、IP、端口、实例   以实际为准)
CREATE DATABASE LINK dblink_finance
CONNECT TO 用户 IDENTIFIED BY 密码
USING '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = IP地址)(PORT = 端口号))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = 实例名称)
)
)';

-- 13.验证是否已经关联 
select * from userinfo@dblink_finance;
-- 14.在中间库创建表结构(以实际为准) 
create table F_CREDIT_AMOUNTSETUP as
       select *
  from CREDIT_AMOUNTSETUP@dblink_finance;
  comment on table F_CREDIT_AMOUNTSETUP
  is 'aaaa详情表';
  comment on column F_CREDIT_AMOUNTSETUP.id
  is '主键';
comment on column F_CREDIT_AMOUNTSETUP.creditcode
  is 'aaaa编号';

  create table F_LOAN_DISCOUNTCONTRACTBILL
as select * from LOAN_DISCOUNTCONTRACTBILL@dblink_finance;
-- Add comments to the table 
comment on table F_LOAN_DISCOUNTCONTRACTBILL
  is 'bbbb表';
comment on column F_LOAN_DISCOUNTCONTRACTBILL.nofficeid
  is '办事处';
---15. 将指定数据的增量从主库推送到中间库
CREATE OR REPLACE PROCEDURE PROCEDURE_FINANCE_TO_MIDDLE
is ---将指定数据的增量从主库推送到中间库
  v_day_7 date;
  v_day_30 date;
  v_now varchar(30);
  V_FILE UTL_FILE.FILE_TYPE;
  V_INPUT CLOB;
BEGIN
select to_char(sysdate, 'yyyy-MM-dd_HH24:mi:ss') into v_now from dual;
V_FILE := UTL_FILE.FOPEN('MONITOR',
                         'FINANCE_TO_MIDDLE_' || v_now || '.txt',
                         'W');
select (sysdate - 7) into v_day_7 from dual;
select (sysdate - 30) into v_day_30 from dual;

	delete from F_CREDIT_AMOUNTSETUP;
	insert into F_CREDIT_AMOUNTSETUP
	  select * from CREDIT_AMOUNTSETUP@dblink_finance;
	commit;
	delete from F_LOAN_DISCOUNTCONTRACTBILL where DTEND > v_day_30;
	insert into F_LOAN_DISCOUNTCONTRACTBILL
	  select *
	    FROM LOAN_DISCOUNTCONTRACTBILL@dblink_finance a
	   where not exists
	   (select id from F_LOAN_DISCOUNTCONTRACTBILL b where a.id = b.id);
	commit;

---- 这里是对结果进行校验,如果输出的表对应值为0,则正常,否则数据丢失
FOR I IN (
          select diff || ' ' || 'F_CREDIT_AMOUNTSETUP' result
            from (select ((select count(*) as count1 from F_CREDIT_AMOUNTSETUP) -
                         (select count(*) as count2
                             from CREDIT_AMOUNTSETUP@dblink_finance)) as diff
                    from dual) a
          
          union all
          select diff || ' ' || 'F_LOAN_DISCOUNTCONTRACTBILL' result
            from (select ((select count(*) as count1
                             from F_LOAN_DISCOUNTCONTRACTBILL) -
                         (select count(*) as count2
                             from LOAN_DISCOUNTCONTRACTBILL@dblink_finance)) as diff
                    from dual) a
          ) LOOP
  UTL_FILE.PUT_LINE(V_FILE, I.RESULT);
END LOOP;
UTL_FILE.FCLOSE(V_FILE);
EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Exception happened,all data was rollback'); 
ROLLBACK;
END;
---16. 首先先执行一次,看看存储过程写的是否正确
--- 如果执行成功,会有success,并且会生成日志文件
exec PROCEDURE_FINANCE_TO_MIDDLE;

Oracle通过定时任务+dblink+存储过程传数据到中间库_第1张图片

--17.先生成定时任务
declare
    JOB_FINANCE_TO_MIDDLE number;  /*JOB_FINANCIAL_TO_MIDDLE:定时器名称*/
  BEGIN
    DBMS_JOB.SUBMIT(  
          JOB => JOB_FINANCE_TO_MIDDLE,  /*自动生成JOB_ID*/  
          WHAT => 'PROCEDURE_FINANCE_TO_MIDDLE;',  /*需要执行的存储过程名称或SQL语句*/  
          --NEXT_DATE => sysdate+3/(24*60),  /*初次执行时间-下一个3分钟*/  
         --INTERVAL => 'trunc(sysdate,''mi'')+100/(24*60)' /*每隔100分钟执行一次*/
         INTERVAL => 'TRUNC(SYSDATE + 1) + (20*60+10)/(24*60)' /*每天晚上8点10分*/
       );  
   commit;
 end;


---18. 查询定时ID,比如找到对应的ID=23
SELECT * FROM user_jobs;

-- 19. 开启定时
begin
 dbms_job.run(23); --开启
 commit;
end;
---20. 如果遇到数据没有增量更新,也就是定时任务没有运行
select value from v$parameter where name like '%job_queue_processes%';

---21. 如果小的话,改成100,很可能是因为这个job值太小造成定时任务不运行  
alter system set job_queue_processes =100;

你可能感兴趣的:(Oracle)