利用kettle的JS進(jìn)行ETL數(shù)據(jù)校驗(yàn)(升級(jí)版)

無意中在網(wǎng)上看到一篇文章《利用kettle中的JS來完成ETL數(shù)據(jù)校驗(yàn)》对竣,挺受啟發(fā)的派歌,覺得用JS來實(shí)現(xiàn)ETL的自動(dòng)化校驗(yàn),是個(gè)不錯(cuò)的思路潘明。但是這篇文章里給的JS腳本樣例確實(shí)有待改進(jìn)辐棒,一是讓初學(xué)者看著不那么清晰病曾,二是擴(kuò)展性和維護(hù)性都較差姊途。于是我做了二次改造,重新編寫了腳本知态,如下:

//Script here

var strConn = "TestOrcl";

var check_status=0;//如果檢測(cè)到有任何一種校驗(yàn)錯(cuò)誤,則check_status=1

var check_table="E_OT_PRMTALT";//校驗(yàn)有關(guān)的表名字

var check_table_id="LICALTID";//校驗(yàn)表主鍵

var check_name=LICALTID;//校驗(yàn)表主鍵值

var check_detail="";//校驗(yàn)到的錯(cuò)誤詳細(xì)情況

var check_type="";//校驗(yàn)到的錯(cuò)誤類型

var check_date=new Date();//校驗(yàn)時(shí)間

var source_table="E_OT_PRMTALT";//數(shù)據(jù)源表名稱立叛,如果數(shù)據(jù)來自多個(gè)數(shù)據(jù)表负敏,則需要聲明多個(gè)

var source_table_id="LICALTID";//數(shù)據(jù)源表主鍵,如果多個(gè)表聯(lián)合主鍵秘蛇,則需要聲明多個(gè)主鍵

/////////////////////////////字段唯一性校驗(yàn)//////////////////////////////////////////

var isuniqueArray=new Array("LICALTID","LICID");//一維數(shù)組其做,表的字段名

var isunique_str="";

var isunique_column="";

for(var i=0;i<isuniqueArray.length;i++){

//1:唯一性枚舉值

? isunique_str+="var "+isuniqueArray[i]+"_isunique=0;";

? //唯一性校驗(yàn)枚舉值賦值

? isunique_str+="var uniquesql_"+isuniqueArray[i]+"=\"SELECT count(1) FROM "+check_table+" where "+isuniqueArray[i]+"='\"+"+isuniqueArray[i]+"+\"' \";";

? isunique_str+="if(fireToDB(strConn,uniquesql_"+isuniqueArray[i]+")[0][0]==1){"+isuniqueArray[i]+"_isunique=1;}";

? //校驗(yàn)所有表需要校驗(yàn)的字段,如果有一個(gè)校驗(yàn)失敗赁还,則校驗(yàn)狀態(tài)為1

? isunique_str+="if(check_status==0){if("+isuniqueArray[i]+"_isunique==0)check_status=1;}";

? //check is unique? return not unique column

? isunique_str+="if("+isuniqueArray[i]+"_isunique==0){if(isunique_column==\"\"){ isunique_column = \""+ isuniqueArray[i] +"\";}else{isunique_column+=\"妖泄、\"+\""+isuniqueArray[i]+"\";}}";?

}

//最終輸出的錯(cuò)誤詳細(xì)情況

isunique_str+="if(check_status==1){check_type=\"違反唯一規(guī)則\";check_detail=\"表\"+source_table+\"中,字段\"+isunique_column+\"違反了唯一規(guī)則\";}";

eval(isunique_str);

//////////////////////////////////////////////////////////////////////////////////

/////////////////////////////字段非空校驗(yàn)//////////////////////////////////////////

var isnullArray=new Array("ALT","ALTBE","ALTAF","ALTDATE");//一維數(shù)組艘策,表的字段名

var isnull_str="";

var isnull_column="";

check_status=0;//校驗(yàn)狀態(tài)置0

for(var i=0;i<isnullArray.length;i++){

//2:非空枚舉值

isnull_str+="var "+isnullArray[i]+"_isnull=0;";

//非空校驗(yàn)枚舉值賦值

isnull_str+="if("+isnullArray[i]+"==null||"+isnullArray[i]+"==\"\"){"+isnullArray[i]+"_isnull=1;}";

//校驗(yàn)所有表需要校驗(yàn)的字段蹈胡,如果有一個(gè)校驗(yàn)失敗,則校驗(yàn)狀態(tài)為1

isnull_str+="if(check_status==0){if("+isnullArray[i]+"_isnull==1)check_status=1;}";

//check is null? return null column

isnull_str += "if("+isnullArray[i]+"_isnull==1){if(isnull_column==\"\"){isnull_column = \""+ isnullArray[i] +"\";}else{isnull_column+=\"朋蔫、\"+\""+isnullArray[i]+"\";}}";

}

//最終輸出的錯(cuò)誤詳細(xì)情況

