需求描述
我们有一个 Oracle 的存储过程, 里面是每个月需要执行一下, 生成报表, 然后发送给业务部门, 这一个功能我们有实现在系统的前台界面 (如图 1-1), 但是客户每次都不点重新生成, 导致导出报表时报出异常 (如图 1-2).
图 1-1
图 1-2
问题分析
既然它是一个存储过程, 我们定位到了该请求相对应的存储过程, 如下图所示
图 1-3
我们看它的参数, 只有两个, 一个是开始时间, 表示当月的开始时间, 一个时结束时间, 表示当月结束时间, 我们只要在脚本执行它的时候传一个参数给它就可以.
问题解决
想要解决这个问题, 我的想法是这样, 把需要处理的所有逻辑写在脚本里, 然后设定一个 Crontab, 通过定时任务去执行.
一, 首先看单纯在 plsql 是如何调用这个存储过程的, 我通过定义一个 startdate 和 enddate, 然后通过 Oracle 的时间函数 last_day 计算出每月的最后一天, 开始的第一天我是直接在月份拼接了'01', 至于为什么 add_months(sysdate,-1) 要 - 1, 是因为当月的一般执行上个月的.
- declare
- startdate varchar2(8);
- enddate varchar2(8);
- begin
- select to_char(add_months(sysdate,-1),'YYYYMM')||'01'
- into startdate from dual;
- select to_char(last_day(add_months(sysdate,-1)),'YYYYMMDD')
- into enddate from dual;
- proc_high_settle_rep_month(startdate,enddate);
- end;
- /
二, 把上述的逻辑写入到 sh 脚本中, 我们在相关的路径新建一个文件 call_proc_high_settle_rep_month.sh, 通过执行 sqlplus, 然后去执行上述的内容
脚本内容如下:
其中 sqlplus 中的 zh 表示数据库账户名,* 表示密码, zh10g 表示数据库实例名, 是你配置在 tnsnames.ora 的连接名.
- . /issdata/application/appiss/.profile
- echo "get begging"
- date
- sqlplus zh/*****@zh10g <<!
- declare
- startdate varchar2(20);
- enddate varchar2(20);
- begin
- select to_char(add_months(sysdate,-1),'YYYYMM')||'01'
- into startdate from dual;
- select to_char(last_day(add_months(sysdate,-1)),'YYYYMMDD')
- into enddate from dual;
- proc_high_settle_rep_month(startdate,enddate);
- end;
- /
- !
- echo "get Finished"
三, 手工执行了这个脚本, 发现没错误, 可以执行.
sh call_proc_high_settle_rep_month.sh
我们添加到 crontab 中, crontab -e 进入 crontab 编辑, 注意脚本要写绝对路径
08 23 5 * * sh /tmp/call_proc_high_settle_rep_month.sh
上述的 crontab 就代表每月的 5 号的 23:08 分就会执行这个命令.
上面的 08 23 5 * * 依次代表分, 时, 日, 月, 周.
至此, 整个程序已经实现好所有的逻辑, 以后就算以后业务部分不点, 也可以导出生成基础数据, 报出报表了.
来源: http://www.linuxidc.com/Linux/2018-07/153312.htm