我可以在 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 的宝贵时间和建议,如果有任何其他建议,我很乐意接受。
新手在这里取得进步并在工作时自学成才,如果我错过了一些明显的事情,我深表歉意。我昨天了解了缓冲区,我想知道是否可以划定缓冲区将搜索的范围。下面是我想知道的例子。
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 的宝贵时间和建议,如果有任何其他建议,我很乐意接受。