isnull_str+="if(check_status==1){if(check_detail==\"\"){check_type=\"違反非空規(guī)則\";check_detail=\"字段\"+ isnull_column +\"違反了非空規(guī)則\";}else{check_type+=\",\"+\"違反非空規(guī)則\";check_detail+=\",字段\"+ isnull_column +\"違反了非空規(guī)則\";}}";

eval(isnull_str);

//////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////標(biāo)準(zhǔn)值校驗(yàn)//////////////////////////////////////////

var isnormalArray = [["S_EXT_FROMNODE","in ('220000')"],["ALT","in ('許可文件編號(hào)','許可文件名稱','許可機(jī)關(guān)','許可內(nèi)容')"]];//二維數(shù)組罚渐,第一列為字段,第二列為匹配規(guī)則

var isnormal_str="";

var isnormal_column="";

check_status=0;//校驗(yàn)狀態(tài)置0

for(var i=0;i<isnormalArray.length;i++){

//3:標(biāo)準(zhǔn)化枚舉值

isnormal_str+="var "+isnormalArray[i][0]+"_isnormal=0;";

//標(biāo)準(zhǔn)化校驗(yàn)枚舉值賦值

isnormal_str+="var normalsql_"+isnormalArray[i][0]+"= \"select? count(1) from "+check_table+" where "+ isnormalArray[i][0] +" "+isnormalArray[i][1]+" and "+check_table_id+"='"+check_name+"'\";";

isnormal_str+="if(fireToDB(strConn, normalsql_"+isnormalArray[i][0]+")[0][0]>0){"+ isnormalArray[i][0] +"_isnormal=1;}";

//校驗(yàn)所有表需要校驗(yàn)的字段驯妄,如果有一個(gè)校驗(yàn)失敗荷并,則校驗(yàn)狀態(tài)為1

isnormal_str+="if(check_status==0){if("+isnormalArray[i][0]+"_isnormal==0) check_status=1;}";

//check is normal? return not normal column

isnormal_str+="if("+isnormalArray[i][0]+"_isnormal==0){if(isnormal_column==\"\"){ isnormal_column = \""+ isnormalArray[i][0] +"\";}else{isnormal_column+=\"、\"+\""+isnormalArray[i][0]+"\";}}";

}

//最終輸出的錯(cuò)誤詳細(xì)情況

isnormal_str+="if(check_status==1){if(check_detail==\"\"){check_type=\"違反標(biāo)準(zhǔn)化規(guī)則\";check_detail=\"字段\"+ isnormal_column +\"違反了標(biāo)準(zhǔn)化規(guī)則\";}else{check_type+=\",\"+\"違反標(biāo)準(zhǔn)化規(guī)則\";check_detail+=\",字段\"+ isnormal_column +\"違反了標(biāo)準(zhǔn)化規(guī)則\";}}";

eval(isnormal_str);

//////////////////////////////數(shù)據(jù)類型校驗(yàn)//////////////////////////////////////////

var datatypeArray = [["ALTDATE","isDate"],["ALTAF","isNum"]];//二維數(shù)組青扔,第一列為要校驗(yàn)的數(shù)據(jù)字段源织,第二列為數(shù)據(jù)類型校驗(yàn)函數(shù)(isDate[日期]、isNum[數(shù)字]微猖、isMailValid[郵箱]谈息、isEmpty[空])

var datatype_str="";

var datatype_column="";

check_status=0;//校驗(yàn)狀態(tài)置0

for(var i=0;i<datatypeArray.length;i++){

//4:類型校驗(yàn)枚舉值

datatype_str+="var "+datatypeArray[i][0]+"_datatype=0;";

//數(shù)據(jù)類型校驗(yàn)枚舉值賦值

datatype_str+="var datatypesql_"+datatypeArray[i][0]+"=\"select "+datatypeArray[i][0]+" from "+ check_table +" where "+check_table_id+"='"+check_name+"'\";";

datatype_str+="if("+datatypeArray[i][1]+"(fireToDB(strConn,datatypesql_"+datatypeArray[i][0]+")[0][0])) "+ datatypeArray[i][0]+"_datatype=1;";

//校驗(yàn)所有需要校驗(yàn)的字段,如果有一個(gè)校驗(yàn)失敗励两,則校驗(yàn)狀態(tài)為1

datatype_str+="if(check_status==0){if("+datatypeArray[i][0]+"_datatype==0) check_status=1;}";

//check is datatype? return not datatype column

datatype_str+="if("+datatypeArray[i][0]+"_datatype==0){if(datatype_column==\"\"){ datatype_column =\""+datatypeArray[i][0]+"\";}else{datatype_column+=\"黎茎、"+datatypeArray[i][0]+"\";}}";

}

//最終輸出的錯(cuò)誤詳細(xì)情況

datatype_str+="if(check_status==1){if(check_detail==\"\"){check_type=\"違反數(shù)據(jù)類型規(guī)則\";check_detail=\"字段\"+datatype_column+\"違反數(shù)據(jù)類型規(guī)則\";}else{check_type+=\",\"+\"違反數(shù)據(jù)類型規(guī)則\";check_detail+=\",字段\"+datatype_column+\"違反數(shù)據(jù)類型規(guī)則\";}}";

