由于本人能力有限,如有不对之处,请在评论中提及,本人会及时做相应修改处理,感谢!
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 ]
请登录后评论~