package Public;
our(@ISA,@EXPORT);
require Exporter;
@ISA=qw(Exporter);
@EXPORT = qw(&GetCurrentDateTime &GetUUID &DateCheck &GetParam &GetJobState &GetDBHandle
&WriteDBLog &GetDBResult_Single &GetDBResult &GetJobParam &UpETL_Job &DateCalculate
&GetProjectList &GetJobList &GetStageList &GetLinkList);
use warnings;
use strict;
use Time::Local;
use Data::UUID;
use DBI;
use DBD::Oracle;
use lib $ENV{"EDWETL_HOME"}."/Scrip/Public";
##--------------------------------------------------------
##--函数名称:GetCurrentDateTime
##--函数说明:得到本机当前的系统时间
##
##--输入参数:
##-- $type:获取类型 date(小写)
##-- time(小写)
##-- 不传参数
##--返回参数说明:
##-- date(小写):返回yyy-mm-dd格式的日期
##-- time(小写):返回hh24:mm:dd格式的机器时间
##-- 不传参/或者参数错误:返回默认格式yyyy-mm-dd hh24:mm:dd的时间
##--------------------------------------------------------
sub GetCurrentDateTime()
{
my ($type) = @_;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time());
my $current = "";
$year += 1900;
$mon = sprintf("%02d", $mon + 1);
$mday = sprintf("%02d", $mday);
$hour = sprintf("%02d", $hour);
$min = sprintf("%02d", $min);
$sec = sprintf("%02d", $sec);
if(not defined($type)){
$current = "${year}-${mon}-${mday} ${hour}:${min}:${sec}";
return $current;
}elsif($type eq 'date'){
$current = "${year}-${mon}-${mday}";
return $current;
}elsif($type eq 'time'){
$current = "${hour}:${min}:${sec}";
return $current;
}
}
##--------------------------------------------------------
##--函数名称:GetUUID
##--函数说明:生成UUID
##
##--输入参数:
##-- 无
##--返回参数说明:
##-- 32位UUID
##--------------------------------------------------------
sub GetUUID(){
my $ug = new Data::UUID;
my $str = $ug->create_str();
$str =~ s/-//g;
return($str);
}
##--------------------------------------------------------
##--函数名称:DateCheck
##--函数说明:日期合法性检查
##
##--输入参数:
##-- workdate:待检查日期
##--返回参数说明:
##-- $err_code:0为正常,非0异常
##--------------------------------------------------------
sub DateCheck(){
my ($workdate) = @_;
return(1) if(not defined($workdate));
$workdate =~ s//..*//;
$workdate =~ s/-//g;
if(not $workdate =~ /^[0-9]{8}$/){
return(1);
}
my $yy = substr($workdate,0,4);
my $mm = substr($workdate,4,2);
my $dd = substr($workdate,6,2);
if($yy <1900 or $mm <1 or $mm >12){
return(1);
}
if($dd<1 or $dd>31){
return(1);
}
if($mm == 4 or $mm == 6 or $mm == 9 or $mm == 11){
return(1) if($dd == 31);
}elsif($mm == 2){
if($yy % 4 == 0 and $yy % 100 != 0 or $yy % 400 == 0){
return(1) if($dd > 29);
}else{
return(1) if($dd > 28);
}
}
return(0);
}
##--------------------------------------------------------
##--函数名称:GetParam
##--函数说明:将PARA.cfg的参数信息存放到hash结构中
##--输入参数:
##-- 无
##--返回参数说明:
##-- $err_code:错误代码
##-- $err_info:错误信息
##-- /@param:哈希数组的引用
##-- {'DBNAME' = PARA.DBNAME ;
##-- 'DBUSR' = PARA.DBUSR ;
##-- 'DBPWD' = PARA.DBUSR ;
##-- .
##-- .
##-- }
##--------------------------------------------------------
sub GetParam(){
my (%param,$name,$value);
open(PARA,$ENV{"EDWETL_HOME"}."/Script/CFG/PARA.cfg") or return(00000002,"打开参数文件".$ENV{"EDWETL_HOME"}."/Script/CFG/PARA.cfg失败");
while(<PARA>){
next if($_!~/=/);
($name,$value)=split(/=/,$_);
$value=~s/ |/n|
//g;
chomp($value);
$param{$name} = $value;
}
close(PARA);
return('00000000','成功获取参数信息',/%param);
}
##--------------------------------------------------------
##--函数名称:GetDBHandle
##--函数说明:返回数据库连接句柄
##--输入参数说明:
##-- $db:数据库名
##-- $usr:数据库连接用户,可选
##-- $pwd:数据库连接密码,可选
##-- $auto_commit:可选
##--返回参数说明:
##-- $err_code:错误码
##-- $err_info:错误信息
##-- $dbh:数据库连接句柄
##--------------------------------------------------------
sub GetDBHandle(){
my ($db,$usr,$pwd,$auto_commit) = @_;
my $dbh;
return(30000001,"数据库名没有指定") if (not defined($db));
$auto_commit = 1 if(not defined($auto_commit));
return(30000001,"auto_commit参数错误") if ($auto_commit != 0 and $auto_commit != 1);
$dbh = DBI->connect("DBI:Oracle:$db", $usr, $pwd, { AutoCommit => $auto_commit, PrintError => 1, RaiseError => 0 } ) or return(20000001,"不能连接数据库 : $DBI::errstr");
return(00000000,"获取数据库 $db 连接句柄成功",$dbh);
}
##--------------------------------------------------------
##--函数名称:GetJobParam
##--函数说明 :根据作业名获取作业参数
##--输入参数:
##-- $job_name
##--返回参数说明:
##-- $err_code:错误代码
##-- $err_info:错误信息
##-- /%param:哈希数组的引用
##-- {'DBNAME' = PARA.DBNAME ;
##-- 'DBUSR' = PARA.DBUSR ;
##-- 'DBPWD' = PARA.DBUSR ;
##-- .
##-- .
##-- }
##--------------------------------------------------------
sub GetJobParam(){
my ($job_nm) = @_;
return(30000001,"作业名没有指定") if(not defined($job_nm));
my ($sql_str,$err_code,$err_info,$dbh,$sth,$GParams,%param_key,%param_val);
($err_code,$err_info,$GParams)=&GetParam();
return($err_code,$err_info) if ($err_code != 0);
($err_code,$err_info,$dbh) = &GetDBHandle($$GParams{"DBNAME"},$$GParams{"DBUSR"},$$GParams{"DBPWD"});
return($err_code,$err_info) if ($err_code != 0);
$sql_str = "select a.param_nm,a.param_val,b.torder"
." from job_param a,job_rela_param b,etl_job c"
." where a.job_id=b.job_id and a.param_id=b.param_id and b.job_id=c.job_id and c.job_nm='$job_nm' and b.param_type='JOB'"
." union"
." select a.param_nm,a.param_val,b.torder"
." from public_param a,job_rela_param b,etl_job c "
." where a.param_id=b.param_id and b.job_id=c.job_id and c.job_nm='$job_nm' and b.param_type='PUB' "
." order by torder asc";
$sth = $dbh->prepare($sql_str) or $dbh->disconnect() and return(20000002,"无法准备SQL语句 $sql_str ".$dbh->errstr());
$sth->execute() or $dbh->disconnect() and return(20000002,"无法执行SQL语句 ".$dbh->errstr());
while(my @row = $sth->fetchrow_array()){
$param_key{$row[2]} = $row[0];
$param_val{$row[0]} = $row[1];
}
$sth->finish();
$dbh->disconnect();
return('00000000','成功获取作业自定义参数',/%param_key,/%param_val);
}
##--------------------------------------------------------
##--函数名称:GetJobState
##--函数说明:获取DS Job状态
##--输入参数:
##-- $proj_nm:项目名称
##-- $job_nm:Job名称
##-- $ds_svr:DS服务器IP
##-- $ds_usr:DS服务器用户
##-- $ds_pwd:DS服务器密码
##--返回参数:
##-- $status:0-OK
##-- 1-RUNNING
##-- 2-WARNINGS
##-- 3-NOT RUNNING
##-- 4-FAILED
##-- 5-COMPILED
##-- 6-RESET
##-- 9-OTHER
##--------------------------------------------------------
sub GetJobState(){
my ($proj_nm,$job_nm,$ds_svr,$ds_usr,$ds_pwd) = @_;
return(30000001) if(not defined($proj_nm) or not defined($job_nm) or not defined($ds_svr) or not defined($ds_usr) or not defined($ds_pwd));
my $status;
my $jobinfo = "dsjob -server $ds_svr -user $ds_usr -password $ds_pwd"
." -jobinfo $proj_nm $job_nm"
;
open(JOBINFO,$jobinfo.'| ');
while(<JOBINFO>){
chomp($_);
my ($info_tp,$info) = split(/:/,);
if($info_tp =~ /Job Status/){
if($info =~ /RUNNING/){
if($info =~ /NOT/){
$status = 3;
}else{
$status = 1;
}
}
$status = 0 if($info =~ /OK/);
$status = 2 if($info =~ /WARNINGS/);
$status = 4 if($info =~ /FAILED/);
$status = 6 if($info =~ /RESET/);
}else{
$status = 5;
}
last if(defined($status));
}
$status = 9 if(not defined($status));
close(JOBINFO);
return($status);
}
##--------------------------------------------------------
##--函数名称:WriteDBLog
##--函数说明:写知识库日志
##--输入参数说明:
##-- $workdate:workdate
##-- $prog_tp:程序类型 0-DS Job 1-存储过程 2-Perl程序 3-可执行文件
##-- $prog_nm:程序名
##-- $info_tp:日志信息类型 I-正常 W-警告 E-错误
##-- $error_cd:错误码
##-- $info_context:日志信息内容
##--返回参数说明:
##-- $err_code:错误码
##-- $err_info:错误信息
##--------------------------------------------------------
sub WriteDBLog(){
my ($workdate,$prog_tp,$prog_nm,$info_tp,$error_cd,$info_context) = @_;
return(30000001,'workdate参数没有定义') if (not defined($workdate));
return(30000001,'程序名称没有定义') if (not defined($prog_nm));
return(30000001,"日期参数不合法:$workdate") if(&DateCheck($workdate) == 1 and defined($workdate));
$workdate = substr($workdate,0,4).'-'.substr($workdate,4,2).'-'.substr($workdate,6,2) if (length($workdate) == 8);
my ($err_code,$err_info,$GParams,$dbh,$machine_tm);
($err_code,$err_info,$GParams)=&GetParam();
return($err_code,$err_info) if($err_code != 0);
($err_code,$err_info,$dbh) = &GetDBHandle($$GParams{"DBNAME"},$$GParams{"DBUSR"},$$GParams{"DBPWD"},0);
return($err_code,$err_info) if($err_code != 0);
$machine_tm = &GetCurrentDateTime();
$info_context =~ s//'//g;
my $sql_str = "INSERT INTO prog_log VALUES(to_date('$machine_tm','yyyy-mm-dd hh24:mi:ss'),to_date('$workdate','yyyy-mm-dd'),'$prog_tp','$prog_nm','$info_tp','$error_cd','$info_context')";
$dbh->do($sql_str) or return(20000003,"日志写入失败".$DBI::errstr);
$dbh->commit();
$dbh->disconnect();
return('00000000','写入日志成功');
}
##--------------------------------------------------------
##--函数名称:UpETL_Job
##--函数说明:更新作业状态
##--输入参数说明:
##-- $job_nm:job_nm
##-- $starttime:开始时间,传""为不修改
##-- $endtime:结束时间,传""为不修改
##-- $jobstate:作业状态,传""为不修改
##-- $txdate:数据日期,传""为不修改
##-- $sessionid:传标志,需要修改传Y,其他为不作修改
##--返回参数说明:
##-- $err_code:错误码
##-- $err_info:错误信息
##--------------------------------------------------------
sub UpETL_Job(){
my ($job_nm,$starttime,$endtime,$jobstate,$txdate,$sessionid) = @_;
my $nullflag="";
if(! defined($starttime) || length($starttime)==0){
$starttime="";
}else{
$starttime="starttime=to_date('".$starttime."','yyyy-mm-dd hh24:mi:ss')";
$nullflag=",";
}
if(! defined($endtime) || length($endtime)==0){
$endtime="";
}else{
$endtime=$nullflag."endtime=to_date('".$endtime."','yyyy-mm-dd hh24:mi:ss')";
$nullflag=",";
}
if(! defined($jobstate) || length($jobstate)==0){
$jobstate="";
}else{
$jobstate=$nullflag."jobstate='".$jobstate."'";
$nullflag=",";
}
if(! defined($txdate) || length($txdate)==0){
$txdate="";
}else{
$txdate=$nullflag."txdate='".$txdate."'";
$nullflag=",";
}
my $flag;
if(defined($sessionid) && $sessionid eq "Y"){
$flag="Y";
$sessionid=$nullflag."sessionid=sessionid+1";
}else{
$flag="N";
$sessionid="";
}
my $sql_str="update etl_job set $starttime $endtime $jobstate $txdate $sessionid where job_nm='$job_nm'";
my ($err_code,$err_info,$GParams)=&GetParam();
return($err_code,$err_info) if($err_code != 0);
my $dbh;
($err_code,$err_info,$dbh) = &GetDBHandle($$GParams{"DBNAME"},$$GParams{"DBUSR"},$$GParams{"DBPWD"},0);
return($err_code,$err_info) if($err_code != 0);
if($dbh->do($sql_str)){
$dbh->commit();
}else{
return(20000004,"更新作业$job_nm的状态失败");
$dbh->disconnect();
}
print "error/n";
##当为作业完成时需要同时将信息转移到etl_log中
if($flag eq "Y"){
$sql_str="insert into etl_log(job_id,starttime,endtime,txdate,jobstate,sessionid) select job_id,starttime,endtime,txdate,jobstate,sessionid from etl_job where job_nm='$job_nm'";
$dbh->do($sql_str);
$dbh->commit();
$dbh->disconnect();
return('00000000','更新成功');
}else{
$dbh->disconnect();
return('00000000','更新成功');
}
}
##--------------------------------------------------------
##--函数名称:GetDBResult_Single
##--函数说明:根据传入的查询语句返回一条记录
##--输入参数说明:
##-- $sql_str:查询语句
##--返回参数说明:
##-- $err_code:错误码
##-- $err_info:错误信息
##-- @result:结果集
##--------------------------------------------------------
sub GetDBResult_Single{
my ($sql_str) = @_;
return(30000001,"传入sql为空") if($sql_str eq "");
my ($err_code,$err_info,$GParams)=&GetParam();
my $dbh;
($err_code,$err_info,$dbh) = &GetDBHandle($$GParams{"DBNAME"},$$GParams{"DBUSR"},$$GParams{"DBPWD"});
my $sth = $dbh->prepare($sql_str) or return(20000002,"执行sql错误");
if(!($sth->execute())){
$sth->finish();
$dbh->disconnect;
return(20000002,"执行sql错误");
}
my @result;
if(!(@result= $sth->fetchrow_array())){
$sth->finish();
$dbh->disconnect;
return(20000002,"查询无结果");
}
$sth->finish();
$dbh->disconnect;
return (00000000,"成功获取",@result);
}
##--------------------------------------------------------
##--函数名称:GetDBResult
##--函数说明:根据传入的查询语句返回多条记录的引用
## 通过引用构造多维数据组
##--输入参数说明:
##-- $sql_str:查询语句
##--返回参数说明:
##-- $err_code:错误码
##-- $err_info:错误信息
##-- /@result:结果集
##--使用例子
#my ($err_cod,$err_info,$res)=&GetDBResult($sql);
#for(my $i=0;$i<@$res;$i++){
# for(my $j=0;$j<@{$$res[$i]};$j++){
# print ${$$res[$i]}[$j]."/n";
# }
#}
##--------------------------------------------------------
sub GetDBResult{
my ($sql_str) = @_;
return(30000001,"传入sql为空") if($sql_str eq "");
my ($err_code,$err_info,$GParams)=&GetParam();
return($err_code,$err_info) if($err_code != 0);
my $dbh;
($err_code,$err_info,$dbh)= &GetDBHandle($$GParams{"DBNAME"},$$GParams{"DBUSR"},$$GParams{"DBPWD"});
return($err_code,$err_info) if($err_code != 0);
my $sth = $dbh->prepare($sql_str);
if(! ($sth->execute())){
$sth->finish();
$dbh->commit;
$dbh->disconnect;
return(20000002,"执行sql错误");
}
my @resualt;
my $i=0;
while(my @Tresualt= $sth->fetchrow_array()){
$resualt[$i]=/@Tresualt;
$i++;
}
return (20000002,"查询无数据") if($i==0);
$sth->finish();
$dbh->disconnect;
return (00000000,"成功获取",/@resualt);
}
##--------------------------------------------------------
#--函数名称: DateCalculate()
#--依赖模块: Time::Local
#--运行环境:不限
#--函数说明: 对日期时间进行加减操作
#--输入参数说明:
#-- $date: "yyyy-mm-dd hh24:mi:ss"格式的日期,例如"2009-09-09 12:21:23"
#-- $secs: 秒数(为负数时就进行日期减操作)
#--返回参数说明:
#-- $err_code: 错误码
#-- $err_info: 错误信息
#-- $date: 格式为"yyyy-mm-dd hh24:mi:ss"的返回日期
##--------------------------------------------------------
sub DateCalculate(){
my ($date,$secs)=@_;
return(30000001,"日期参数未定义") if(not defined($date));
return(30000002,"日期格式错误,需传入格式为yyyy-mm-dd hh24:mi:ss") if($date!~/^[0-9]{4}/-[0-1][0-9]/-[0-3][0-9] [0-5][0-9]:[0-5][0-9]:[0-5][0-9]$/);
return(30000001,"参数秒未定义") if(not defined($secs));
return(30000002,"秒格式错误,需传入参数为整形数值(可以为负值)") if($secs!~/^/-?/d+$/);
my $year=substr($date,0,4)-1900;
my $month=substr($date,5,2)-1;
my $day=substr($date,8,2);
my $hour=substr($date,11,2);
my $minute=substr($date,14,2);
my $sec=substr($date,17,2);
##月份hash表
my %months=('Jan'=>'01','Feb'=>'02','Mar'=>'03','Apr'=>'04','May'=>'05','Jun'=>'06','Jul'=>'07','Aug'=>'08','Sep'=>'09','Oct'=>'10','Nov'=>'11','Dec'=>'12');
my ($week,$Tmonth,$time,$rdate);
$time = timelocal($sec,$minute,$hour,$day,$month,$year);
$rdate=scalar localtime($time+$secs);
($week,$Tmonth,$day,$time,$year)=split(/ +/,$rdate);
$month=$months{$Tmonth};
my $returnDate=sprintf("%04d-%02d-%02d %s",$year,$month,$day,$time);
return(00000000,"日期操作成功",$returnDate)
}
##--------------------------------------------------------
#--函数名称: GetProjectList()
#--依赖模块: 无
#--运行环境:DS命令环境下
#--函数说明: 获取某个服务器下的所有工程清单
#--输入参数说明:
#-- $Server:服务器
#-- $USER:服务器
#-- $PWD:服务器
#--返回参数说明:
#-- $err_code: 错误码
#-- $err_info: 错误信息
#-- /@JobList: 作业清单
##--------------------------------------------------------
sub GetProjectList(){
my ($Server,$USER,$PWD,$Project)= @_;
return (30000002,"DS服务器参数不能为空") if(not defined($Server));
return (30000002,"用户名参数不能为空") if(not defined($USER));
return (30000002,"口令参数不能为空") if(not defined($PWD));
my ($err_code,$err_info,$cmd_str,@ProjectList);
$cmd_str="dsjob -server $Server -user $USER -password $PWD -lprojects";
open(DS,$cmd_str.'| ') or return (40000001,"执行命令$cmd_str失败");
while(<DS>){
chomp($_);
push(@ProjectList,$_);
}
close(DS);
return (00000000,"成功获取工程$Project的作业清单",/@ProjectList);
}
##--------------------------------------------------------
#--函数名称: GetJobList()
#--依赖模块: 无
#--运行环境:DS命令环境下
#--函数说明: 获取某个工程下的作业清单
#--输入参数说明:
#-- $Server:服务器
#-- $USER:服务器
#-- $PWD:服务器
#-- $Project_NM:工程名称
#--返回参数说明:
#-- $err_code: 错误码
#-- $err_info: 错误信息
#-- /@JobList: 作业清单
##--------------------------------------------------------
sub GetJobList(){
my ($Server,$USER,$PWD,$Project_NM)= @_;
return (30000002,"DS服务器参数不能为空") if(not defined($Server));
return (30000002,"用户名参数不能为空") if(not defined($USER));
return (30000002,"口令参数不能为空") if(not defined($PWD));
return (30000002,"DS 工程参数不能为空") if(not defined($Project_NM));
my ($err_code,$err_info,$cmd_str,@JobList);
$cmd_str="dsjob -server $Server -user $USER -password $PWD -ljobs $Project_NM";
open(DS,$cmd_str.'| ') or return (40000001,"执行命令$cmd_str失败");
while(<DS>){
chomp($_);
push(@JobList,$_);
}
close(DS);
return (00000000,"成功获取工程$Project_NM的作业清单",/@JobList);
}
##--------------------------------------------------------
#--函数名称: GetStageList()
#--依赖模块: 无
#--运行环境:DS命令环境下
#--函数说明: 获取某个DS作业的Stage清单
#--输入参数说明:
#-- $Server:服务器
#-- $USER:服务器
#-- $PWD:服务器
#-- $Project_NM:工程名称
#-- $Job_NM:作业名
#--返回参数说明:
#-- $err_code: 错误码
#-- $err_info: 错误信息
#-- /@StageList: 作业清单
##--------------------------------------------------------
sub GetStageList(){
my ($Server,$USER,$PWD,$Project_NM,$Job_NM)= @_;
return (30000002,"DS服务器参数不能为空") if(not defined($Server));
return (30000002,"用户名参数不能为空") if(not defined($USER));
return (30000002,"口令参数不能为空") if(not defined($PWD));
return (30000002,"DS 工程参数不能为空") if(not defined($Project_NM));
return (30000002,"DS 作业名参数不能为空") if(not defined($Job_NM));
my ($err_code,$err_info,$cmd_str,@StageList);
$cmd_str="dsjob -server $Server -user $USER -password $PWD -lstages $Project_NM $Job_NM";
open(DS,$cmd_str.'| ') or return (40000001,"执行命令$cmd_str失败");
while(<DS>){
chomp($_);
push(@StageList,$_);
}
close(DS);
return (00000000,"成功获取作业$Job_NM的Stage清单",/@StageList);
}
##--------------------------------------------------------
#--函数名称: GetLinkList()
#--依赖模块: 无
#--运行环境:DS命令环境下
#--函数说明: 获取某个Stage的link清单
#--输入参数说明:
#-- $Server:服务器
#-- $USER:服务器
#-- $PWD:服务器
#-- $Project_NM:工程名称
#-- $Job_NM:作业名
#-- $Stage_NM:Stage名
#--返回参数说明:
#-- $err_code: 错误码
#-- $err_info: 错误信息
#-- /@StageList: 作业清单
##--------------------------------------------------------
sub GetLinkList(){
my ($Server,$USER,$PWD,$Project_NM,$Job_NM,$Stage_NM)= @_;
return (30000002,"DS服务器参数不能为空") if(not defined($Server));
return (30000002,"用户名参数不能为空") if(not defined($USER));
return (30000002,"口令参数不能为空") if(not defined($PWD));
return (30000002,"DS 工程参数不能为空") if(not defined($Project_NM));
return (30000002,"DS 作业名参数不能为空") if(not defined($Job_NM));
return (30000002,"DS Stage名参数不能为空") if(not defined($Stage_NM));
my ($err_code,$err_info,$cmd_str,@LinkList);
$cmd_str="dsjob -server $Server -user $USER -password $PWD -llinks $Project_NM $Job_NM $Stage_NM";
open(DS,$cmd_str.'| ') or return (40000001,"执行命令$cmd_str失败");
while(<DS>){
chomp($_);
push(@LinkList,$_);
}
close(DS);
return (00000000,"成功获取作业$Stage_NM的Link清单",/@LinkList);
}
1;
__END__