1. 概述
1.1 应用场景
SAP RFC 一次性取数过大时,驱动可能会崩溃,FDL 也可能会宕机。部分 RFC 函数提供了 ROWCOUNT、ROWSKIPS 和 date 参数,分别用于控制每次取多少行、从第几行开始取,以及按日期过滤数据。这些参数的逻辑与 API 获取数据时的偏移量类似。
然而,「SAP ERP输入」 并没有像「API 输入」算子那样提供高级设置来自动实现偏移量。
1.2 实现思路
本文示例中,从 MySQL 数据库表中取数模拟 SAP RFC 取数。
1)参数列表中新增参数times、size:
times:某个日期下的第几次取数,初始值设置为 0;例如每个日期下有 12 条数据, 每次取 5 条,需要 3 次才能取完。
size:每次取数条数,本文示例中,每次取 5 条数据。
2)将来源表中最早日期和最晚日期分别输出为参数日期、e_date。
3)「循环容器」执行条件为:日期<=e_date。「循环容器」节点中,每次最多读取 5 条数据,读取数据后,判断当前日期下数据是否取完:
如果当前日期下,数据未取完,「日期」参数值不变,「times」参数值需要加 1 继续取数。
如果当前日期下,数据取完,「times」需要恢复为 0,「日期」需要加 1 。
1.3 任务展示
FineDataLink 中的数据处理过程,详情参见:https://demo.finedatalink.com/ 「SAP RFC:日期+偏移量双重循环取数」。
2. 操作步骤
2.1 场景模拟
本文示例,从 MySQL 中取数模拟从 SAP RFC 取数。
待取数的表数据如下图所示:
点击展开更多 |
2.2 参数准备
2.2.1 取数参数准备
1)新建定时任务,点击「参数列表」,新增参数 times、size。如下图所示:
用户需根据实际情况设置 size 的值。参数说明如下表所示:
参数 | 说明 |
---|---|
times | 某个日期下的第几次取数,初始值设置为 0 例如每个日期下有 12 条数据, 每次取 5 条,需要 3 次才能取完 |
size | 每次取数条数,本文示例中,每次取 5 条数据 |
2.2.2 循环容器执行条件参数准备
本文示例中,我们需要将日期输出为参数,传递给循环容器,「循环容器」中根据 size、times 参数取数,直至该日期下数据取完。循环执行条件为:日期参数<=最大日期,所以我们先准备「循环容器」执行条件参数。
1)拖入「数据转换」节点,进入「数据转换」节点。
2)拖入「Spark SQL」算子,构建待取数表中最早日期和最晚日期,用户需根据实际情况设置最早日期和最晚日期值。
本文示例 SQL语句:
SELECT '2024-09-01' AS s_date, '2024-09-03' AS e_date
当月第一天到当天的日期:
SELECT CONCAT(LEFT(current_date,7),"-01") as s_date,LEFT(current_date,10) as e_date
3)拖入「参数输出」算子,将 s_date、e_date 字段分别输出为参数日期、e_date(代表待取数表中最晚日期)。如下图所示:
2.3 循环容器设置
拖入「循环容器」节点,设置循环方式为条件循环,执行条件为:日期参数<=e_date参数。如下图所示:
2.4 取数
2.4.1 将目标表中该日期下已取出的数据条数输出为参数
本节目的:便于后续节点使用该参数,计算出当前日期下剩余多少条数据未读取,进而更新 2.2.2 节输出的名为「日期」的参数值、2.2.1 节输出的 times 参数值。
「循环容器」节点中拖入「参数赋值」节点,筛选出目标表中该日期下一共读取的数据条数,并输出为参数。如下图所示:
设计任务时,需要新建一张目标表,存放读取后的数据。
SQL语句为:SELECT count(*) as num from `demotest`.`双循环_目标表` where date='${日期}'
2.4.2 按照每次最多取5条数据标准取出当前日期下未读取的数据
1)循环容器中,在「参数赋值」节点后拖入「数据转换」节点,进入「数据转换」节点。
本文示例,从 MySQL 数据库表中取数,模拟 SAP RFC 中取数。
拖入「DB表输入」算子,输入 SQL 语句,从待取数表中,取出当前日期参数下,未读取的数据(若未读取数据超过 5 条,则本次读取 5 条,若未读取数据少于 5 条,则将未读取数据全部取出)。
SELECT * FROM `demo1`.`双循环_取数` where date = '${日期}' and ID>=1+(${times}*${size}) and ID<=(${times}+1)*${size}
2)拖入「DB表输出」算子,将取出的数据输出到目标表中。如下图所示:
2.5 更新取数参数
当前日期下,第一次取数后,我们需要更新「日期」参数值和「times」参数值:
如果当前日期下,数据未取完,「日期」参数值不变,「times」参数值需要加 1 继续取数。
如果当前日期下,数据取完,「times」需要恢复为 0,「日期」变为下个日期参数。
后续步骤中,我们需要使用「新增计算列」算子给「日期」、「times」参数重新赋值,然后使用「参数输出」算子将这两个参数输出。
步骤 | 说明 |
---|---|
1 | 获取当前日期下未读取的数据条数,便于后续步骤中根据数据是否读完,更新「日期」参数值和「times」参数值 |
2、3 | 「times」参数初始类型为数值类型(本文 2.2.1 节设置的该参数),所以「新增计算列」算子中第一次计算不会出错,但后续步骤中使用「参数输出」算子将「times」参数输出,该参数字段类型变为字符串类型,「新增计算列」算子第二次计算时将出错 所以「新增计算列」算子中重新赋值前,需要修改「times」参数类型,保证「新增计算列」算子中每次计算不出错 |
4 | 根据数据是否读完,更新「日期」参数值和「times」参数值 此时,times参数字段类型为 double,值显示示例:1.0,需要修改字段类型为 int |
5 | 修改 times 参数字段类型为 int |
6 | 输出「日期」参数和「times」参数 注:循环容器内的参数,优先级高于循环容器外的同名参数 |
2.5.1 获取当前日期下未读取的数据条数
1)循环容器中,在「数据转换」节点后拖入「数据转换」节点,进入「数据转换」节点。
2)拖入「DB表输入」算子,获取当前日期下,还剩几条数据没读取。如下图所示:
SELECT (COUNT(*) - ${已读取}) AS diff FROM `demo1`.`双循环_取数` WHERE date = '${日期}'
2.5.2 修改times字段类型
1)拖入「新增计算列」算子,新增列 time,值为参数 times 的值。如下图所示:
2)拖入「字段设置」算子,修改字段 time 的类型为 int,便于后续「新增计算列」算子中计算。如下图所示:
2.5.3 更新参数值
1)拖入「新增计算列」算子,更新字段 times、日期的值。如下图所示:
注:公式中的time、日期为参数格式,需要点击输入。
times:IF(diff=0,0,time+1)
日期:IF(diff=0,format(ADDTODATE(日期, 'd',1),'yyyy-MM-dd'),日期)
2)点击「数据预览」,如下图所示:
times 字段类型为 double,需要修改为 int。
3)拖入「字段设置」算子,修改 times 字段类型为 int,删除 time 字段。如下图所示:
4)拖入「参数输出」算子,将times、日期输出为参数。如下图所示:
2.6 效果查看
点击「运行」按钮后,可查看到目标表中已取出所有数据。如下图所示:
后续,用户可将该定时任务发布到 生产模式 ,并设置 执行频率