1、kettle知识点系列之kettle的循环模式
这种模式是在我使用复杂模式后,我连接的资源库常常会因为这个循环导致速度慢、卡等问题,最后发现了这种模式。这种模式是在我解决问题的过程中自己写的,刚开始我使用简单模式处理场景需求,但是我的作业比较复杂,循环需要执行的地方是作业,作业中又有很多作业,作业中的转换又有。这是我个人做的一个循环demo作业,对于简单模式的循环,一般执行的循环体为转换,如果为作业,作业中不能有。组件,这样导致每次循环控制都是
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循环的例子,欢迎大家查看,如有问题请大家留言指出。
更多推荐
所有评论(0)