在这里没有进步,在工作时自学成才,如果我错过了一些显而易见的事情,我很抱歉。我昨天了解了缓冲区,我想知道是否可以定义缓冲区将搜索的范围。下面是我想知道的一个例子。
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.
对OP的扩展问题的回答。
在不了解用例和表关系细节的情况下回答这个问题总是很困难的。但根据您的代码:
在最后的FOR EACH中,您只迭代operacao记录,其中首先it codigo是唯一的(然后将其放入tt min oper中(。然后过滤操作codigo<gt;10,并将得到的记录添加到tt操作中。
因此,此时tt操作器应该包含具有唯一it codigo值和op codigo<gt;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<gt;10以及:
for each operacao WHERE operacao.op-codigo <> 10 NO-LOCK
break by operacao.it-codigo by operacao.num-id-operacao:
能歌善舞有多少张唱片?有没有一个索引把它作为第一个字段?带有BREAK-BY的FOR EACH仍然会检索表中的所有记录,但只处理第一个(它编码(记录。这可能是一项非常艰巨的任务。
在大表格中,如果最好这样做,而不是用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条记录(DB中有10个Salesrep(。但这只有在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语句,因此
DEFINE BUFFER ex1 FOR emit .
FOR EACH ex1 WHERE ex1.id > 50000:
DISP ex1.id ex1.name.
end.
我之前发布的代码花了几分钟编译。我设法通过在另一个里面放一个FOR EACH来减少它(现在只需要25秒(。不幸的是,我无法过滤op codigo<gt;10在第一个FOR EACH中,因为它会改变结果。我没有使用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.
我找不到我想要的缓冲区解决方案,但我以前所未有的方式做到了,所以我认为这是一场胜利。谢谢你的时间和建议,迈克,如果还有其他建议,我愿意接受