由于本人能力有限,如有不对之处,请在评论中提及,本人会及时做相应修改处理,感谢!
TASKCTL原生Oracle存储过程执行插件缺少了对SQLplus本身异常的捕获,主要体现在如存储过程等本身不存在时没有存储过程执行退出码,而TASKCTL又没有捕获ORA-错误码,可能导致执行结果不够准确。下面分别是 TASKCTL 6/5/4版本的Oracle存储过程的执行插件
TASKCTL 6 版本Oracle执行插件 更新如下
#!/bin/bash #------------------------------------------------------------------------------ # (一) 功能: 在CTL服务或代理用户环境下执行ORACLE的存储过程 # # (二) 参数: 在TASKCTL所有插件中,具有以下统一的参数接口 # 1. tccid: 【无用】容器(流程或定时器)ID # 2. jobid: 【无用】作业ID # 3. progname: 【有用】程序名称。程序名对应sh类型作业的progname属性 # 4. para 【有用】参数信息。参数信息对应sh类型作业的para属性 # 5. exppara 【有用】环境参数信息。环境参数信息对应sh类型作业的exppara属性 # 6. hostuser 【无用】远程主机用户链接信息。远程主机用户链接信息对应sh类型作业的hostuser属性 # # 参数说明: # (1) progname: ORACLE的存储过程名称 # (2) para : ORACLE的存储过程入口参数串 # (3) exppara : 数据库连接信息 # 格式: [数据库名称],[数据库用户],[数据库密码] # (三) 存储过程的参数接口要求 # [过程名称] # ( # in char var1, # in char var2, # ... # out int retvalue, # out char retmsg # ) # # 说明: # 1. 该插件要求存储过程必须有两个输出参数 # 2. retvalue返回值 返回0表示成功,非0失败 # 3. 如果输出参数不满足要求,您可以修改该插件,以适应您的存储过程接口 # # (四) 作业定义举例: # 1. 无输入参数存储过程 # <[存储过程自定义作业类型名]> # <name>job1</name> # <progname>[存储过程名]</progname> # <exppara>$(dbname),$(dbuser),$(dbpasswd)</exppara> # </[存储过程自定义作业类型名]> # # 2. 1个输入参数存储过程, 比如是workdate流程变量 # <oraproc> # <name>job2</name> # <progname>myproc1</progname> # <para>'$(workdate)'</para> # <exppara>$(dbname),$(dbuser),$(dbpasswd)</exppara> # </oraproc> # # 3. 2个输入参数存储过程(如果多个,以此类推) # <oraproc> # <name>job1</name> # <progname>myproc2</progname> # <para>'para1','para2'</para> # <exppara>$(dbname),$(dbuser),$(dbpasswd)</exppara> # </oraproc> # #------------------------------------------------------------------------------ if [ $# -ne 6 ] then echo "Param error !" echo "Usage: $0 progname para expara" exit 126 fi #------------------------------------------------------------------------------ # 第一步: 接收参数 #------------------------------------------------------------------------------ # tccid=$1 # jobid=$2 ProgName=$3 Para=$4 ExpPara=$5 # HostUser=$6 #------------------------------------------------------------------------------ # 第二步: 解析exppara,分别获取数据库名称、用户、密码等信息 #------------------------------------------------------------------------------ # 数据库名 并去前后空格 tmpstr=`echo "${ExpPara}"|awk -F ',' '{print $1}'` DBNAME=`echo ${tmpstr}` # 数据库用户 并去前后空格 tmpstr=`echo "${ExpPara}"|awk -F ',' '{print $2}'` DBUSER=`echo ${tmpstr}` # 数据库密码 并去前后空格 tmpstr=`echo "${ExpPara}"|awk -F ',' '{print $3}'` DBPASSWD=`echo ${tmpstr}` #------------------------------------------------------------------------------ # 第三步: 执行存储过程,执行时应判断参数是否为空 #------------------------------------------------------------------------------ # echo "sqlplus ${DBUSER}/${DBPASSWD}@${DBNAME}" if [ -z ${Para} ];then echo "${ProgName}(ret,cret);" #执行存储过程 sqlstr=`sqlplus ${DBUSER}/${DBPASSWD}@${DBNAME} << EOF 2>&1 WHENEVER SQLERROR exit 2 WHENEVER OSERROR exit 3 set serveroutput on declare ret number; cret varchar2(128); begin ${ProgName}(ret,cret); dbms_output.put_line('result'||ret||'##'||cret||'result'); end; / quit EOF` out=$? if [ ${out} != 0 ];then echo -e "${sqlstr}" echo "The oraproc error exit, exit code ${out}" exit ${out} fi else echo "${ProgName}(${Para},ret,cret);" #执行存储过程 sqlstr=`sqlplus ${DBUSER}/${DBPASSWD}@${DBNAME} << EOF 2>&1 WHENEVER SQLERROR exit 2 WHENEVER OSERROR exit 3 set serveroutput on declare ret number; cret varchar2(128); begin ${ProgName}(${Para},ret,cret); dbms_output.put_line('result'||ret||'##'||cret||'result'); end; / quit EOF` out=$? if [ ${out} != 0 ];then echo -e "${sqlstr}" echo "The oraproc error exit, exit code ${out}" exit ${out} fi fi #------------------------------------------------------------------------------ # 第四步: 插件返回 #------------------------------------------------------------------------------ echo "================================================================================" echo -e "${sqlstr}" echo "================================================================================" out=`echo $sqlstr |awk -F 'result' '{print $2}'|awk -F '##' '{print $1}'` CMSG=`echo $sqlstr |awk -F 'result' '{print $2}'|awk -F '##' '{print $2}'` echo "${ProgName} RETURN CODE:" ${out} [${CMSG}] exit ${out}
TASKCTL 5 版本Oracle执行插件 更新如下
#!/bin/bash #------------------------------------------------------------------------------ # (一) 功能: 在CTL服务或代理用户环境下执行ORACLE的存储过程 # # (二) 参数: 在TASKCTL所有插件中,具有以下统一的参数接口 # 1. tccid: 【无用】容器(流程或定时器)ID # 2. jobid: 【无用】作业ID # 3. progname: 【有用】程序名称。程序名对应sh类型作业的progname属性 # 4. para 【有用】参数信息。参数信息对应sh类型作业的para属性 # 5. exppara 【有用】环境参数信息。环境参数信息对应sh类型作业的exppara属性 # # 参数说明: # (1) progname: ORACLE的存储过程名称 # (2) para : ORACLE的存储过程入口参数串 # (3) exppara : 数据库连接信息 # 格式: [数据库名称],[数据库用户],[数据库密码] # (三) 存储过程的参数接口要求 # [过程名称] # ( # in char var1, # in char var2, # ... # out int retvalue, # out char retmsg # ) # # 说明: # 1. 该插件要求存储过程必须有两个输出参数 # 2. retvalue返回值 返回0表示成功,非0失败 # 3. 如果输出参数不满足要求,您可以修改该插件,以适应您的存储过程接口 # # (四) 作业定义举例: # 1. 无输入参数存储过程 # <[存储过程自定义作业类型名]> # <name>job1</name> # <progname>[存储过程名]</progname> # <exppara>$(dbname),$(dbuser),$(dbpasswd)</exppara> # </[存储过程自定义作业类型名]> # # 2. 1个输入参数存储过程, 比如是workdate流程变量 # <oraproc> # <name>job2</name> # <progname>myproc1</progname> # <para>'$(workdate)'</para> # <exppara>$(dbname),$(dbuser),$(dbpasswd)</exppara> # </oraproc> # # 3. 2个输入参数存储过程(如果多个,以此类推) # <oraproc> # <name>job1</name> # <progname>myproc2</progname> # <para>'para1','para2'</para> # <exppara>$(dbname),$(dbuser),$(dbpasswd)</exppara> # </oraproc> # #------------------------------------------------------------------------------ if [ $# -ne 5 ] then echo "Param error !" echo "Usage: $0 progname para expara" exit 126 fi #------------------------------------------------------------------------------ # 第一步: 接收参数 #------------------------------------------------------------------------------ # tccid=$1 # jobid=$2 ProgName=$3 Para=$4 ExpPara=$5 #------------------------------------------------------------------------------ # 第二步: 解析exppara,分别获取数据库名称、用户、密码等信息 #------------------------------------------------------------------------------ # 数据库名 并去前后空格 tmpstr=`echo "${ExpPara}"|awk -F ',' '{print $1}'` DBNAME=`echo ${tmpstr}` # 数据库用户 并去前后空格 tmpstr=`echo "${ExpPara}"|awk -F ',' '{print $2}'` DBUSER=`echo ${tmpstr}` # 数据库密码 并去前后空格 tmpstr=`echo "${ExpPara}"|awk -F ',' '{print $3}'` DBPASSWD=`echo ${tmpstr}` #------------------------------------------------------------------------------ # 第三步: 执行存储过程,执行时应判断参数是否为空 #------------------------------------------------------------------------------ # echo "sqlplus ${DBUSER}/${DBPASSWD}@${DBNAME}" if [ -z ${Para} ];then echo "${ProgName}(ret,cret);" #执行存储过程 sqlstr=`sqlplus ${DBUSER}/${DBPASSWD}@${DBNAME} << EOF 2>&1 WHENEVER SQLERROR exit 2 WHENEVER OSERROR exit 3 set serveroutput on declare ret number; cret varchar2(128); begin ${ProgName}(ret,cret); dbms_output.put_line('result'||ret||'##'||cret||'result'); end; / quit EOF` out=$? if [ ${out} != 0 ];then echo -e "${sqlstr}" echo "The oraproc error exit, exit code ${out}" exit ${out} fi else echo "${ProgName}(${Para},ret,cret);" #执行存储过程 sqlstr=`sqlplus ${DBUSER}/${DBPASSWD}@${DBNAME} << EOF 2>&1 WHENEVER SQLERROR exit 2 WHENEVER OSERROR exit 3 set serveroutput on declare ret number; cret varchar2(128); begin ${ProgName}(${Para},ret,cret); dbms_output.put_line('result'||ret||'##'||cret||'result'); end; / quit EOF` out=$? if [ ${out} != 0 ];then echo -e "${sqlstr}" echo "The oraproc error exit, exit code ${out}" exit ${out} fi fi #------------------------------------------------------------------------------ # 第四步: 插件返回 #------------------------------------------------------------------------------ echo "================================================================================" echo -e "${sqlstr}" echo "================================================================================" out=`echo $sqlstr |awk -F 'result' '{print $2}'|awk -F '##' '{print $1}'` CMSG=`echo $sqlstr |awk -F 'result' '{print $2}'|awk -F '##' '{print $2}'` echo "${ProgName} RETURN CODE:" ${out} [${CMSG}] exit ${out}
TASKCTL 4 版本Oracle执行插件 更新如下
#!/bin/bash #------------------------------------------------------------------------------ # (一) 功能: 在CTL服务或代理用户环境下执行ORACLE的存储过程 # # (二) 参数: 在TASKCTL所有插件中,具有以下统一的参数接口 # 1. progname: 【有用】程序名称。程序名对应sh类型作业的progname属性 # 2. para 【有用】参数信息。参数信息对应sh类型作业的para属性 # 3. exppara 【有用】环境参数信息。环境参数信息对应sh类型作业的exppara属性 # # 参数说明: # (1) progname: ORACLE的存储过程名称 # (2) para : ORACLE的存储过程入口参数串 # (3) exppara : 数据库连接信息 # 格式: [数据库名称],[数据库用户],[数据库密码] # (三) 存储过程的参数接口要求 # [过程名称] # ( # in char var1, # in char var2, # ... # out int retvalue, # out char retmsg # ) # # 说明: # 1. 该插件要求存储过程必须有两个输出参数 # 2. retvalue返回值 返回0表示成功,非0失败 # 3. 如果输出参数不满足要求,您可以修改该插件,以适应您的存储过程接口 # # (四) 作业定义举例: # 1. 无输入参数存储过程 # <[存储过程自定义作业类型名]> # <name>job1</name> # <progname>[存储过程名]</progname> # <exppara>$(dbname),$(dbuser),$(dbpasswd)</exppara> # </[存储过程自定义作业类型名]> # # 2. 1个输入参数存储过程, 比如是workdate流程变量 # <oraproc> # <name>job2</name> # <progname>myproc1</progname> # <para>'$(workdate)'</para> # <exppara>$(dbname),$(dbuser),$(dbpasswd)</exppara> # </oraproc> # # 3. 2个输入参数存储过程(如果多个,以此类推) # <oraproc> # <name>job1</name> # <progname>myproc2</progname> # <para>'para1','para2'</para> # <exppara>$(dbname),$(dbuser),$(dbpasswd)</exppara> # </oraproc> # #------------------------------------------------------------------------------ if [ $# -ne 3 ] then echo "Param error !" echo "Usage: $0 progname para expara" exit 126 fi #------------------------------------------------------------------------------ # 第一步: 接收参数 #------------------------------------------------------------------------------ ProgName=$1 Para=$2 ExpPara=$3 #------------------------------------------------------------------------------ # 第二步: 解析exppara,分别获取数据库名称、用户、密码等信息 #------------------------------------------------------------------------------ # 数据库名 并去前后空格 tmpstr=`echo "${ExpPara}"|awk -F ',' '{print $1}'` DBNAME=`echo ${tmpstr}` # 数据库用户 并去前后空格 tmpstr=`echo "${ExpPara}"|awk -F ',' '{print $2}'` DBUSER=`echo ${tmpstr}` # 数据库密码 并去前后空格 tmpstr=`echo "${ExpPara}"|awk -F ',' '{print $3}'` DBPASSWD=`echo ${tmpstr}` #------------------------------------------------------------------------------ # 第三步: 执行存储过程,执行时应判断参数是否为空 #------------------------------------------------------------------------------ # echo "sqlplus ${DBUSER}/${DBPASSWD}@${DBNAME}" if [ -z ${Para} ];then echo "${ProgName}(ret,cret);" #执行存储过程 sqlstr=`sqlplus ${DBUSER}/${DBPASSWD}@${DBNAME} << EOF 2>&1 WHENEVER SQLERROR exit 2 WHENEVER OSERROR exit 3 set serveroutput on declare ret number; cret varchar2(128); begin ${ProgName}(ret,cret); dbms_output.put_line('result'||ret||'##'||cret||'result'); end; / quit EOF` out=$? if [ ${out} != 0 ];then echo -e "${sqlstr}" echo "The oraproc error exit, exit code ${out}" exit ${out} fi else echo "${ProgName}(${Para},ret,cret);" #执行存储过程 sqlstr=`sqlplus ${DBUSER}/${DBPASSWD}@${DBNAME} << EOF 2>&1 WHENEVER SQLERROR exit 2 WHENEVER OSERROR exit 3 set serveroutput on declare ret number; cret varchar2(128); begin ${ProgName}(${Para},ret,cret); dbms_output.put_line('result'||ret||'##'||cret||'result'); end; / quit EOF` out=$? if [ ${out} != 0 ];then echo -e "${sqlstr}" echo "The oraproc error exit, exit code ${out}" exit ${out} fi fi #------------------------------------------------------------------------------ # 第四步: 插件返回 #------------------------------------------------------------------------------ echo "================================================================================" echo -e "${sqlstr}" echo "================================================================================" out=`echo $sqlstr |awk -F 'result' '{print $2}'|awk -F '##' '{print $1}'` CMSG=`echo $sqlstr |awk -F 'result' '{print $2}'|awk -F '##' '{print $2}'` echo "${ProgName} RETURN CODE:" ${out} [${CMSG}] exit ${out}
可以看到不同版本,只是入口参数发生了变化,参数解析为了保证通用性,没有使用新版本 TASKCTL 解析参数的 ctlgetvalue 的 C 语言程序等。
至于如何更新 Oracle 执行插件,此处由于作业类型均有,只需要把对应版本的执行插件覆盖原 $TASKCTLDIR/src/plugin/oraproc/shell/cprunoraproc.sh 即可,那一台执行节点执行Oracle存储过程,那一台就一定要修改,其他不用的节点可以随意。其他可以参考TASKCTL论坛的其他帖子,如 http://www.taskctl.com/forum/detail_129.html ,http://www.taskctl.com/forum/detail_124.html 等
当存储过程定义不满足TASKCTL规范时,也可以调整该执行插件适配,主要在SQLplus执行代码拼接那一段,具体自行调试即可
[最后编辑于 2020-06-10 11:53 ]
请登录后评论~