1 概述

1.1 版本

服务器版本
v8.0.0及之后版本

1.2 应用场景

场景一:用户需要从 API 接口取数, API 接口的参数来自数据库内的一列字段。由于 API 接口中,参数每次只能读取一个参数值,所以需要将数据库的某列字段值逐个输出为参数,遍历所有参数从 API 接口取数。
场景二:数据量非常大时,用户希望分段执行,每次只取出一段时间内的数据,直至取出所有时间段内的数据。

1.3 功能简介

【循环容器】节点+参数 联合使用,可满足分批抽取数据的场景。

2 使用限制

1、参数赋值的参数只能给其下游节点使用,循环容器内也是一样的。
2、【循环容器】节点内不能拖入的节点类型:【子任务】节点和【循环容器】节点。

3 功能说明

3.1 遍历循环

3.1.1 使用说明

【循环容器】节点前,需要使用【参数赋值】节点或者【数据转换-参数输出】算子输出参数,然后在【循环容器】中遍历所有参数从数据库/API接口中取数。

注:每次循环使用的参数,来自任务参数。

为便于理解,下面以一个示例说明遍历循环。
场景:
API 接口中包含参数“产品Id”,可取出特定“产品Id”的接口数据。
现在“产品Id”保存在数据库中,希望取出这些“产品Id”对应的接口数据,其中 API 接口每次只能取出一个“产品Id”对应的数据。
方案:
使用【参数赋值】节点将保存在数据库中的“产品Id”取出并输出为参数,将这些参数传递给【循环容器】。
【循环容器】中拖入【单表同步】节点从 API 接口取数,每次取数时只使用一个 “产品Id” ,直到所有“产品Id”都被使用停止循环。

注:【参数赋值】节点中建议设置一个调试值(默认值),便于下游节点引用参数后查看效果,调试值不参与实际运行。

3.1.2 循环限制

循环次数上限。默认1000次,用户可手动调整,上限为10000次,必填。

3.1.3 循环方式

支持两种循环方式:遍历循环(foreach)、条件循环(do-while)。

1)遍历循环:遍历循环参数(数组)中的元素,遍历结束则循环结束,循环次数与遍历对象的元素个数一致。循环次数由字段值的个数决定。

  • 当遍历值不为空时,返回布尔值:true,继续下一次循环;
  • 当遍历值为空时,返回布尔值:false,结束容器内的循环。

2)条件循环:说明请参见本文 3.2 节内容。

3.1.4 遍历参数

选择当前任务的任务参数,选择的参数逐行获取值,未选择的参数直接获取值。

  • 当选择遍历循环(foreach)时,必须选择遍历参数。
  • 当选择条件循环(do-while)时,遍历参数可选。

【遍历参数】一般设置为循环容器上游的参数赋值节点输出的参数,可以选择单个或多个。

3.1.5 执行条件

当选择遍历循环(foreach)时,无需配置执行条件,所选参数输出的结果遍历完时结束循环。

3.1.6 容错机制

若用户希望循环容器内能忽略节点的报错继续执行循环,而不是停止下一次循环。例如:API循环取数时取出数据为空中出现的循环取数时,一次获取的批量数据可能为空,则希望此时还能继续执行循环取数,则可使用该功能。

  • 默认不勾选:当一次循环中有节点执行报错,不再进行下一次循环。
  • 当勾选时:循环容器中有一个节点报错时,继续执行循环(在日志中需要输出单次循环中的错误信息),此循环容器的执行结果还是执行失败。

3.2 条件循环

3.2.1 使用说明

条件循环需要同时满足以下两个条件:

  • 具备每次循环取数的参数:使用参数赋值、参数输出等,设置每次循环取数需要用到的参数。参数可以来自容器外,也可以来自容器内。
  • 具备循环结束条件:根据实际场景设置循环结束条件,当不符合循环条件时,结束循环。

3.2.2 循环方式

循环限制、容错机制详细说明请参见本文 3.1 章节内容。

条件循环:
先执行一次循环体,再判断条件。设定循环执行和结束的条件,循环次数由条件决定。

  • 当条件判断返回布尔值:true,继续下一次循环;
  • 当条件判断返回布尔值:false,结束容器内的循环。

3.2.3 执行条件

循环方式为“条件循环”时,必须配置“执行条件”。
需要设定结束条件,条件中的参数可以是循环容器外的参数,也可以是循环容器内的参数。
循环容器的条件循环是 do-while 循环,特点是第一次执行循环时,不论执行条件是否满足,都会执行;第一次之后的循环需要满足执行条件。

4 日志说明

若离线任务中包含【循环容器】节点,运行任务后,“日志”下会展示最近10 次循环信息。如下图所示:

5 例子

本节通过一个完整示例,演示【循环容器】节点在“按月分批同步数据”场景下的完整配置过程。示例采用条件循环(do-while),对应本文 1.2 节”场景二:数据量非常大时,分段执行”。

5.1 示例场景

业务背景:将源表 src_monthly_data 中的数据按月分批同步到目标表 ods_monthly_data,同步范围为 2025-01 至 2025-10 共 10 个月。

