#!/usr/bin/perl
###############################################################################
# 规则检查主要包括以下步骤:
#1.查询出所有的规则组,进行第一次循环
# 2.查询当前规则组下的所有规则(一般都是针对同一个字段),循环每一个规则,从中提取规则sql
# 3.一组规则的每个规则都会在前一个规则的执行基础之上计算通过率,
# 有效检查记录总数,计算的粒度细分到机构,规则编号
#说明:
#调用形式 :
#perl ruleCheck-concurrent.pl DQC_BHYWXXB#BHQSRQ_20160601.dir(单个字段)
#perl ruleCheck-concurrent.pl DQC_BHYWXXB#XDHTH-CJRQ_20160601.dir(多个字段)
#执行数据库环境:DB210.5 DPF
# Writer : zengst
# Version : 2.0
###############################################################################
use strict;#对语法做严格限制,如变量必须先用my声明
use DBI;
use Time::Local;
my $dbh;#与数据库的连接
my $AUTO_HOME = $ENV{"AUTO_HOME"};
#通过ETL的加密方式得到登录信息
my $LOGON_DB2_FILE=$ENV{"LOAD_LOGON_DB2_FILE"};
my $DB2LOGON_FILE = "${AUTO_HOME}/etc/${LOGON_DB2_FILE}";
my $ODBCDriver = "AHNXODS64";
my $LOGONSTR;
my $DB2user;
my $DB2pwd;
my $RUN_DATE;#质量检测日期
my $Topic_Area;#检查的专题
my $Sys_Id;#检查的系统id
my $Map_Id;#规则组id
my $table_Name;#检查的表名
my $Check_Column_Name;#检查的字段名称,一个规则组,检测一个字段
my $PK_Column_Name;#检查的表的主键字段
my $Org_Column_Name;#机构字段名称,注意不是值,因为检查的业务系统的机构字段可能不一致
my $Rule_Name;#规则说明,即检查的是什么
my $checkID; #检查编号
my $SQLClause;#当前规则检查的sql
my $Rule_Info;#规则信息
my $Rule_Group;#规则组信息
my $whereClause;
my $modifydate;
my $CheckDimension;#规则维度
my $CheckSegmentation;
my $logFile;
my $RuleTable='EASTDQM.Rule';#规则信息表
my $RuleGroupTable='EASTDQM.RuleGroup';#规则组信息表
my $check_Result = 'EASTDQM.Check_Result';#轻度结果汇总表
my $check_detail='EASTDQM.Check_Result_Detail';#检查结果明细表
my $check_detail_sample = 'EASTDQM.check_detail_sample';
#日志文件目录
#一个大于号,表示覆盖原有文件的内容
#两个大于号表示在原有文件内容之后添加
#@日志文件因为并发,可能发生读写冲突,最好加上表名和字段名的区分,即规则组的粒度
# 判断是否有信号文件信息
if ( $#ARGV < 0 ) {
print "\n";
print "Usage: ****.pl CONTROL_FILE \n";
print "Usage: Use parameters \n";
print "CONTROL_FILE -- SYS_JOBNAME_YYYYMMDD.dir \n";
exit(1);
}
my $job_params = $ARGV[0]; #传入的参数
my $tableName="";#参数中的表名
my $column="";#参数中的字段名
my $TX_DATE=substr($job_params,length($job_params)-12,8);#业务数据日期
my $_date = substr($TX_DATE,0,4)."-".substr($TX_DATE,4,2)."-".substr($TX_DATE,6,2);
#my $TX_DATE="20160621";#数据日期
my $jobName = substr($job_params,4,length($job_params)-17);
sub getTableAndColumn{
if($jobName =~ /#/){
my @job_split = split("#",$jobName);
$tableName = @job_split[0];
#可能有多个列,列之间通过中杠分割
$column = @job_split[1];
if(split("-",$column)){
my @columnArr = split("-",$column);
my $columnLength = $#columnArr;
foreach my $k(0..$columnLength){
if($k eq 0){
$column = @columnArr[$k];
}else{
$column = $column.','.@columnArr[$k];
}
}
}
}
else{
print "The para format is wrong\n";
return 0;
}
}
sub getDB2LogonStr{
#定义文件的句柄
my $LOGONFILEREF;
#打开文件
open($LOGONFILEREF, "${DB2LOGON_FILE}");
my $LOGONSTR = <$LOGONFILEREF>;
close(LOGONFILEREF);
$LOGONSTR = `${AUTO_HOME}/bin/IceCode.exe "$LOGONSTR"`;
my ($UserID, $UserPwd) = split(' ',$LOGONSTR);
chop($UserPwd);
($DB2user,$DB2pwd) = split(',' , $UserPwd);
}
#初始化数据库的连接信息
sub DBconnect{
getDB2LogonStr();
$dbh = DBI->connect("dbi:ODBC:${ODBCDriver}","$DB2user","$DB2pwd",{RaiseError => 1, AutoCommit => 0 })
|| die "Couldn't connect to database: ".DBI->errstr;
print (GetNowTime()." get DB2 connection success! \n ");
return $dbh;
}
#得到规则组信息。因为每一个规则组里面的规则需要进行单独的
#权重评分,一次性搜索全部的规则时处理逻辑会相当复杂
sub getRuleGroupInfo{
#得到所有正在运行的规则组
getTableAndColumn();
my $runFreq =isRunCondition();
#根据表名+字段名的粒度筛选规则组,并发时并发度做到一定程度的最大化
my $groupInfoSQL = "select Map_Id,Topic_Area from ${RuleGroupTable} where Status= 1 and freq_flag in($runFreq) and table_name='$tableName' and check_column_name='$column' order by Map_Id";
#my $groupInfoSQL = "select Map_Id,Topic_Area from ${RuleGroupTable} where Status= 1 and freq_flag in('01') and table_name='dacorpinfo' and check_column_name='basicbankname' order by Map_Id";
#my $groupInfoSQL = "select Map_Id,Topic_Area from ${RuleGroupTable} where Status= 1 and table_name not in('CZXX','GRDQCKFHZ','GRHQCKFHZMXJL','GRJCXX','JJKXX','JYLS','NBFHZMXJL') AND MAP_ID NOT IN(SELECT MAP_ID FROM $check_Result group by map_id) order by Map_Id";
my $sth = $dbh->prepare($groupInfoSQL) or return -1;
my $ret = $sth->execute() or return -1;
${Rule_Group} = $sth->fetchall_arrayref();
$sth->finish();
return ${Rule_Group};
}
#得到数据库配置表的信息
sub getRuleInfo{
my ($groupId)=@_;#参数传入规则组Map_id
#一个规则组下有多个规则,rule_prior小的先执行
my $ruleConfigSql =
"select check_id,Topic_Area,r.sys_id,r.table_Name,r.Check_Column_Name,".
"r.PK_Column_Name,r.Org_Column_Name,rule_name,modifydate,r.SQLClause,map_id,WhereClause,CHECKDIMENSION ".
"from ${RuleTable} r".
" where r.status='1' and map_id=$groupId ".
" order by Rule_Prior asc";
my $sth = $dbh->prepare($ruleConfigSql) or return -1;
my $ret = $sth->execute() or return -1;
${Rule_Info} = $sth->fetchall_arrayref();
$sth->finish();
return 0;
}
#执行规则SQL
sub exeRuleSql{
#存储已经排好序的待执行的规则sql
my @exeCheckSql=();
for my $i(0..$#${Rule_Info}){
$checkID=${Rule_Info}->[$i]->[0]; #检查编号
print (GetNowTime()." Begin To Run Rule[$i]:$checkID \n");
$Topic_Area = ${Rule_Info}->[$i]->[1];#Rule_Info是一个二维数组,${Rule_Info}->[$i]表示是第i行
$Sys_Id=${Rule_Info}->[$i]->[2];
$table_Name=${Rule_Info}->[$i]->[3];
$Check_Column_Name=${Rule_Info}->[$i]->[4];
$PK_Column_Name=${Rule_Info}->[$i]->[5];
$Org_Column_Name=${Rule_Info}->[$i]->[6];
$Rule_Name=${Rule_Info}->[$i]->[7];
$modifydate=${Rule_Info}->[$i]->[8];
$SQLClause=${Rule_Info}->[$i]->[9];
$SQLClause =~ s/(\$[\w_]+)/eval $1/ge;
$SQLClause =~ s/(\$\{[^\}]+\})/eval $1/ge;
$Map_Id=${Rule_Info}->[$i]->[10];
$whereClause = ${Rule_Info}->[$i]->[11];
$CheckDimension = ${Rule_Info}->[$i]->[12];
push(@exeCheckSql,$SQLClause);
#为了防止多次执行,需要删除轻度汇总表和和检查明细表
#运行时要删除全部的机构数据
print (GetNowTime() . " **************************Clear The Result Table:**************************\n");
my $DelSql = "Delete From ${check_Result} Where Check_ID = ${checkID} and rundate='${_date}'";
my $sth = $dbh->prepare($DelSql) or return -1;
#返回影响的行数,select也可以影响行数
my $ret = $sth->execute() or return -1;
$sth->finish();
print (GetNowTime() . " **************************Clear The Result Table:Succeed[Rows:$ret] **************************\n");
print (GetNowTime() . " **************************Clear The Detail Table:**************************\n");
my $DelSql = "Delete From ${check_detail} Where Check_ID = ${checkID} and RUNDATE='${_date}'";
$sth = $dbh->prepare($DelSql) or return -1;
#返回影响的行数,也包括select语句
$ret = $sth->execute() or return -1;
$sth->finish();#释放结果集
print (GetNowTime() . " **************************Clear The Detail Table:Succeed[Rows:$ret]**************************\n");
#字符串的相等是eq,第一次执行的规则的记录总数是待检测表的记录总数
if($i==0){
my $fromposi = index($SQLClause,'FROM');
my $fromclause = substr($SQLClause,$fromposi+4);
#主键字段是多列,这里将它拼成一列
my $pkselect = '';
my @PKcon = split(",",$PK_Column_Name);
my $PKlen = $#PKcon;#获得数组的下标,数组为空时,返回-1
if($PKlen eq 0){
$pkselect = $PK_Column_Name;
}else{
foreach my $k(0..$PKlen){
if($k eq 0){
$pkselect = @PKcon[$k];
}else{
$pkselect = $pkselect.'||'.'\'#\''.'||'.(@PKcon[$k]);
}
}
}
#对检查的字段是多列情况的处理,将多列的数据拼接成一列
my $ckselect= '';
my @CKcon = split(",",$Check_Column_Name);
my $CKlen = $#CKcon;
if($CKlen eq 0){
$ckselect = $Check_Column_Name;
}else{
foreach my $k(0..$CKlen){
if($k eq 0){
$ckselect = @CKcon[$k];
}else{
$ckselect = $ckselect.'||'.'\'#\''.'||'.(@CKcon[$k]);
}
}
}
my $now1 = time;
print (GetNowTime() ." ************************** insert into detail begin **************************\n");
#将规则sql的检查结果插入detail表,因为最终需要进行轻度汇总
my $detailinsertSql = "Insert Into ${check_detail}" .
" select ${checkID},'${_date}', ${Map_Id}," .
" '${Topic_Area}','${Sys_Id}','${table_Name}','${Check_Column_Name}','${CheckDimension}','${CheckSegmentation}',".
" ${pkselect},${Org_Column_Name},${ckselect} from ".$fromclause;
my $detailsth = $dbh->prepare($detailinsertSql) or return -1;
$detailsth->execute() or return -1;
$detailsth->finish();
print (GetNowTime() ." ************************** insert into detail end **************************\n");
print (GetNowTime() ." ************************** insert into sample data begin **************************\n");
#从全量表按照规则、机构和运行日期的维度取得样本数据,插入到样例表
#partition by 可以是多个字段
my $sampInsert = "insert into ${check_detail_sample}".
" select ${checkID},'${_date}',${Map_Id},'${Topic_Area}','${Sys_Id}','${table_Name}','${Check_Column_Name}',".
"'${CheckDimension}','${CheckSegmentation}',pk_column_value,org_id,check_column_value from ".
"(select crt.*,ROW_NUMBER() over( partition by org_id,check_id) as seq from ${check_detail} crt where rundate='${_date}') detailtmp ".
" where detailtmp.seq<6";
my $inssth = $dbh->prepare($sampInsert) or return -1;
$inssth->execute() or return -1;
$inssth->finish();
#将日志信息打印到文件当中
print (GetNowTime() ." ************************** insert into sample data end **************************\n");
print (GetNowTime() ." ************************** begin insert check_result**************************\n");
#将detail数据进行汇总插入到result表,直接通过sql进行数据的循环插入,方式insert into table select ******
my $InsSql = " Insert Into ${check_Result}".
" select ${checkID},'${_date}', '${Rule_Name}',${Map_Id},'${Topic_Area}','${Sys_Id}','${table_Name}','${Check_Column_Name}','${CheckDimension}','${CheckSegmentation}',".
" mainorg ,effectCount,effectCount-decode(FailCount,null,0,FailCount), decode(FailCount,null,0,FailCount),".
" cast(decode(FailCount,null,0,FailCount) as double)/effectCount,cast((effectCount-decode(FailCount,null,0,FailCount)) as double)/effectCount from ".
"(select count(*) as effectCount, $Org_Column_Name as mainorg from ${Sys_Id}.${table_Name} group by ${Org_Column_Name}) tmain ".
" left join ".
"(select count(*) as FailCount, org_id,check_id from ${check_detail} detail where detail.rundate = '${_date}'and check_id=${checkID} group by org_id,check_id) tdetail".
" on tmain.mainorg = tdetail.org_id";
my $collsth = $dbh->prepare($InsSql) or return -1;
$collsth->execute() or return -1;
$collsth->finish();
print (GetNowTime() ." ************************** end insert check_result**************************\n");
my $now2 = time;
my $diff = $now2 - $now1;
if($diff > 1800){#大于30分钟
print ("execute time is : $diff second,checkId is :【$checkID】 ! \n");
}
$dbh->commit();
#没有commit时,就不会插入到数据库
}else{
#上一次执行的sql,一个规则组下的第n个规则执行时,检查的有效记录数=全表-前面n-1次检查出的记录数
my $preWhereCluse = '';
my $arrIndex = $#exeCheckSql;
#当前是第i个规则sql,那么需要得到前面i-1个规则sql检测的sql
for(my $j=0;$j<=($arrIndex-1);$j++){
#这里要求规则sql都是有where条件的,截取的都是where之后的内容
#这里要求执行的规则sql只有where子句
my $whereposi = index(@exeCheckSql[$j],'WHERE');
my $whereclause = substr(@exeCheckSql[$j],$whereposi+5);
if($j eq 0){
$preWhereCluse = ' and not('.$whereclause.')';
}else{
$preWhereCluse = $preWhereCluse.' and not('.$whereclause.')';
}
}
#本次检查在上一次检查的基础上,排除上次规则检查有问题的记录
my $currSqlCluse = $SQLClause.$preWhereCluse;
my $fromposi = index($currSqlCluse,'FROM');
my $fromclause = substr($currSqlCluse,$fromposi+4);
my $pkselect = '';
my @PKcon = split(",",$PK_Column_Name);
my $PKlen = $#PKcon;#获得数组的下标,从0开始,数组为空时,返回-1
if($PKlen eq 0){
$pkselect = $PK_Column_Name;
}else{
foreach my $k(0..$PKlen){
if($k eq 0){
$pkselect = @PKcon[$k];
}else{
$pkselect = $pkselect.'||'.'\'#\''.'||'.(@PKcon[$k]);
}
}
}
my $ckselect= '';
my @CKcon = split(",",$Check_Column_Name);
my $CKlen = $#CKcon;
if($CKlen eq 0){
$ckselect = $Check_Column_Name;
}else{
foreach my $k(0..$CKlen){
if($k eq 0){
$ckselect = @CKcon[$k];
}else{
$ckselect = $ckselect.'||'.'\'#\''.'||'.(@CKcon[$k]);
}
}
}
my $now1 = time;
print (GetNowTime() ." ************************** insert into detail begin **************************\n");
#将规则sql的检查结果插入明细表
my $detailInsertSql = "Insert Into ${check_detail}" .
" select ${checkID},'${_date}', ${Map_Id}," .
" '${Topic_Area}','${Sys_Id}','${table_Name}','${Check_Column_Name}','${CheckDimension}','${CheckSegmentation}',".
" ${pkselect},${Org_Column_Name},${ckselect} from ".$fromclause;
my $detailsth = $dbh->prepare($detailInsertSql) or return -1;
$detailsth->execute() or return -1;
$detailsth->finish();
print (GetNowTime() ." ************************** insert into detail end **************************\n");
print (GetNowTime() ." ************************** insert into sample data begin **************************\n");
#从临时表按照规则、机构和运行日期的维度取得样本数据,插入明细表
#partition by 可以是多个字段
my $sampInsert = "insert into ${check_detail_sample}".
" select ${checkID},'${_date}',${Map_Id},'${Topic_Area}','${Sys_Id}','${table_Name}','${Check_Column_Name}',".
"'${CheckDimension}','${CheckSegmentation}',pk_column_value,org_id,check_column_value from ".
"(select crt.*,ROW_NUMBER() over( partition by org_id,check_id) as seq from ${check_detail} crt where rundate='${_date}') detailtmp ".
" where detailtmp.seq<6";
my $inssth = $dbh->prepare($sampInsert) or return -1;
$inssth->execute() or return -1;
$inssth->finish();
print (GetNowTime() ." ************************** insert into sample data end **************************\n");
print (GetNowTime() ." ************************** begin insert check_result**************************\n");
#将detail数据插入到result表,直接通过sql进行数据的循环插入,方式insert into table select ******
my $InsSql = " Insert Into ${check_Result}".
" select ${checkID},'${_date}', '${Rule_Name}',${Map_Id},'${Topic_Area}','${Sys_Id}','${table_Name}','${Check_Column_Name}','${CheckDimension}','${CheckSegmentation}',".
" mainorg ,effectCount,effectCount-decode(FailCount,null,0,FailCount), decode(FailCount,null,0,FailCount),".
" cast(decode(FailCount,null,0,FailCount) as double)/effectCount,cast((effectCount-decode(FailCount,null,0,FailCount)) as double)/effectCount from ".
"(select count(*) as effectCount, $Org_Column_Name as mainorg from ${Sys_Id}.${table_Name} where 1=1".$preWhereCluse." group by ${Org_Column_Name}) tmain ".
" left join ".
"(select count(*) as FailCount, org_id,check_id from ${check_detail} detail where detail.rundate = '${_date}'and check_id=${checkID} group by org_id,check_id) tdetail".
" on tmain.mainorg = tdetail.org_id";
my $collsth = $dbh->prepare($InsSql) or return -1;
$collsth->execute() or return -1;
$collsth->finish();
print (GetNowTime() ." ************************** end insert check_result**************************\n");
my $now2 = time;
my $diff = $now2 - $now1;
if($diff > 1800){#大于30分钟
print ("execute time is : $diff second,checkId is :【$checkID】 ! \n");
}
$dbh->commit();
}#else block
}#rule_info for block
return 0;
}
sub main{
print "main begin \n";
#得到数据库连接
$dbh = DBconnect();
#初始化规则组信息
print (GetNowTime() . " *********************init ruleGroup info ! ***************************\n");
getRuleGroupInfo();
#如果查询没有数据,返回接收的数组取值后,下标的最大值就是-1
my $ruleGrouplength = $#${Rule_Group}+1;
print (GetNowTime() . " *********************ruleGroup length: $ruleGrouplength ***************************\n");
#判断执行结果
if ($ruleGrouplength = 0 ){
print (GetNowTime() . " *********************No Rule_Group Info !*********************\n");
} else {
print (GetNowTime() . " *********************Get Rule_Group:Succeed !********************* \n");
}
#循环规则组,根据每一个规则组,找到该规则组下的规则(注意规则状态必须是1,即是可运行的)
my $groupTemp = '';
for my $ii(0..$#${Rule_Group}){
$groupTemp = ${Rule_Group}->[$ii]->[0];
print (GetNowTime() . "********************* Begin To Run Rule_Group[$ii+1],groupId:${groupTemp}********************* \n");
#传入了规则组参数Mapid
print (GetNowTime() . " *********************Begin To get Rule Info! ***************************\n");
getRuleInfo($groupTemp);
print (GetNowTime() . " *********************end To get Rule Info! ***************************\n");
print (GetNowTime() . " *********************Begin To execute Rule check ! ***************************\n");
exeRuleSql();
#将错误明细表的记录导出成txt文件,这里是规则组的粒度
#导出明细后,删除明细数据,防止数据量膨胀
print (GetNowTime() . " *********************end To execute Rule check ! ***************************\n");
}
print (GetNowTime() . " ********************* end ***************************\n");
return 0;
}
sub GetNowTimeNospechar{
my ($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst) = localtime();
$hour = sprintf("%02d", $hour);
$min = sprintf("%02d", $min);
$sec = sprintf("%02d", $sec);
my $stime = GetNowDate().$hour.$min.$sec;
return $stime;
}
sub GetNowTime{
my ($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst) = localtime();
$hour = sprintf("%02d", $hour);
$min = sprintf("%02d", $min);
$sec = sprintf("%02d", $sec);
my $stime = GetNowDate()." ".$hour.":".$min.":".$sec;
return $stime;
}
#找到当前的日期,月份要加1,年份是从1900开始算的
sub GetNowDate{
my ($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst) = localtime();
$mon = sprintf("%02d", $mon+1);
$day = sprintf("%02d", $day);
my $stime = ($year+1900)."-".$mon."-".$day;
return $stime;
}
sub GetNowDate8{
my ($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst) = localtime();
$mon = sprintf("%02d", $mon+1);
$day = sprintf("%02d", $day);
my $stime = ($year+1900).$mon.$day;
return $stime;
}
#判断当前日期所属的频率(每天,每星期,每半月,每月,每季度,每年)
sub isRunCondition{
my $FLAG ="'01'";
my $year = substr($TX_DATE,0,4);
my $month = substr($TX_DATE,4,2);
my $day = substr($TX_DATE,6,2);
#判断是否闰年
my $isRunYear;
if(($year%4==0 && $year%100!=0) || $year%400==0){
$isRunYear = 1;
} else {
$isRunYear = 0;
}
#判断TX_DATE所在周的周末
my $timenum = Time::Local::timelocal(0, 0, 0, $day, $month-1, $year);
my @timestr = localtime($timenum);
my $wday = $timestr[6];
if ($wday==6){
$FLAG=$FLAG.",'02'";
}
#判断TX_DATE所在月的月末
my $Month_End;
if($month eq "01" || $month eq "03" || $month eq "05" || $month eq "07" || $month eq "08" || $month eq "10" || $month eq "12"){
$Month_End = "31";
} elsif($month eq "04" || $month eq "06" || $month eq "09" || $month eq "11"){
$Month_End = "30";
} elsif($month eq "02" && $isRunYear==1) {
$Month_End = "29";
} else {
$Month_End = "28";
}
if($Month_End eq $day){
$FLAG=$FLAG.",'03'";
}
#判断TX_DATE所在季的季末
my $Quarter_Month;
my $Quarter_End;
if($month eq "01" or $month eq "02" or $month eq "03") {
$Quarter_Month="03";
}elsif($month eq "04" or $month eq "05" or $month eq "06") {
$Quarter_Month="06";
}elsif($month eq "07" or $month eq "08" or $month eq "09") {
$Quarter_Month="09";
}elsif($month eq "10" or $month eq "11" or $month eq "12") {
$Quarter_Month="12";
}
if($Quarter_Month eq "03" || $Quarter_Month eq "12" ){
$Quarter_End ="31";
} elsif($Quarter_Month eq "09" || $Quarter_Month eq "06" ){
$Quarter_End ="30";
}
if($Quarter_Month.$Quarter_End eq $month.$day){
$FLAG=$FLAG.",'04'";
}
#判断TX_DATE所在半年末
my $Half_Month;
my $Half_End;
if($month eq "01" or $month eq "02" or $month eq "03" or $month eq "04" or $month eq "05" or $month eq "06") {
$Half_Month="06";
}elsif($month eq "07" or $month eq "08" or $month eq "09" or $month eq "10" or $month eq "11" or $month eq "12") {
$Half_Month="12";
}
if($Half_Month eq "12" ){
$Half_End ="31";
} elsif($Half_Month eq "06" ){
$Half_End ="30";
}
if($Half_Month.$Half_End eq $month.$day){
$FLAG=$FLAG.",'05'";
}
#年末
my $Year_End="1231";
if($Year_End eq $month.$day){
$FLAG=$FLAG.",'06'";
}
return $FLAG;
}
#方法调用,程序入口
my $rc = main();#函数的入口
exit($rc);#这里的exit内容可以被ETL接收到
相关推荐
数据质量管理的机制对企业至关重要,包括数据报告和初步数据评估,这些步骤帮助识别数据的结构、内容、规则和关系,以及数据的健康状态。通过50个检查项,企业可以更深入地检查数据的各个方面,提升数据质量,从而...
1. **规则引擎**:用于执行自定义的数据质量检查规则,支持热插拔,便于维护和升级。 2. **JOB引擎**:调度和执行监控任务。 3. **告警引擎**:当检测到数据质量问题时,触发告警机制。 4. **监控结果分析**:提供对...
规则配置管理模块作为Java Web应用程序部署在金融数据平台Tomcat集群上,数据质量管理员可以通过统一的Web服务访问,实现检查规则的维护。检查执行模块作为多个ETL任务部署在金融数据平台ETL服务器上,由Automation...
数据源检验主要检查数据的时效性(是否按时到达)、完整性(与代码表的一致性、记录数检查)、原则性(字段数值是否合法)和逻辑性(字段间的逻辑关系)。这些检验通过一系列规则来实施,例如,所有代码表和数据表都...
针对设备装置领域的应用,数据质量的管理尤为重要,因为这直接影响到设备的运行效率、故障预测和维护策略。本文将深入探讨“根据用户应用程序要求改写数据质量规则的方法和系统”的主题,旨在提供一种灵活且定制化的...
第八章质检结果详细展示了数据检查后的状态,帮助用户识别和修复问题。 第九章导入情况部分,解释了数据导入过程中的注意事项,以及如何检查和处理导入失败的情况。 第十章比对检查介绍了系统如何对比不同数据源,...
规则定义部分可以自定义数据检查的逻辑,比如字段非空检查、数值范围检查等。 在配置完成后,用户需要启动Anubis服务,通常可以通过命令行或者图形界面进行。对于初学者,图形界面可能更为直观,但熟练掌握命令行...
3. **数据治理服务团队**提供技术支持和服务,包括数据质量规则的技术评估、执行数据质量检查、协助解决数据质量问题等。 4. **公司总部各部门**负责职能领域内的数据质量管理执行: - 制定和管理数据质量需求和...
**监控管理**允许用户定义数据质量检查方案,包括检查范围、时间、规则、评分规则和评估报告。这些方案可以手动或自动调度,以便定期执行数据质量检查。 **结果管理**收集和存储质量检查的结果,包括对象名称、时间...
数据质量是信息技术领域中的核心议题,尤其是在大数据时代,高质量的数据对于企业决策、业务运营和数据分析至关重要。石秀峰先生的“浅析数据质量管理体系与方法”深入探讨了如何构建有效的数据质量管理机制,确保...
SonarQube JAVA检查规则指南 SonarQube 是一个广泛使用的静态代码分析工具,用于检查 Java 项目中的 bug、漏洞和坏味道。 SonarQube 提供了许多内置规则,用于检查 Java 代码的质量和安全性。下面是 SonarQube 中的...
4.3 执行检查:运行MapGis数据检查功能,系统自动扫描并记录问题。 4.4 分析结果:查看检查报告,识别问题所在,分析错误原因。 4.5 错误修复:依据检查结果,对数据进行修正。 4.6 再次检查:修复后再次进行数据...
- 当前数据清洗面临的主要问题在于:数据检查和修复操作要么依赖于硬编码,要么依赖人工判断(文献[5])。 硬编码的问题在于缺乏灵活性,一旦数据定义发生变化就需要重新编写和编译代码。而人工判断的方法虽然可以...
算法是分析方法的具体实现,首先详细介绍了基于关联规则分析的Apriori算法、FP-growth 算法和Eclat算法,并通过对比这些算法在不同数据集的运行结果,分析了算法各自的优缺点及其适用领域,同时探讨了各个算法的优势...
总的来说,《中国移动省级NG2-BASS(v4.0)技术规范数据质量管理子系统分册》是一份详细的技术文档,它不仅为数据质量管理子系统的设计、实施和运行提供了标准化指导,更是通过有效的数据质量管理提高了业务分析的精度...
1. **质量检查规则管理**:允许用户自定义数据质量检查规则,确保数据符合特定的质量标准。 2. **绩效管理**:通过对数据质量的持续跟踪和评估,实现对数据质量绩效的有效管理。 3. **工作流管理**:支持定义复杂的...
接着,利用验证引擎根据这些规则检查源数据和目标数据,记录校验结果。修正引擎则依据校验结果进行自动或手动修正,并保存修改记录。数据分析和管理过程中,要通过校验结果发现问题,参考修正记录提出改进策略。项目...
数据仓库之数据质量建设是构建高效、可靠的决策支持系统的关键环节。...通过制定和执行严格的质量标准,可以在早期发现问题并及时解决,避免后期大规模的数据清洗工作,确保数据仓库的稳定运行和数据分析的可靠性。
最后,数据管控门户作为企业数据管控的统一入口,它整合了元数据管理、数据质量检查、数据标准执行监控和数据安全管理等功能。通过门户,企业能够实现人员、流程和技术的有效整合,降低风险,提高数据管理的效率和...
将数据质量规则集成到日常的数据处理流程中,确保数据的一致性和准确性。 ##### 步骤5:检查异常并完善规则 持续监控数据质量,发现并修正规则中的不足之处。 ##### 步骤6:对照目标,监测数据质量 定期评估数据...