kettle9.0 根据条件从表中获取记录 然后根据主键进行插入/更新操作
一、需求:想实现增量同步,根据条件查询对应的数据,然后根据主键进行操作,如果有则更新,没有则新增。目标中需要添加一个字段(org_id)用来区分是从那个表中获取的数据
1、新建一个任务,因为一个转换里面的数据都是异步处理的,所以不能放在一个转换里面,需要建两个转换。工作里面是按照步骤来的。

2、第一个转换是获取当前表的字段信息

获取表的字段sql:
SELECT
-- 拼接所有字段名(按ORDINAL_POSITION排序,逗号分隔)
GROUP_CONCAT(COLUMN_NAME ORDER BY ORDINAL_POSITION SEPARATOR ',') AS FIELD_LIST,
-- 取主键字段(无主键时返回空,需确保表有主键)
MAX(CASE WHEN COLUMN_KEY = 'PRI' THEN COLUMN_NAME ELSE NULL END) AS PK_FIELD
FROM information_schema.columns
WHERE table_schema = DATABASE()
AND table_name = '${TABLE_NAME}';
3、第二个转换查询数据进行处理同步

(1)表记录查询:查询今年的数据(查询的时候,需要给目标表添加一个字段用来区分是从那个公司同步的数据)
SELECT * , '${company_id}' AS org_id FROM ${TABLE_NAME}
where gmt_modified >= CONCAT(YEAR(NOW()), '-01-01 00:00:00')
AND gmt_modified <= NOW();
(2)脚本内容:形成sql语句放在常量 (DYNAMIC_VALUES)里面
//Script here
// 1. 获取当前行的所有字段名(自动识别,无需手动输入)
var fieldNames = getFieldNames();
// 2. 初始化字段值数组(用于存储拼接后的每个字段值)
var valueArray = [];
// 3. 遍历所有字段,自动处理类型转义(字符串加单引号,数值直接保留)
for (var i = 0; i < fieldNames.length; i++) {
var fieldName = fieldNames[i];
var fieldValue = getVariable(fieldName); // 自动获取字段值
// 处理null值(转为空字符串)
if (fieldValue === null || fieldValue === undefined) {
valueArray.push("''"); // 字符串类型空值
continue;
}
// 自动判断字段类型,处理转义
var fieldType = getFieldType(fieldName); // 自动获取字段类型
if (fieldType === "String" || fieldType === "Date" || fieldType === "Timestamp") {
// 字符串/日期类型:加单引号,转义单引号(避免SQL语法错误)
var escapedValue = fieldValue.toString().replace(/'/g, "''");
valueArray.push("'" + escapedValue + "'");
} else {
// 数值类型(int/double等):直接保留原值
valueArray.push(fieldValue.toString());
}
}
// 4. 拼接所有字段值为逗号分隔字符串(格式:'1','张三',25,'2025-12-03')
var dynamicValues = valueArray.join(',');
// 5. 将拼接结果存入之前的DYNAMIC_VALUES字段,供后续SQL使用
setVariable("DYNAMIC_VALUES", dynamicValues);
(3)执行SQL
INSERT INTO ${TARGET_TABLE} (${FIELD_LIST}, org_id) -- 新增org_id字段
VALUES (${DYNAMIC_VALUES})
ON DUPLICATE KEY UPDATE
${REPLACE(FIELD_LIST, ',', ' = VALUES(\\1), ')}, org_id = VALUES(org_id); -- 同步更新org_id
浙公网安备 33010602011771号