是否可以提供进度完成的估计小时数或分钟数? - 进步 4GL

Is it possible to provide estimate hrs or minutes for progress completion? - PROGRESS 4GL

我正在使用下面的进度完成查询,它显示了记录更新过程中完成的百分比。我的问题或疑问是是否可以提供估计的 hrs/minutes 以完成此进度?

例如,考虑一个 table 有 1000 条记录,每条记录在更新之前都会进行一些验证,大约时间不到一秒(毫秒)。因此,如果单个记录在验证后花费不到一毫秒的时间进行更新,那么 1000 条记录的估计值是多少?如何计算并转换成hh:mm:ss?请帮助编写示例查询。

DEFINE VARIABLE I AS INTEGER NO-UNDO.
DEFINE VARIABLE iPercentage AS INTEGER NO-UNDO.
DEFINE VARIABLE iComp       AS INTEGER NO-UNDO.
DEFINE VARIABLE iRec        AS INTEGER NO-UNDO.

ASSIGN
I     = 0
iComp = 0
iRec  = 0
iPercentage = 0.


/* Calculating Total records*/
FOR EACH <table> NO-LOCK:
  iRec = iRec + 1.
END.
/* Taking each records from the same table to update*/
FOR EACH <table> NO-LOCK:
  I = I + 1.
  
  IF I = 1 THEN DO:
  /*do some more validations*/
    iComp =  iComp  + I.
    iPercentage  = 100 * (iComp / iRec).

    IF iPercentage = 100 THEN DO:
        MESSAGE "Record Updation Is completed".
    END.
    ELSE DO:
        I = 0
        NEXT.
    END.  
 END.

 END.

A​​BL做起来并不简单。也许甚至不可能。我认为你必须保持跟踪 - 即测量这样的查询需要多长时间,并将其存储在某个地方。 您可以有一个数据库 table,它有一个查询名称、返回的记录数(也许?)和花费的时间。您可以使用这些记录来确定平均需要多长时间才能找到,比如说,100 条记录并将其与百分比进度条一起使用。在每次查询之后,你在那个table中创建一条记录,记录它有多长。

但是这样做会增加处理该查询的时间。并且数据库本身没有任何东西可以为您执行此操作。

还有比遍历所有查询次数更快的方法。

您可以使用带有 PRESELECT 子句的查询,它可以为您提供计数。

define query qT for Table.
open query qT preselect each Table.
iRec = query qT:num-results.   // if you use a FOR you get 0

get first qT no-lock.
do while available Table:
  if query qT:current-result-row mod 50 = 0 then
    . //   update the progress bar

  // do stuff with the data

  get next qT no-lock.
end.

您缺少的一点是到目前为止经过的时间。这很容易获得:

DEFINE VARIABLE I AS INTEGER NO-UNDO.
DEFINE VARIABLE iPercentage AS INTEGER NO-UNDO.
DEFINE VARIABLE iComp       AS INTEGER NO-UNDO.
DEFINE VARIABLE iRec        AS INTEGER NO-UNDO.

ASSIGN
I     = 0
iComp = 0
iRec  = 0
iPercentage = 0.


/* Calculating Total records*/
FOR EACH <table> NO-LOCK:
  iRec = iRec + 1.
END.

etime( true ).  // set the etime counter to 0

/* Taking each records from the same table to update*/
FOR EACH <table> NO-LOCK:
  I = I + 1.
  
  IF I = 1 THEN DO:
  /*do some more validations*/
    iComp =  iComp  + I.
    iPercentage  = 100 * (iComp / iRec).
    IF iPercentage = 100 THEN DO:
        MESSAGE "Record Updation Is completed".
    END.
    ELSE DO:

        message string( 1000 * ((( etime / ( iComp / iRec )) - etime )) , "hh:mm:ss" ) "remaining".

        I = 0
        NEXT.
    END.  
 END.

 END.

这里的变体依赖于 nwahmaet 建议的 NUM-RESULTS,并使用 DATETIME-TZ 变量和 INTERVAL 函数来确定运行时间。仅每 1000 次迭代进行一次输出,以便 Progress 的显示不会导致比处理更多的负载。

&scoped Table Customer

SESSION:APPL-ALERT-BOXES = FALSE .  

DEFINE VARIABLE I           AS INTEGER NO-UNDO.
DEFINE VARIABLE iPercentage AS INTEGER NO-UNDO.
DEFINE VARIABLE iComp       AS INTEGER NO-UNDO.
DEFINE VARIABLE iRec        AS INTEGER NO-UNDO.

DEFINE VARIABLE dtStart AS DATETIME-TZ NO-UNDO.
DEFINE VARIABLE iMsecs   AS INTEGER NO-UNDO.

ASSIGN
    I     = 0
    iComp = 0
    iRec  = 0
    iPercentage = 0.


DEFINE QUERY qT FOR {&table} .
OPEN QUERY qT PRESELECT EACH {&Table}.
iRec = QUERY qT:NUM-RESULTS.   // if you use a FOR you get 0

dtStart = NOW .

/* Taking each records from the same table to update*/
FOR EACH {&table} NO-LOCK:
    I = I + 1.

    IF I MODULO 1000 = 0 THEN DO:
PAUSE .05 . // simulate some load

        /*do some more validations*/
        iComp =  iComp  + I.
        iPercentage  = 100 * (iComp / iRec).

        iMsecs = INTERVAL (NOW, dtStart, "milliseconds") .

        MESSAGE i "of" iRec "/" iMsecs "/"

                STRING (INTEGER ((iMsecs / (i / iRec)    // iMsecs / % processed = estimated total time
                                - iMsecs)                // minus time already spent
                                 / 1000),                // msecs to seocnds

                        "hh:mm:ss")                      // format output
               "remaining".
    END.
END.

MESSAGE "Record Updation Is completed".