SAP小技巧 查询接口的分页查询处理

前言

在查询类的接口中, 如果查询的数据量过大,因为http调用的最大时长限制或者系统的内存限制, 都可能引起超时报错或内存溢出报错. 此时就需要把查询接口做分页处理

本文主要介绍使用分页查询接口同步数据的注意事项

SQL分页

ABAP OPEN SQL新版本支持分页查询. 

如下图, 可以通过 OFFSET <M>偏移量 和 UP TO <N> ROWS 两个参数实现分页查询

其中OFFSET  <M> 表示跳过 M 条记录 从M + 1开始获取数据

UP TO <N> ROWS 表示获取 N 条记录

分页查询中的排序很重要. 一般情况需要按找主键排序, 以便确保结果集合稳定排序,分页查询不会导致遗漏数据

894890b5d9aab3bd922f109ff08c7394.png

客户端处理方式

如果上述SQL分页查询封装成服务. 客户端调用服务时, 需要通过如下循环实现所有数据的获取

假定总数据量 25 . 每次查询记录数10

循环开始

第一次查询偏移量0   指定每包记录数10 . 返回记录数10

第二次查询偏移量0+10 指定每包记录数10 . 返回记录数10

第三次查询偏移量0+20 指定每包记录数10.  返回记录数 5

判定返回记录数5<每次查询记录数10 . 退出循环

遗漏数据的可能情况一

使用SQL语句的分页方式, 可能有如下数据遗漏的可能

删除数据

如果数据集合存在删除. 无论怎么优化查询,都可能导致查询的数据遗漏.

示例

数据集

主键   时间戳

1010    T10

1020    T10

1030    T10

1040    T10

1050    T10

本轮查询的每页最大记录数 2

第一次查询 偏移量 OFFSET  0  UP TO 2 ROWS, 获取数据

1010    T10

1020    T10

第一次查询后, 如果记录1020 被删除. 结果集变成

1010    T10

1030    T10

1040    T10

1050    T10

第二次查询 偏移量 OFFSET 2 UP TO 2 ROWS,获取数据

1040    T10

1050    T10

第三次查询 偏移量OFFSET 4 UP TO 2 ROWS,没有获取数据, 退出查询

可以看到,因为在两次查询间隔删除了主键1020的记录, 从而导致客户端获取的数据集和服务器的数据集不一致,客户端遗漏了不该遗漏的数据 1030 同时因为通过查询同步数据的方式无法获取删除掉的数据1020 的删除信息, 导致服务端和客户端的数据差异

服务端

1010    T10

1030    T10

1040    T10

1050    T10

客户端获取

1010    T10

1020    T10

1040    T10

1050    T10

解决方式

如果数据存在删除,通过查询语句是无法把删除信息传递到客户端系统的,因此设计系统时使用数据的标记删除取代物理删除. 可以避免情况这种麻烦.

遗漏数据的可能情况二

客户端限定了查询开始及结束时间戳. 服务端使用开始和结束时间戳查询数据.客户端按结束时间戳作为下次查询的开始时间戳

比如如下结果集

主键   时间戳

1010    T10

1020    T10

1030    T10

1040    T10

1050    T10

 查询时间戳 >=T01 AND <= T11 . 每页最大记录数 2

第一次查询 偏移量 OFFSET  0  UP TO 2 ROWS, 获取数据

1010    T10

1020    T10

第一次查询后, 关键字 1010数据发生改变, 时间戳变成 T12

查询条件不变, 可以获取的结果集变成

1020    T10

1030    T10

1040    T10

1050    T10

第二次查询 偏移量 OFFSET  2  UP TO 2 ROWS, 获取数据

1040T10

1050T10

第三次查询, 偏移量 OFFSET  4  UP TO 2 ROWS ,没有获取数据. 本轮查询结束

可以看出

客户端遗漏了关键字 1030 的数据. 该记录再下一轮查询中也无法获取. 

对于新增记录

因为新增记录的时间戳 > 客户端限定的时间戳T11. 本轮查询无法获取新增的记录,下轮查询中客户端调整了查询时间戳范围, 可以获取

数据遗漏的可能情况三

客户端限定了开始时间戳,结束时间戳, 服务端仅使用时间戳>=开始时间戳查询数据, 客户端获取所有查询结果集中最大的时间戳作为下次查询的开始时间戳

比如如下结果集, 

主键   时间戳

1010    T10

1020    T10

1030    T10

1040    T10

1050    T10

 查询时间戳 >=T01 . 每页最大记录数 2

第一次查询 偏移量 OFFSET  0  UP TO 2 ROWS, 获取数据

1010    T10

1020    T10

第一次查询后, 关键字 1010数据发生改变, 时间戳变成 T11

客户端的查询条件不变 >=T01, 可以获取的结果集不变

1010    T11

1020    T10

1030    T10

1040    T10

1050    T10

第二次查询 偏移量 OFFSET  2  UP TO 2 ROWS, 获取数据

1030    T10

1040    T10

第二次查询后,

如果新增了记录1012 T12 ,1042 T13,使用时间戳>=T01的查询结果集变成

1010    T11

1012    T12

1020    T10

1030    T10

1040    T10

1042    T13

1050    T10

第三次查询, 偏移量 OFFSET  4  UP TO 2 ROWS ,

1040    T10

1042    T12

第四次查询, 偏移量 OFFSET  6  UP TO 2 ROWS ,

1050    T10

本轮结束后,客户端的查询结果集

1010    T10

1020    T10

1030    T10

1040    T10

