如何修复 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.
DELETE OBJECT 语句本质上属于 FINALLY
块。
您需要在删除之前检查句柄的有效性
他们:
最后:
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 中的示例 运行。
我是 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.
DELETE OBJECT 语句本质上属于 FINALLY 块。
您需要在删除之前检查句柄的有效性 他们:
最后: 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 中的示例 运行。