【问题标题】:How to fix Dynamic Query error for progress 4gl?如何修复进度 4gl 的动态查询错误?
【发布时间】:2021-10-12 20:09:33
【问题描述】:

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

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.

【问题讨论】:

    标签: openedge progress-4gl


    【解决方案1】:

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

    该程序存在多个问题。

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

    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).
    

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

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

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

    但是,您的程序中没有任何内容可以证明需要动态查询。在这种情况下,这只会增加不必要的复杂性。您的程序尚未迭代动态查询 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) 然后删除对象 bh1。 IF VALID-HANDLE (bh2) 然后删除对象 bh2。 IF VALID-HANDLE (qh) 然后删除对象 qh。 结束。

    【讨论】:

    • 感谢 Mike 的知识分享。您在程序中建议的更改给出另一个错误“QUERY-PREPARE text must have 1 FOR EACH/PRE SELECT for each query buffer. (7325)”。 .似乎 QUERY-PREPARE 中给出的谓词必须以相同的顺序将每个级别的连接匹配到查询中的缓冲区..但是有一种情况我们无法将(未链接的表)连接到缓冲区..什么如果?
    • 用 add-buffer 替换 set-buffer 或在单个 set-buffers 中提供所有缓冲区。
    • 不迭代动态查询 qh 中的记录。我需要迭代
    【解决方案2】:

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

    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 中运行的示例。

    【讨论】:

    • 谢谢你成功了!!!..如何验证SET-BUFFERS、QUERY-PREPARE、QUERY-OPEN()和GET-FIRST()???
    • 什么意思?
    • 我们必须验证它们以避免运行时错误。
    • 如果你想自己处理错误,抓住它们。
    猜你喜欢
    • 2013-08-28
    • 2021-10-09
    • 2012-08-13
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    相关资源
    最近更新 更多