1040    T10

1042    T13

1050    T10

其中新增的记录1012 T12 在本轮查询中没有获取. 修改的记录 1010 T11,客户端获取的是旧记录,新增记录 1042 T13 获取了.

客户记录时间戳采用本轮查询的最大时间戳  记录下 T13

下轮查询时, 使用 >=T13 查询. 遗漏数据

1012    T12

1010    T13

改进的方式

客户端限定了开始时间戳和结束时间戳.并使用结束时间戳作为下次查询的开始时间戳

服务端强制使用时间戳>=开始时间戳查询

比如如下结果集,  

主键   时间戳

1010    T10

1020    T10

1030    T10

1040    T10

1050    T10

客户端 使用时间戳 T01  T11 . 

 查询时间戳 >=T01 . 每页最大记录数 2

第一次查询 偏移量 OFFSET  0  UP TO 2 ROWS, 获取数据

1010    T10

1020    T10

第一次查询后, 关键字 1010数据发生改变, 时间戳变成 T12

客户端的查询条件不变 >=T01, 可以获取的结果集不变

1010T12

1020T10

1030T10

1040T10

1050T10

第二次查询 偏移量 OFFSET  2  UP TO 2 ROWS, 获取数据

1030    T10

1040    T10

第二次查询后,

如果新增了记录1012 T13 ,1042 T14,查询结果集变成

1010    T12

1012    T13

1020    T10

1030    T10

1040    T10

1042    T14

1050    T10

第三次查询, 偏移量 OFFSET  4  UP TO 2 ROWS ,

1040    T10

1042    T14

第四次查询, 偏移量 OFFSET  6  UP TO 2 ROWS ,

1050    T10

本轮结束后,客户端的查询结果集

1010    T10

1020    T10

1030    T10

1040    T10

1040    T10

1042    T14

1050    T10

其中新增的记录1012 T13在本轮查询中没有获取. 新增记录 1042 T14 获取到了.

客户端记录采用本轮查询的结束时间戳  记录下 T11

下轮查询时, 使用 >=T11查询. 获取的数据,包括上轮查询未获取的数据 1012 T13 及修改的数据

1010    T12

1012    T13

1042    T14

这样确保了客户端最终的数据集等同于服务端的数据集

时间戳分包获取变化量的方式

在数据集不存在物理删除的情况下. 可以使用下述方式获取服务器的数据

非业务查询字段的附加查询字段:

  • ZINI    全量查询标记( 'X' 全量查询  '' 变化量查询)

  • BEGIN_TS    查询开始时间戳

  • END_TS    查询结束时间戳

  • PAGESTART    分页查询偏移量,详见长文本

  • PAGESIZE    每页查询最大记录数(当查询返回数<每页查询记录数时,表示查询结束)

d1cac9a52094a12cdc17e889e276fdb2.png

两种查询方式

01

全量查询

客户端:循环执行

传递业务查询条件,

传递查询开始时间戳,结束时间戳,分页查询偏移量,每页查询最大记录数

不记录时间戳

当查询记录数<每页查询的最大记录数,退出循环

  服务端: 

    使用业务查询条件和时间戳>=开始时间戳 ,时间戳<=结束时间戳及分页信息查询数据.

02

变化量查询

客户端:循环执行

不传递业务查询条件,

传递查询开始时间戳,结束时间戳,分页查询偏移量,每页查询最大记录数

用查询结束时间戳记录时间戳作为下轮查询的开始时间戳

当查询记录数<每页查询的最大记录数,退出循环

服务端: 使用时间戳>=开始时间戳及分页信息查询数据

客户端代码示例:

cfe856cd6bafc163b74602346a9193d2.png

分页查询的偏移量的处理:

b078891907c2045d9115c448527a181e.png

服务端代码示例

25bbec843eb6799d9910ebbf5ac917fd.png

其它安全的分页方式

  先获取查询集的所有关键字或所有查询集内容,

   如果查询集个数<=每页查询最大记录数,一次性返回所有查询内容.

  如果查询集个数>每页查询最大记录数,生成一个查询号临时存储本次查询的所有关键字或数据,返回第一页的数据,附带这个查询号.

  后续查询需要添加该查询号及偏移量. 根据查询号获取关键字信息或全部内容, 如果是关键字信息,再根据偏移量及每页查询的最大记录数关联查询数据返回

定期删除过期的查询号临时存储的数据(关键字或全部数据集)

这种分页查询的方式可以确保不会存在数据遗漏,但是因为设计到全量查询及查询的关键字或结果集的存储,对系统性能开销较大.

总结

数据的物理删除无法通过查询方式传递到目标系统.

对于专门的数据同步工具,

  • SAP DS 基于查询语句获取数据也无法解决这个问题.

  • SAP SLT 根据数据库的日志获取数据的改变信息,可以把删除传递到目标系统实现数据的删除

因此设计系统尽量不要使用物理删除数据,而使用删除标记字段标记数据的删除.

变化量的分页查询在时间戳的记录及服务端使用时间戳的方式上需要特别注意, 使用不当容易出现数据丢失或不一致的情况.

时间戳方式无论如何都可能造成数据重复传输的情况, 仅适用于主数据的传输. 对于单据类数据最好使用标记字段及锁来确保数据的一次性传输

THE

END

约定

如果你对这篇文章感兴趣,请帮忙点赞,在看,分享.       

请微信联系管理员: 

syjf1976 

sharry_xlp  

Yannick_Duan 

申请进入公众号讨论群提问或者参与话题讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值