如何修复 progress 4gl 的动态查询错误?

How to fix Dynamic Query error for progress 4gl?

我是 progress 4GL 的新手。我通过将多个 table 添加到单个查询中并使用 table 字段名称从另一个 table 中查找记录来为缓冲区编写逻辑。我不确定为什么会出现错误。请帮忙改一下逻辑

DEFINE VARIABLE ix AS INTEGER NO-UNDO.
DEFINE VARIABLE qh AS HANDLE  NO-UNDO.
DEFINE VARIABLE bh AS HANDLE  NO-UNDO.
DEFINE VARIABLE fh AS HANDLE  NO-UNDO EXTENT 10.
DEFINE VARIABLE cQuery AS CHARACTER NO-UNDO.

CREATE BUFFER bh FOR TABLE "Customer, Invoice".
CREATE QUERY qh.

ASSIGN
    cQuery = "FOR EACH Customer NO-LOCK, EACH Invoice WHERE Invoice.Cust-Num = Customer.Cust- 
 Num NO-LOCK: ".

qh:SET-BUFFERS(bh).
qh:QUERY-PREPARE(cQuery).
qh:QUERY-OPEN().
qh:GET-FIRST().

 /* Field Invoice.Cust-Num is already defined in cQuery*/

  FIND Order WHERE Order.Cust-Num =  Invoice.Cust-Num NO-LOCK  NO-ERROR.
IF NOT AVAILABLE Order THEN DO:
  FIND Ref-Call WHERE Ref-Call.Cust-Num = Invoice.Cust-Num NO-LOCK NO-ERROR.
DISPLAY Ref-Call.Cust-Num.
END.


qh:QUERY-CLOSE().
bh:BUFFER-RELEASE().
DELETE OBJECT bh.
DELETE OBJECT qh.

查看字段名称,您正在使用经典的运动数据库进行训练。有一个“较新”的 Sports2000 演示数据库,其中包含更多可能值得一试的数据。

该程序中存在多个问题。

首先,您不能为两个 table(客户、发票)定义一个动态缓冲区。这会在运行时导致错误。您需要:

DEFINE VARIABLE bh1 AS HANDLE  NO-UNDO.
DEFINE VARIABLE bh2 AS HANDLE  NO-UNDO.

CREATE BUFFER bh1 FOR TABLE "Customer".
CREATE BUFFER bh2 FOR TABLE "Invoice".

然后

qh:ADD-BUFFER(bh1).
qh:ADD-BUFFER(bh2).

第二个问题(您的编译错误)是因为编译器没有看到您已经在访问 table 发票。 bh2 只会在运行时被认为是 Invoice table 的缓冲区。所以需要动态访问Cust-Num字段:

FIND Order WHERE Order.Cust-Num =  bh2::Cust-Num NO-LOCK  NO-ERROR.

注意:您在此处通过发票的 Cust-Num 访问单个订单 - 我假设,您想要执行类似通过发票的 Order-Num 字段访问订单的操作。那将是一个逻辑错误,而不是语法错误。

但是,您的程序中没有任何内容证明需要动态查询。在这种情况下,这只会增加不必要的复杂性。您的程序尚未迭代动态查询 qh 中的记录 - 但我认为这是目标。所以这个简单的静态 FOR EACH 块做同样的事情:

FOR EACH Customer NO-LOCK, EACH Invoice WHERE Invoice.Cust-Num = Customer.Cust- 
 Num NO-LOCK: 

    FIND Order WHERE Order.Cust-Num =  Invoice.Cust-Num NO-LOCK  NO-ERROR.

    IF NOT AVAILABLE Order THEN DO:
        FIND Ref-Call WHERE Ref-Call.Cust-Num = Invoice.Cust-Num NO-LOCK NO-ERROR.
        DISPLAY Ref-Call.Cust-Num.
    END /* NOT AVAILABLE */.
END. /* FOR EACH */

最后,这里:

DELETE OBJECT bh.
DELETE OBJECT qh.
  1. DELETE OBJECT 语句本质上属于 FINALLY 块。

  2. 您需要在删除之前检查句柄的有效性 他们:

    最后: IF VALID-HANDLE (bh1) THEN DELETE OBJECT bh1. IF VALID-HANDLE (bh2) THEN DELETE OBJECT bh2. IF VALID-HANDLE (qh) THEN DELETE OBJECT qh。 结束。

这是一个工作示例 - 我对您的代码所做的更改通常可以通过小写来识别。

DEFINE VARIABLE qh AS HANDLE  NO-UNDO.
DEFINE VARIABLE bhc AS HANDLE  NO-UNDO.
DEFINE VARIABLE bhi AS HANDLE  NO-UNDO.
DEFINE VARIABLE cQuery AS CHARACTER NO-UNDO.

CREATE BUFFER bhc FOR TABLE "Customer".
create buffer bhi for table "Invoice".
CREATE QUERY qh.

cQuery = "FOR EACH Customer NO-LOCK,"
       + "EACH Invoice WHERE Invoice.CustNum = Customer.CustNum no-lock".

qh:SET-BUFFERS(bhc,bhi).
qh:QUERY-PREPARE(cQuery).
qh:QUERY-OPEN().
do while qh:get-next().

  message bhc::CustNum bhi::InvoiceNum.
  FIND Order WHERE Order.CustNum = bhi::CustNum NO-LOCK NO-ERROR.
  IF NOT AVAILABLE Order THEN DO:
    FIND RefCall WHERE RefCall.CustNum = bhi::CustNum NO-LOCK NO-ERROR.
    if available RefCall then
      message RefCall.CustNum.
  END.

end.

finally:
   DELETE OBJECT bhc no-error.
   DELETE OBJECT bhi no-error.
   DELETE OBJECT qh no-error.
end finally.

观看 ABLdojo 中的示例 运行。