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

时间:2021-03-26 11:39:32

标签: openedge progress-4gl

Noob to Progress 并在工作时自学,如果我错过了一些明显的东西,很抱歉。我昨天了解了缓冲区,我想知道是否可以界定缓冲区将搜索的范围。下面是我想知道的一个例子。

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.

3 个答案:

答案 0 :(得分:1)

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

DEFINE BUFFER ex1 FOR emit .

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

答案 1 :(得分:1)

回答 OP 的扩展问题。

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

在最后的 FOR EACH 中,您只迭代 opacao 记录,其中 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 仍将检索表中的所有记录,但仅处理 FIRST-OF (it-codigo) 记录。这可能是一个非常繁重的操作。

在大表中,如果用 BREAK-BY 代替 FOR EACH 可能会更好。我的订单表有 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.

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

答案 2 :(得分:0)

我之前发布的代码需要几分钟才能编译。我设法通过将 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,如果有任何其他建议,我都愿意接受。

相关问题