实现思路:使用【循环容器】节点,每次循环只同步当月数据,同步完成后将”同步时间”加 1 个月,继续处理下个月,直到”同步时间”超过”最大截止日期”时结束循环。

5.1.1 前置准备:建表与测试数据

本示例以达梦数据库为例,若使用其他数据库,SQL 语法需相应调整。

源表与目标表结构一致,字段如下:

字段名 类型 说明
id BIGINT 主键
user_name VARCHAR(50) 姓名
age INT 年龄
amount DECIMAL(10,2) 金额
gmt_create DATETIME 创建时间(按月过滤的关键字段

建源表(达梦语法,主键自增使用 IDENTITY):

CREATE TABLE src_monthly_data (
    id BIGINT IDENTITY(1,1) NOT NULL,
    user_name VARCHAR(50),
    age INT,
    amount DECIMAL(10,2),
    gmt_create DATETIME,
    PRIMARY KEY (id)
);
COMMENT ON TABLE src_monthly_data IS '按月分批同步-源表';
COMMENT ON COLUMN src_monthly_data.id IS '主键';
COMMENT ON COLUMN src_monthly_data.user_name IS '姓名';
COMMENT ON COLUMN src_monthly_data.age IS '年龄';
COMMENT ON COLUMN src_monthly_data.amount IS '金额(元)';
COMMENT ON COLUMN src_monthly_data.gmt_create IS '创建时间(按月过滤字段)';

建目标表(结构与源表一致,id 无需自增):

CREATE TABLE ods_monthly_data (
    id BIGINT NOT NULL,
    user_name VARCHAR(50),
    age INT,
    amount DECIMAL(10,2),
    gmt_create DATETIME,
    PRIMARY KEY (id)
);
COMMENT ON TABLE ods_monthly_data IS '按月分批同步-目标表';

插入测试数据:向源表插入 2025-01 至 2025-10 共 10 个月、每月 4 条的数据,共 40 条。完整 INSERT 语句见配套文件 test_data_dm.sql,数据分布如下:

月份 姓名 数据条数
2025-01 张伟、王芳、李娜、刘强 4
2025-02 陈静、杨洋、赵敏、黄磊 4
2025-03 周杰、吴倩、徐明、孙丽 4
2025-04 张伟、王芳、李娜、刘强 4
2025-05 陈静、杨洋、赵敏、黄磊 4
2025-06 周杰、吴倩、徐明、孙丽 4
2025-07 张伟、王芳、李娜、刘强 4
2025-08 陈静、杨洋、赵敏、黄磊 4
2025-09 周杰、吴倩、徐明、孙丽 4
2025-10 张伟、王芳、李娜、刘强 4

每条数据的 gmt_create 分布在对应月份的 1 / 8 / 15 / 22 日。

5.2 任务参数配置

循环开始前,需要在任务级别定义两个”全局变量”,作为循环的起点和终点。

参数名称 类型 取值方式 初始值 作用
同步时间 日期 常量 2025-01-01 每次循环处理的月份起点,容器内每轮循环结束后 +1 个月
最大截止日期 日期 常量 2025-11-01 循环结束条件:同步时间超过该日期时停止

注:任务参数必须先建好并保存,否则下游【循环容器】中引用 ${同步时间} / ${最大截止日期} 会报”参数未定义”。

配置位置:任务编辑画布 → 顶部菜单”任务参数” → 弹出任务参数弹窗 → 填写名称/类型/值 → 保存。

5.3 节点配置

整体流程(参数赋值 → 循环容器 → SQL 脚本 → 单表同步 → +1 月赋值 → 结束):

  参数赋值(容器外)          循环容器
  ┌──────────┐           ┌──────────────────────────────┐
  │ 同步时间  │ ────────▶ │  ┌────┐  ┌────┐  ┌────────┐  │
  │ 截止日期  │           │  │SQL │→ │单表 │→ │+1月赋值│  │
  └──────────┘           │  │脚本 │  │同步 │  └────────┘  │
                          │  └────┘  └────┘              │
                          └──────────────────────────────┘

5.3.1 参数赋值节点(容器外)

用于将任务参数传递给【循环容器】。该节点含 3 个 Tab:

(1)节点信息:节点名称建议设置为能体现用途的名称,如”初始化参数”。

(2)输出参数:点击”+ 添加参数”添加 2 行:

任务参数 值类型
同步时间 常量 2025-01-01
最大截止日期 常量 2025-11-01

(3)数据来源:值类型为”常量”时无需配置,保持默认即可。

5.3.2 循环容器节点

从左侧节点面板”流程”分类拖入【循环容器】节点,并用连线将【参数赋值】连到【循环容器】。双击打开配置:

配置项 取值 说明
循环方式 条件循环(do-while) 按时间段循环,循环次数由条件决定
执行条件 见下方公式 满足条件则继续循环
遍历参数 (空) 条件循环无需遍历参数
容错机制 不勾选 同步任务失败应立即停止,避免脏数据
循环限制 1000(默认) 保险值,防止死循环

执行条件公式

daysbetween(datetime(${同步时间},"yyyy-MM-dd"),datetime(${最大截止日期},"yyyy-MM-dd")) > 0

公式解读:将”同步时间”与”最大截止日期”按 yyyy-MM-dd 格式解析为日期并计算天数差,差值大于 0 则继续循环,否则结束循环。

当前轮次 同步时间 最大截止日期 daysbetween 结果 继续循环?
1 2025-01-01 2025-11-01 304
2 2025-02-01 2025-11-01 273
…… …… …… ……
10 2025-10-01 2025-11-01 31
11 2025-11-01 2025-11-01 0 否(结束循环)

注:条件循环是 do-while 循环,第一次先执行循环体,再判断条件。因此第 11 轮会先同步完当月数据,再判断 daysbetween = 0 不满足,循环结束。

5.3.3 SQL 脚本节点(容器内)

双击进入循环容器内部,从”脚本”分类拖入【SQL 脚本】节点。该节点用于循环内的预处理,例如计算当月数据范围、写临时表等。

配置项 取值 说明
数据源 选择源数据源连接 脚本要操作的库
配置方式 SQL 一般选 SQL
SQL 语句 见下方示例 可引用 ${同步时间} 等参数

SQL 语句示例(验证参数可正确取到):

SELECT '${同步时间}' AS current_month, '${最大截止日期}' AS max_deadline FROM dual;

5.3.4 单表同步节点(容器内)

从”基础”分类拖入【单表同步】节点,连线【SQL 脚本】→【单表同步】。单表同步节点含 3 个 Tab。

(1)数据来源

配置项 取值 说明
来源类型 数据连接 一般选数据连接
数据库 选择源数据源连接 例如”AI财开内网数据库”
表/视图 src_monthly_data 源表
过滤条件 见下方公式 按月取数的核心

过滤条件(达梦语法):

gmt_create >= '${同步时间}' AND gmt_create < ADD_MONTHS('${同步时间}', 1)

注:${同步时间} 每轮循环会自动替换为当月 1 号,因此每次只同步当月数据。其他数据库的”加 1 月”函数不同,例如 MySQL 使用 DATE_ADD('${同步时间}', INTERVAL 1 MONTH)

(2)数据去向

配置项 取值 说明
目标数据库 选择目标数据源连接 同库则与源一致
目标表 ods_monthly_data 目标表
字段映射 同名自动映射 源字段与目标字段同名时自动对应
主键 id 用于写入模式判断

(3)写入模式

模式 行为 适用场景
插入更新 按主键:有则更新、无则插入 分批同步首选
仅更新 只更新已存在行,不插入新行 历史数据修正
追加 永远追加,重复数据会产生多行 日志/流水类数据
指定目标表后追加 追加到指定后缀的表 按月分表存储

注:分批同步场景必须选择”插入更新”。若选择”追加”,同一月数据在多轮循环中会重复写入,产生重复行。

5.3.5 参数赋值节点(容器内,每轮 +1 月)

在容器内【单表同步】之后,再拖入一个【参数赋值】节点,连线【单表同步】→【参数赋值】。该节点负责在每轮循环结束后将”同步时间”加 1 个月。

配置项 取值 说明
任务参数 同步时间 与容器外同名
值类型 表达式 必须选表达式,不能选常量
dateadd(month, 1, '${同步时间}', 'yyyy-MM-dd') 关键公式
调试值 2025-01-01 与初始值一致

注:值类型必须选择”表达式”。若选择”常量”并写死为 2025-02-01,会导致每个月都同步 1 月数据,无法推进循环。

5.4 试运行与验证

  1. 点击画布顶部”试运行”→ 选择业务日期 → 运行。
  2. 在”运行日志” Tab 观察循环信息(最近 10 次循环,参见本文第 4 节)。

验证清单

检查项 通过标准
循环次数 运行日志中循环次数 = 10
目标表行数 40 条
月份完整性 2025-01 ~ 2025-10,无缺失
退出条件 最后一轮同步时间 = 2025-11-01,daysbetween = 0 退出
无重复数据 写入模式选”插入更新”,无重复行

5.5 常见问题

  1. 首次执行时报”参数未定义”:检查任务参数是否已保存,参数名与下游引用是否完全一致(含空格、大小写)。

  2. 循环只跑 1 次就结束:检查执行条件公式中日期格式 yyyy-MM-dd 是否正确;容器内【参数赋值】的”加 1 月”表达式是否正确。

  3. 某月数据重复同步:检查【单表同步】写入模式是否误选为”追加”,应改为”插入更新”。

  4. 加 1 月不生效:检查容器内【参数赋值】的值类型是否误选为”常量”,应为”表达式”。

  5. 达梦数据库日期过滤报错:确认过滤条件使用的是达梦函数 ADD_MONTHS,而非 MySQL 的 DATE_ADD

作者:fancy  创建时间:2025-09-30 14:30
最后编辑:曾伟峰  更新时间:2026-08-19 18:10