kettle知识点系列之kettle的循环模式

在kettle的使用过程中难免会用到一些循环的操作,我这里总结了三种循环模式:简单模式、复杂模式、推荐模式。以下作业均围绕此场景描述展开。
场景描述:现有一个任务需求,要将n多个服务器下的m多个实例中的数据同步到同一个实例中,这些实例中数据库名称一致,密码可能不同,库中的表名都一致、但是库中的字段可能有差异,但是差异很小。

1、简单模式

这种循环方法网上很常见,但是不一定满足个人需求。这是我个人做的一个循环demo作业,对于简单模式的循环,一般执行的循环体为转换,如果为作业,作业中不能有复制记录到结果集组件,否则在循环的过程中获取的db配置会被覆盖掉。以下我对整个作业的基本组件内容贴出来。
(1)总任务
在这里插入图片描述
(2)转换
在这里插入图片描述
表输入内容:这里我是从数据库查询其他数据库的连接信息。

SELECT  
QXDMMC, 
QXDM ,
TARGET_HOST ,
TARGET_PORT,
TARGET_DB ,
SOURCE_HOST,
SOURCE_PORT,
SOURCE_DB,
SOURCE_PWD,
PASSWORD,
COM_HOST,
COM_PORT,
COM_DB,
SOURCE_PWD,
TARGET_PWD,
TARGET_USER,
SOURCE_USER,
COM_USER,
US_USER,
rownum as i
FROM  xxxx(表名)

(3)设置变量 :这是写的脚本设置变量

var prevRow=previous_result.getRows();//获取上一个传递的结果
if (prevRow == null &&(prevRow.size()=0))
{
    false;
}else{
	var myobj = prevRow.get(0);
	//设置db连接参数
   parent_job.setVariable("QXDM",myobj.getString("QXDM","QXDM"));
   parent_job.setVariable("QXDM",myobj.getString("QXDMMC","QXDMMC"));
   //这里其他参数都是这种写法,就不一一写了。
	
    parent_job.setVariable("DB_CONFIG", prevRow);//ArrayList存储
    parent_job.setVariable("size", prevRow.size());//存储执行表的总数量
    parent_job.setVariable("i", 0);//循环控制变量
	parent_job.setVariable("DB_CONFIG_ITEM",myobj);
    true;
}

(4)检测字段的值:这里主要控制循环的停止
在这里插入图片描述
(5)循环控制(js脚本)

var prevRow=previous_result.getRows();//获取上一个传递的结果
var i=new Number(parent_job.getVariable("i"));//获取循环变量
var size=new Number(parent_job.getVariable("size"));//循环总数
i++

if(i<size) {
	var myobj =  prevRow[i];
	parent_job.setVariable("DB_CONFIG_ITEM",myobj );
	//设置db连接新参数
	parent_job.setVariable("QXDM",myobj.getString("QXDM","QXDM"));
parent_job.setVariable("QXDM",myobj.getString("QXDMMC","QXDMMC"));
//这里其他参数都是这种写法,就不一一写了。
}
parent_job.setVariable("i", i);//变量加1
true;

(6)设置变量的使用。在转换中设置数据库的地方填写如下格式变量即可。
在这里插入图片描述

2、复杂模式

这种模式是在我解决问题的过程中自己写的,刚开始我使用简单模式处理场景需求,但是我的作业比较复杂,循环需要执行的地方是作业,作业中又有很多作业,作业中的转换又有复制记录到结果集组件,这样导致每次循环控制都是下标越界异常,最后发现是因为后续的复制记录到结果集覆盖掉了获取DB参数那里的结果集。因此有了如下解法。
(1)总任务
在这里插入图片描述

(2)获取DB配置
在这里插入图片描述
表输入:将记录拼接成JSON字符串

SELECT  ('{"QXDMMC":"'  || QXDMMC 
|| '","QXDM":"' 				|| QXDM 
|| '","TARGET_HOST":"'  || TARGET_HOST 
|| '","TARGET_PORT":"'  || TARGET_PORT
|| '","TARGET_DB":"'    || TARGET_DB 
|| '","SOURCE_HOST":"'  || SOURCE_HOST
|| '","SOURCE_PORT":"'  || SOURCE_PORT
|| '","SOURCE_DB":"'    || SOURCE_DB
|| '","SOURCE_PWD":"'   || SOURCE_PWD
|| '","PASSWORD":"'     || PASSWORD
|| '","COM_HOST":"'     || COM_HOST
|| '","COM_PORT":"'     || COM_PORT
|| '","COM_DB":"'       || COM_DB
|| '","SOURCE_PWD":"'   || SOURCE_PWD
|| '","TARGET_PWD":"'   || TARGET_PWD
|| '","TARGET_USER":"'  || TARGET_USER
|| '","SOURCE_USER":"'  || SOURCE_USER
|| '","COM_USER":"'     || COM_USER
|| '","US_USER":"'      || US_USER
|| '"}'
) AS QXDM
FROM  xxxx(表名)

(3)设置变量:注意这里js脚本用到了eval()函数,不懂得自行百度。