eval(datatype_str);

//////////////////////////////////////////////////////////////////////////////////////

if(check_detail!="")

{

check_detail=check_detail+","+source_table_id+"="+check_name;

}

以下是執(zhí)行后的效果:

在此基礎(chǔ)上我們還可以擴(kuò)展更多的校驗(yàn),比如通過正則表達(dá)式的方式(利用kettle的isRegExp函數(shù))当悔,如下:

//////////////////////////////正則表達(dá)式校驗(yàn)//////////////////////////////////////////

var dataArray = [["Email","^\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,3}$","^[\\w-\.]+@([\\w-]+\\.)+[\\w-]{2,4}$"]];//二維數(shù)組傅瞻,第一列為要校驗(yàn)的數(shù)據(jù)字段,第二列為規(guī)則1盲憎,第三列為規(guī)則2(可選)

var data_str="";

var data_column="";

check_status=0;//校驗(yàn)狀態(tài)置0

for(var i=0;i

//4:類型校驗(yàn)枚舉值

data_str+="var "+dataArray[i][0]+"_data=0;";

//數(shù)據(jù)類型校驗(yàn)枚舉值賦值

data_str+="var datasql_"+dataArray[i][0]+"=\"select "+dataArray[i][0]+" from "+check_table+" where "+ check_table_id +"='"+check_name+"'\";";

data_str+="if(isRegExp(fireToDB(strConn,datasql_"+dataArray[i][0]+")[0][0],dataArray[i][1],dataArray[i][2] )>-1) "+dataArray[i][0]+"_data=1;";

//校驗(yàn)所有需要校驗(yàn)的字段嗅骄,如果有一個(gè)校驗(yàn)失敗,則校驗(yàn)狀態(tài)為1

data_str+="if(check_status==0){if("+dataArray[i][0]+"_data==0) check_status=1;}";

//check is data? return not data column

data_str+="if("+dataArray[i][0]+"_data==0){if(data_column==\"\"){data_column=\""+ dataArray[i][0] + "\"; } else {data_column+=\"饼疙、"+dataArray[i][0]+"\";}}";

}

//最終輸出的錯(cuò)誤詳細(xì)情況

data_str+="if(check_status==1){if(check_detail==\"\"){check_type=\"違反數(shù)據(jù)類型規(guī)則\";check_detail=\"字段\"+ data_column +\"違反數(shù)據(jù)類型規(guī)則\";}else{check_type+=\",\"+\"違反數(shù)據(jù)類型規(guī)則\";check_detail+=\",字段\"+ data_column + \"違反數(shù)據(jù)類型規(guī)則\";}}";eval(data_str);

以上腳本的好處就是溺森,可以直接通過修改變量慕爬,就能對(duì)不同輸出表的不同字段進(jìn)行校驗(yàn),基本上不用修改邏輯代碼屏积,如果進(jìn)一步優(yōu)化一下医窿,就可以寫成函數(shù),直接調(diào)用炊林±崖可以把檢驗(yàn)字段和檢驗(yàn)規(guī)則進(jìn)一步參數(shù)化,通過調(diào)用參數(shù)表渣聚,來執(zhí)行數(shù)據(jù)驅(qū)動(dòng)的校驗(yàn)測(cè)試(這就是一種自動(dòng)化測(cè)試的思路)独榴。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市奕枝,隨后出現(xiàn)的幾起案子棺榔,更是在濱河造成了極大的恐慌,老刑警劉巖隘道,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件症歇,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡薄声,警方通過查閱死者的電腦和手機(jī)当船,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來默辨,“玉大人德频,你說我怎么就攤上這事∷跣遥” “怎么了壹置?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)表谊。 經(jīng)常有香客問我钞护,道長(zhǎng),這世上最難降的妖魔是什么爆办? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任难咕,我火速辦了婚禮,結(jié)果婚禮上距辆,老公的妹妹穿的比我還像新娘余佃。我一直安慰自己,他們只是感情好跨算,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布爆土。 她就那樣靜靜地躺著,像睡著了一般诸蚕。 火紅的嫁衣襯著肌膚如雪步势。 梳的紋絲不亂的頭發(fā)上氧猬,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音坏瘩,去河邊找鬼盅抚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛倔矾,可吹牛的內(nèi)容都是我干的泉哈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼破讨,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了奕纫?” 一聲冷哼從身側(cè)響起提陶,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎匹层,沒想到半個(gè)月后隙笆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡升筏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年撑柔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片您访。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡铅忿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出灵汪,到底是詐尸還是另有隱情檀训,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布享言,位于F島的核電站峻凫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏览露。R本人自食惡果不足惜荧琼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望差牛。 院中可真熱鬧命锄,春花似錦、人聲如沸多糠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夹孔。三九已至被盈,卻和暖如春析孽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背只怎。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工袜瞬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人身堡。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓邓尤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親贴谎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汞扎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容