You need to enable JavaScript to run this app. Progress-4GL 创建缓冲区时能否限定其数据搜索范围
优惠活动
大模型
产品
解决方案
定价
更多

Progress-4GL 创建缓冲区时能否限定其数据搜索范围

关于缓冲区自定义限定范围的实现说明

DEFINE BUFFER 原生语法本身不支持在定义行直接追加WHERE子句来绑定固定数据范围。缓冲区本质是对应表/临时表的内存操作句柄,本身没有持久化存储过滤规则的属性,你尝试编写的DEFINE BUFFER ex1 FOR emit WHERE emit.id > 50000 属于不被支持的非法语法。

如果你的业务需求是让某个缓冲区永久绑定固定的查询范围、不需要每次遍历重复写WHERE条件,可以通过给缓冲区关联固定配置的QUERY对象实现等效效果,示例代码:

/* 定义目标缓冲区 */
DEFINE BUFFER ex1 FOR emit.
/* 给缓冲区绑定固定查询,把过滤条件固化在查询配置里 */
DEFINE QUERY q-ex1 FOR ex1 SCROLLING.
OPEN QUERY q-ex1 FOR PRESELECT ex1 WHERE ex1.id > 50000.
/* 后续遍历直接走这个固化的查询,不需要重复写WHERE条件 */
GET FIRST q-ex1.
DO WHILE NOT QUERY-OFF-END("q-ex1"):
    DISPLAY ex1.id ex1.name.
    GET NEXT q-ex1.
END.

只要你不主动修改这个QUERY的过滤条件,该缓冲区的所有遍历结果都会被限定在你最初定义的范围内,完全可以实现“缓冲区自带数据范围限制”的效果,适配你的业务诉求。

现有业务代码的效率优化方案

你当前代码的性能瓶颈主要来自三点:无索引的临时表嵌套比对、冗余的临时表中转、可能的全表无索引扫描。对应的优化都是ABL开发里的常规性能优化思路:

  • 删除完全冗余的临时表中转
    你当前代码里的tt-oper属于多出来的中间层,仅把tt-min-oper里op-codigo <>10的物料复制了一遍,这一步会额外增加一次临时表全遍历、写入的开销,完全可以删掉。
    同时给所有临时表加上匹配字段的索引,避免嵌套遍历的时候做无索引的逐行比对:
    def temp-table tt-min-oper 
        field it-codigo like operacao.it-codigo
        field num-id-operacao like operacao.num-id-operacao
        field op-codigo like operacao.op-codigo
        /* 给后续关联的匹配字段加索引,大幅提升关联速度 */
        index idx-it it-codigo
    .
    
    def temp-table tt-valida-oper 
        field it-codigo like operacao.it-codigo
        /* 加唯一索引,避免重复写入同个物料的重复记录 */
        index idx-it it-codigo unique
    .
    
    删掉原来遍历tt-min-oper写入tt-oper的整段逻辑,把原本对tt-oper的过滤条件直接挪到后面的关联查询里:
    FOR EACH operacao NO-LOCK,
        EACH tt-min-oper NO-LOCK
        WHERE operacao.it-codigo = tt-min-oper.it-codigo
        AND tt-min-oper.op-codigo <> 10
        AND operacao.op-codigo = 10:
        
        CREATE tt-valida-oper.
        ASSIGN tt-valida-oper.it-codigo = operacao.it-codigo.
    END.
    
  • 优化首条记录的提取逻辑
    你当前提取每个物料第一条操作记录的逻辑,是全表扫描operacao再加BREAK BY排序,如果operacao表没有(it-codigo, num-id-operacao)的复合索引,这一步会触发全表扫描+磁盘临时排序,开销极大。
    只要表上存在it-codigo升序的索引,这一步不需要做任何逻辑调整,就能只读取每个物料的第一条匹配记录就结束,不需要全表遍历所有行。
  • 百万级大表场景的无临时表优化
    如果operacao表的数据量超过百万级,连tt-min-oper临时表的读写开销都可以省掉。你当前的业务逻辑本质是筛选“存在非10类型初始操作、同时存在10类型操作记录”的物料,完全可以通过自关联operacao表实现,不需要任何临时表中转:
    /* 优先走op-codigo的索引,直接定位所有op-codigo=10的操作记录,减少扫描量 */
    FOR EACH operacao NO-LOCK
        WHERE operacao.op-codigo = 10,
        /* 利用it-codigo的索引,关联找同个物料下存在非10类型的操作记录 */
        EACH operacao ex-init NO-LOCK
        WHERE ex-init.it-codigo = operacao.it-codigo
        AND ex-init.op-codigo <> 10:
        
        CREATE tt-valida-oper.
        ASSIGN tt-valida-oper.it-codigo = operacao.it-codigo.
    END.
    
    这种写法全程会走表上的现成索引,不会触发全表扫,性能会比多临时表中转的方式高一个数量级。

内容的提问来源于stack exchange,提问作者Diego

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 04:36:09