我可以在 Progress-4GL 中创建缓冲区时指定缓冲区的内容吗?

Can I specify the contents of the buffer while creating it in Progress-4GL?

新手在这里取得进步并在工作时自学成才,如果我错过了一些明显的事情,我深表歉意。我昨天了解了缓冲区,我想知道是否可以划定缓冲区将搜索的范围。下面是我想知道的例子。

DEFINE BUFFER ex1 FOR emit WHERE emit.id > 50000.

FOR EACH ex1:
    DISP ex1.id ex1.name.
end.

我知道我可以在此示例中将 WHERE 放在 FOR EACH 部分,但我想知道我是否以及如何分隔缓冲区,以便我可以在此处的代码中执行我打算执行的操作。

感谢您的帮助。

编辑:我会把我写的代码放在这里,这样更容易理解我的意思。除了使用临时表之外,我真的看不到任何其他解决方案,它使一切变得如此缓慢。我会像这样保留我的代码,但如果有人知道更好的解决方案,请告诉我。再次感谢您的宝贵时间。

def var contador as int.
def var contador2 as int.
def var contador3 as int.

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
.

def temp-table tt-oper 
field it-codigo like operacao.it-codigo
field op-codigo like operacao.op-codigo
.

def temp-table tt-valida-oper 
field it-codigo like operacao.it-codigo
.

for each operacao NO-LOCK
break by operacao.it-codigo by operacao.num-id-operacao:
    IF FIRST-OF (operacao.it-codigo) THEN DO:
        
        CREATE tt-min-oper.
        ASSIGN
        tt-min-oper.it-codigo = operacao.it-codigo
        tt-min-oper.num-id-operacao = operacao.num-id-operacao
        tt-min-oper.op-codigo = operacao.op-codigo
        .
    END.
END.

FOR EACH tt-min-oper WHERE tt-min-oper.op-codigo <> 10 NO-LOCK:
    create tt-oper.
    assign tt-oper.it-codigo = tt-min-oper.it-codigo.
END.


FOR EACH operacao NO-LOCK,
    EACH tt-oper
    WHERE operacao.it-codigo = tt-oper.it-codigo
    AND operacao.op-codigo = 10 NO-LOCK:
       
        create tt-valida-oper.
        assign
        tt-valida-oper.it-codigo = operacao.it-codigo.
    
END.

您在查询中限制了结果,在您的情况下是 FOR EACH 语句,所以

DEFINE BUFFER ex1 FOR emit .

FOR EACH ex1 WHERE ex1.id > 50000:
    DISP ex1.id ex1.name.
end.

回答 OP 的扩展问题。

在不知道您的用例和有关 table 关系的详细信息的情况下回答这个问题总是很困难。但是从你的代码:

在最后的 FOR EACH 中,您只迭代 operacao 记录,其中首先 it-codigo 是唯一的(然后将其放入 tt-min-oper)。然后过滤 tt-min-oper for op-codigo <> 10 并将结果记录添加到 tt-oper.

所以此时 tt-oper 应该包含具有唯一 it-codigo 值和 op-codigo <> 10 的记录。

所以至少你在这里不需要这个循环:

FOR EACH tt-min-oper WHERE tt-min-oper.op-codigo <> 10 NO-LOCK:
    create tt-oper.
    assign tt-oper.it-codigo = tt-min-oper.it-codigo.
END.

与初始 FOR EACH 一样,您也可以在 op-codigo <> 10 上进行过滤:

for each operacao WHERE operacao.op-codigo <> 10 NO-LOCK
break by operacao.it-codigo by operacao.num-id-operacao:

能歌剧有多少记录?是否有以it-codigo为第一个字段的索引?带有 BREAK-BY 的 FOR EACH 仍将检索 table 中的所有记录,但仅处理第一个 (it-codigo) 的记录。那可能是一个非常繁重的操作。

在大型 table 中,如果做这样的事情可能比使用 BREAK-BY 的 FOR EACH 更好。我的订单 table 有 700000 条记录,所以这里处理所有 700000 条记录:

FOR EACH Order BREAK BY Order.Salesrep:
        
    IF FIRST-OF (Order.Salesrep) THEN
    DO:
        DISPLAY Order.Salesrep . 
    END.
END.

这里得到了相同的结果,但只读取了 10 条记录(数据库中有 10 个销售代表)。但这只有在 Salesrep 字段有索引时才有可能。

DEFINE VARIABLE cPrevious-Salesrep AS CHARACTER NO-UNDO . 

FIND FIRST Order WHERE Order.Salesrep > cPrevious-Salesrep
    NO-LOCK NO-ERROR . 
    
DO WHILE AVAILABLE (Order):
    DISPLAY Order.Salesrep WITH DOWN . 
    DOWN 1 .
    
    ASSIGN cPrevious-Salesrep = Order.Salesrep. 

    FIND NEXT Order WHERE Order.Salesrep > cPrevious-Salesrep
        NO-LOCK NO-ERROR . 
END.

因此,要优化您的代码,您需要了解您的数据库模式和实际数据。

我之前发布的代码编译花了几分钟。我通过将 FOR EACH 放入另一个中来设法减少了很多(现在只需要 25 秒)。不幸的是,我无法在第一个 FOR EACH 中过滤 op-codigo <> 10,因为它会改变结果。我没有使用 USE-INDEX,因为我读到 Tom Bascom 说它不好,但我们在使用的表中有索引。我对表格了解不多,因为我在这里很新,而且我还在学习很多东西。

所以我的代码变成了下面的例子。我不知道将 FOR EACH 放在另一个里面是否好,我总是避免这样做,但我所有的同事都这样做。

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
.

DEF TEMP-TABLE tt-valida-oper 
FIELD it-codigo LIKE operacao.it-codigo
FIELD num-id-operacao   LIKE operacao.num-id-operacao
.


FOR EACH operacao NO-LOCK
BREAK BY operacao.it-codigo BY operacao.num-id-operacao:
    IF FIRST-OF (operacao.it-codigo) THEN DO:
    CREATE tt-min-oper.
       ASSIGN
       tt-min-oper.it-codigo = operacao.it-codigo
       tt-min-oper.num-id-operacao = operacao.num-id-operacao
       tt-min-oper.op-codigo = operacao.op-codigo
       .          
     END.
 END.

FOR EACH tt-min-oper
WHERE tt-min-oper.op-codigo <> 10 NO-LOCK:
    FOR EACH operacao
    WHERE operacao.it-codigo = tt-min-oper.it-codigo
    AND operacao.op-codigo = 10 NO-LOCK:
        CREATE tt-valida-oper.
        ASSIGN
        tt-valida-oper.it-codigo = operacao.it-codigo
        tt-valida-oper.num-id-operacao = tt-min-oper.num-id-operacao
        .
    END.
END.

我找不到我想要的缓冲区解决方案,但我设法以一种我以前从未做过的方式做到了,所以我认为这是一个胜利。感谢 Mike 的宝贵时间和建议,如果有任何其他建议,我很乐意接受。