由于本人能力有限,如有不对之处,请在评论中提及,本人会及时做相应修改处理,感谢!
TASKCTL原生Oracle存储过程执行插件缺少了对SQLplus本身异常的捕获,主要体现在如存储过程等本身不存在时没有存储过程执行退出码,而TASKCTL又没有捕获ORA-错误码,可能导致执行结果不够准确。下面分别是 TASKCTL 6/5/4版本的Oracle存储过程的执行插件
TASKCTL 6 版本Oracle执行插件 更新如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | #!/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执行插件 更新如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | #!/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执行插件 更新如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | #!/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 ]
请登录后评论~