执行时 打印:dbms_output.put_line ( ‘11111111111’ );
拼接的动态sql 可以用 execute immediate 后面 加拼接的语句,下面有类似;
可以定义变量,然后 使用 into + 变量来使用;
异常 可以使用:EXCEPTION WHEN others THEN
删除7天以前的备份表,创建一个当天新的备份表(DAILY_BACKUP)
--1.建立执行错误日志表
CREATE TABLE SYS_PUB_PROC_ERR_LOG (
LOG_ID NUMBER,
MODULE_NAME VARCHAR2 ( 100 ),
PROC_NAME VARCHAR2 ( 100 ),
TIME DATE,
SQL_CODE VARCHAR2 ( 50 ),
SQL_ERRM VARCHAR2 ( 100 ),
ERR_CONTENT VARCHAR2 ( 500 )
);
COMMENT ON COLUMN SYS_PUB_PROC_ERR_LOG.LOG_ID IS '主键';
COMMENT ON COLUMN SYS_PUB_PROC_ERR_LOG.MODULE_NAME IS '模块名称';
COMMENT ON COLUMN SYS_PUB_PROC_ERR_LOG.PROC_NAME IS '存储过程名称';
COMMENT ON COLUMN SYS_PUB_PROC_ERR_LOG.TIME IS '时间';
COMMENT ON COLUMN SYS_PUB_PROC_ERR_LOG.SQL_CODE IS 'SQLCODE';
COMMENT ON COLUMN SYS_PUB_PROC_ERR_LOG.SQL_ERRM IS 'SQLERRM';
COMMENT ON COLUMN SYS_PUB_PROC_ERR_LOG.ERR_CONTENT IS '报错的具体行';
--2.表主键的序列
CREATE sequence SEQ_RECORD_PROC_ERR minvalue 1 maxvalue 9999999999999999999999999999 START WITH 21 INCREMENT BY 1 cache 20;
--3.通用记录错误存储过程
CREATE
OR REPLACE PROCEDURE record_proc_err_log ( module_name VARCHAR2, proc_name VARCHAR2, v_SQLCODE VARCHAR2, v_SQLERRM VARCHAR2, v_err_line VARCHAR2 ) IS PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO sys_pub_proc_err_log ( log_id, module_name, proc_name, time, sql_code, sql_errm, err_content )
VALUES
( seq_record_proc_err.nextval, module_name, proc_name, SYSDATE, v_SQLCODE, v_SQLERRM, v_err_line );
commit;
END record_proc_err_log;
create or replace PROCEDURE DAILY_BACKUP AS
v_now VARCHAR2(8);
v_seven varchar2(8);
v_7tab1_has int;
v_table_name_1 CONSTANT VARCHAR2(50) := 'eval_sum_newest_info_bak_';
BEGIN
--获取当天日期
select to_char(SYSDATE, 'YYYYMMDD')
into v_now
from dual;
--获取7天前日期
select to_char(TRUNC(SYSDATE -7), 'YYYYMMDD')
into v_seven
from dual;
--删除7天前的表
select count(1) into v_7tab1_has from user_tables where TABLE_NAME = upper(v_table_name_1 || v_seven);
if v_7tab1_has=1 then
--如果存在,则执行drop table (drop 是不能回滚的)
dbms_output.put_line ( '删除的表, '|| v_table_name_1 || v_seven );
execute immediate 'drop table '|| v_table_name_1 || v_seven;
end if;
--创建当天的数据备份
dbms_output.put_line ( 'CREATE TABLE ' || v_table_name_1 || v_now || ' AS SELECT * FROM eval_sum_newest_info');
EXECUTE IMMEDIATE 'CREATE TABLE ' || v_table_name_1 || v_now || ' AS SELECT * FROM eval_sum_newest_info';
COMMIT;
EXCEPTION
WHEN others THEN
record_proc_err_log ( 'process', 'data', SQLCODE, SQLERRM, substr( dbms_utility.format_error_backtrace, 1, 400 ) );
ROLLBACK;
END DAILY_BACKUP;
-- 创建存储过程 先调用处理备份表,然后 处理重复数据
CREATE
OR REPLACE PROCEDURE PROCESS_DUPLICATE_DATA IS -- 定义变量
row1 NUMBER;
row2 NUMBER;
v_now VARCHAR2 ( 8 );
v_table_name_1 CONSTANT VARCHAR2 ( 50 ) := 'eval_sum_newest_info_bak_';
BEGIN--获取当天日期
SELECT
to_char( SYSDATE, 'YYYYMMDD' ) INTO v_now
FROM
dual;
-- 查看重复数据
SELECT
sum( count( * ) ) INTO row1
FROM
EVAL_SUM_NEWEST_INFO
GROUP BY
eval_basic_information_id,
eval_sum_risk_info_id,
risk_dept_id
HAVING
count( * ) > 1;
IF
( row1 > 0 ) THEN-- 如果存在重复数据,则删除存在的备份表(7天),创建新的备份表
DAILY_BACKUP ( );
BEGIN-- 查询 备份表 是否和 原表一致(说明备份数据完整,可以处理重复数据了)
dbms_output.put_line ( '创建的表: ' || v_table_name_1 || v_now );
dbms_output.put_line ( 'SELECT count( * ) FROM ( SELECT * FROM EVAL_SUM_NEWEST_INFO MINUS SELECT * FROM ' || v_table_name_1 || v_now || ' ) t' );
-- 把拼接的语句 作比较,然后把数量 赋值给row2
execute IMMEDIATE 'SELECT count( * ) FROM ( SELECT * FROM EVAL_SUM_NEWEST_INFO MINUS SELECT * FROM ' || v_table_name_1 || v_now || ' ) t' INTO row2;
IF
( row2 > 0 ) THEN-- 这里是不一致(不做清理数据)
dbms_output.put_line ( '00000000000' );
ELSE dbms_output.put_line ( '11111111111' );
-- 删除重复数据
execute IMMEDIATE 'delete EVAL_SUM_NEWEST_INFO WHERE id in
(
select id from (
select t.*, row_number() over(partition by eval_basic_information_id,eval_sum_risk_info_id,risk_dept_id order by id ) rn from EVAL_SUM_NEWEST_INFO t
) where rn > 1
)';
END IF;
COMMIT;
EXCEPTION
WHEN others THEN
record_proc_err_log ( 'process', 'data', SQLCODE, SQLERRM, substr( dbms_utility.format_error_backtrace, 1, 400 ) );
ROLLBACK;
END;
END IF;
END;
-- 1.创建任务
declare duplicate_data_job number; --duplicate_data_job定时任务名称
begin
sys.dbms_job.submit(
duplicate_data_job, --任务名称
'PROCESS_DUPLICATE_DATA;',--执行的存储过程
sysdate,--执行时间
--'TRUNC(SYSDATE + 1) + (15*60+52)/(24*60)'--下次执行时间 11:55
'TRUNC(SYSDATE + 1)' --每天午夜12点
--'sysdate+2/(24*60)' --每2分钟执行一次
);
COMMIT;
end;
-- 以下不需要执行,一些sql做参考 的查看命令
-- 查看定时任务
SELECT * FROM user_jobs;
-- 手动启动,执行完后再执行3 查看,如果next_date 没有自动变成明天这个时间的话,那么就需要配置下5
BEGIN
dbms_job.run(25);
END;
-- *********
--在 90上试验之后是可以的 (通过查阅资料发现原来有一个参数job_queue_processes数字为0是定时任务都不会执行)
alter system set job_queue_processes =10;
-- *********
-- 删除存储过程
DROP PROCEDURE PROCESS_DUPLICATE_DATA;
-- 停止任务
BEGIN
dbms_job.broken(25,true);
END;
-- 删除任务
begin
dbms_job.remove(45);--ALL_JOBS.job的值
end;
-- 1.创建表 参数:表名,建表语句
CREATE
OR REPLACE PROCEDURE PROCESS_DUPLICATE_DATA2 IS row1 NUMBER;
row2 NUMBER;
BEGIN
SELECT
count( table_name ) INTO row1
FROM
all_tables
WHERE
table_name = upper( 'eval_sum_newest_info_bak' );
IF
( row1 = 1 ) THEN-- 删除存在的备份表,创建新的备份表
--execute immediate 'drop table EVAL_SUM_NEWEST_INFO_BAK';
--execute immediate 'create table eval_sum_newest_info_bak as select * from eval_sum_newest_info';
dbms_output.put_line ( '00000000000' );
BEGIN
SELECT
count( * ) INTO row2
FROM
( SELECT * FROM EVAL_SUM_NEWEST_INFO MINUS SELECT * FROM EVAL_SUM_NEWEST_INFO_BAK ) t;
IF
( row2 > 0 ) THEN
dbms_output.put_line ( '11111111111' );
ELSE dbms_output.put_line ( '222222222222' );
END IF;
END;
ELSE dbms_output.put_line ( '33333333333' );
END IF;
END;
CREATE
OR REPLACE PROCEDURE test IS row1 NUMBER;--第一个游标
row2 NUMBER;--第二个游标
BEGIN
BEGIN
SELECT
count( table_name ) INTO row1
FROM
all_tables
WHERE
table_name = upper( 'eval_sum_newest_info_bak' );
IF
( row1 = 1 ) THEN-- 删除存在的备份表,创建新的备份表
--execute immediate 'drop table EVAL_SUM_NEWEST_INFO_BAK';
--execute immediate 'create table eval_sum_newest_info_bak as select * from eval_sum_newest_info';
dbms_output.put_line ( '0000000000' );
ELSE dbms_output.put_line ( '33333333333' );
END IF;
END;
--分开
BEGIN
SELECT
count( * ) INTO row2
FROM
( SELECT * FROM EVAL_SUM_NEWEST_INFO MINUS SELECT * FROM EVAL_SUM_NEWEST_INFO_BAK ) t;
IF
( row2 > 0 ) THEN
dbms_output.put_line ( '11111111111' );
ELSE dbms_output.put_line ( '222222222222' );
END IF;
END;
END;