Release 10.1A: OpenEdge Development:
Progress 4GL Handbook

> ## QUERY-PREPARE method

> Once you’ve defined the buffers for a dynamic query, the next step is to provide it with a `FOR EACH` statement that it should use to retrieve and order data when you open the query. The `QUERY-PREPARE` method takes the `FOR EACH` statement as its argument. It returns true if the operation succeeded and false otherwise. You can use `QUERY-PREPARE` to define the record selection for a dynamic query or to change the selection for a static one. This sample code prepares the dynamic query for the Order, Customer, and SalesRep tables:

>     DEFINE VARIABLE hQuery    AS HANDLE     NO-UNDO.
>     DEFINE VARIABLE iBufNum   AS INTEGER    NO-UNDO.
>     DEFINE VARIABLE cBufNames AS CHARACTER  NO-UNDO.
>     DEFINE VARIABLE lSuccess  AS LOGICAL    NO-UNDO.
>     CREATE QUERY hQuery.
>     hQuery:SET-BUFFERS(BUFFER Order:HANDLE, BUFFER Customer:HANDLE).
>     hQuery:ADD-BUFFER(BUFFER SalesRep:HANDLE).
>     lSuccess =
>         hQuery:QUERY-PREPARE("FOR EACH Order WHERE OrderStatus = 'Ordered', "
>                            + "FIRST Customer OF Order, "
>                            + "FIRST SalesRep OF Order "
>                            + "BY SalesRep").
>     IF NOT lSuccess OR ERROR-STATUS:NUM-MESSAGES NE 0 THEN
>     DO:
>         /* Deal with possible errors in the Query Prepare. */
>     END.

> There are a few important comments to make about this example:

> 1. Remember that when you use a one-to-one join in a `FOR EACH` statement for a query, you must include the `FIRST` or `EACH` keyword in each table phrase, as is shown in the following code example. Since there is just one Customer for each Order, and one SalesRep for each Order, there is no need to iterate through potentially multiple Customers or SalesReps for an Order, so the `FIRST` keyword suffices. In a `FOR EACH` statement in a block header, the `FIRST` keyword would be optional, as in this example:

>     FOR EACH Order WHERE OrderStatus = "Ordered",
>         Customer OF Order, SalesRep OF Order:
>         DISPLAY OrderNum Order.CustNum Customer.NAME SalesRep.RepName.
>     END.

> 2. If you know exactly what the `WHERE` clause and `BY` clause are when you write the procedure, you might not need to use dynamic constructs at all. More realistically, you use the `QUERY-PREPARE` method when you don’t know the selection and sort criteria until run time. In the "Extending the sample window to filter dynamically" section, you’ll build an extension to the Customer and Orders window that shows this flexibility more realistically.

> 3. Since you normally use the `QUERY-PREPARE` method in cases where the `WHERE` clause is truly variable, it is essential that you always assign the result of the method to a logical variable, and then check the value of that variable and the `ERROR-STATUS:NUM-MESSAGES` value to be sure that the prepare succeeded. If it doesn’t and you continue without intercepting the error, your procedure generates a whole series of error statements as you attempt to open and use the query.

Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095