var prevRow=previous_result.getRows();//获取上一个传递的结果
if (prevRow == null &&(prevRow.size()=0))
{
    false;
}else{
	var myobj =  eval('(' + prevRow.get(0) + ')');
	//设置db连接参数
	parent_job.setVariable("QXDM",myobj[0].QXDM);
	parent_job.setVariable("QXDMMC",myobj[0].QXDMMC);
	parent_job.setVariable("TARGET_HOST",myobj[0].TARGET_HOST);
	parent_job.setVariable("TARGET_PORT",myobj[0].TARGET_PORT);
	parent_job.setVariable("TARGET_DB",myobj[0].TARGET_DB);
	parent_job.setVariable("SOURCE_HOST",myobj[0].SOURCE_HOST);
	parent_job.setVariable("SOURCE_PORT",myobj[0].SOURCE_PORT);
	parent_job.setVariable("SOURCE_DB",myobj[0].SOURCE_DB);
	parent_job.setVariable("COM_HOST",myobj[0].COM_HOST);
	parent_job.setVariable("COM_PORT",myobj[0].COM_PORT);
	parent_job.setVariable("COM_DB",myobj[0].COM_DB);
	parent_job.setVariable("PASSWORD",myobj[0].PASSWORD);
	parent_job.setVariable("SOURCE_PWD",myobj[0].SOURCE_PWD);
	parent_job.setVariable("TARGET_PWD",myobj[0].TARGET_PWD);
	parent_job.setVariable("TARGET_USER",myobj[0].TARGET_USER);
	parent_job.setVariable("SOURCE_USER",myobj[0].SOURCE_USER);
	parent_job.setVariable("COM_USER",myobj[0].COM_USER);
	parent_job.setVariable("US_USER",myobj[0].US_USER);
    parent_job.setVariable("DB_CONFIG", prevRow);//ArrayList存储
    parent_job.setVariable("size", prevRow.size());//存储执行表的总数量
    parent_job.setVariable("i", 0);//循环控制变量
	parent_job.setVariable("DB_CONFIG_ITEM",myobj);
    true;

}

(4)检测字段的值
在这里插入图片描述
(5)循环控制

var prevRow =  eval('(' + parent_job.getVariable("DB_CONFIG") + ')');
var i=new Number(parent_job.getVariable("i"));//获取循环变量
i++
var size=new Number(parent_job.getVariable("size"));//循环总数
if(i<size) {
	var myobj =  prevRow[i];
	parent_job.setVariable("DB_CONFIG_ITEM",myobj[0]);
	//设置db连接新参数
	parent_job.setVariable("QXDM",myobj[0].QXDM);
	parent_job.setVariable("QXDMMC",myobj[0].QXDMMC);
	parent_job.setVariable("TARGET_HOST",myobj[0].TARGET_HOST);
	parent_job.setVariable("TARGET_PORT",myobj[0].TARGET_PORT);
	parent_job.setVariable("TARGET_DB",myobj[0].TARGET_DB);
	parent_job.setVariable("SOURCE_HOST",myobj[0].SOURCE_HOST);
	parent_job.setVariable("SOURCE_PORT",myobj[0].SOURCE_PORT);
	parent_job.setVariable("SOURCE_DB",myobj[0].SOURCE_DB);
	parent_job.setVariable("COM_HOST",myobj[0].COM_HOST);
	parent_job.setVariable("COM_PORT",myobj[0].COM_PORT);
	parent_job.setVariable("COM_DB",myobj[0].COM_DB);
	parent_job.setVariable("PASSWORD",myobj[0].PASSWORD);
	parent_job.setVariable("SOURCE_PWD",myobj[0].SOURCE_PWD);
	parent_job.setVariable("TARGET_PWD",myobj[0].TARGET_PWD);
	parent_job.setVariable("TARGET_USER",myobj[0].TARGET_USER);
	parent_job.setVariable("SOURCE_USER",myobj[0].SOURCE_USER);
	parent_job.setVariable("COM_USER",myobj[0].COM_USER);
	parent_job.setVariable("US_USER",myobj[0].US_USER);
	
}
parent_job.setVariable("i", i);//变量加1
true;

(6)使用
在这里插入图片描述
3、推荐模式
这种模式是在我使用复杂模式后,我连接的资源库常常会因为这个循环导致速度慢、卡等问题,最后发现了这种模式。这种模式个人极力推荐,非常好用,比前两种好用。接下来对其进行详细介绍。
(1)总任务
在这里插入图片描述
(2)设置DB
在这里插入图片描述

表输入:

SELECT  QXDMMC, 
QXDM ,
TARGET_HOST ,
TARGET_PORT,
TARGET_DB ,
SOURCE_HOST,
SOURCE_PORT,
SOURCE_DB,
SOURCE_PWD,
PASSWORD,
COM_HOST,
COM_PORT,
COM_DB,
SOURCE_PWD,
TARGET_PWD,
TARGET_USER,
SOURCE_USER,
COM_USER,
US_USER,
rownum as i
FROM  xxx(表名)

(3)循环控制:切记必须勾选,否则无法循环
在这里插入图片描述
(4)作业:圈起来的转换必须要
在这里插入图片描述
(5)设置数据库连接变量:就是设置数据连接转换
在这里插入图片描述
从结果获取记录:
在这里插入图片描述
设置变量:
在这里插入图片描述
(6)用法:与其他模式一致。
在这里插入图片描述
以上就是我总结的有关kettle循环的例子,欢迎大家查看,如有问题请大家留言指出。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