Kbase 21396: How To Pass Dynamic Temp-tables Between Processes?
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  4/27/2010 |
|
Status: Verified
GOAL:
How to pass dynamic temp-tables as INPUT, OUTPUT or INPUT-OUTPUT parameters between processes or dynamic functions?
GOAL:
How To Pass Dynamic Temp-tables Between Processes?
GOAL:
How To Pass Dynamic Temp-tables Between Dynamic Functions?
FACT(s) (Environment):
All Supported Operating Systems
Progress 9.x
OpenEdge 10.x
FIX:
When using static temp-tables, the 'TABLE' keyword is used to specify that the parameter is a temp-table. The following is an example of a RUN statement using a static temp-table:
DEFINE TEMP-TABLE ttCustomer NO-UNDO LIKE customer.
RUN proc.p (INPUT TABLE ttCustomer).
In order to pass dynamic temp-tables, the keyword 'TABLE-HANDLE' was added in the Progress 4GL. The following is an example of a RUN statement using a dynamic temp-table:
DEFINE VARIABLE hTempTable AS HANDLE NO-UNDO.
CREATE TEMP-TABLE hTempTable.
hTempTable:CREATE-LIKE("customer").
RUN proc.p (INPUT TABLE-HANDLE hTempTable).
Example Explanation
At the end of this Knowledge Base there is an example which shows how to handle, create and pass dynamic temp-tables between the Client and Server side using the Progress AppServer. The procedure dynBrowser.p is the Client side procedure. It gets the table records using a dynamic temp-table as OUTPUT parameter in the RUN statement and shows these records in a dynamic browser.Procedure 'getTableRecords' and function 'getBufferFields' are internal processes of the Server side procedure (procServer.p in this example).
The CREATE-LIKE function cannot be used in the Client side, because there is no data base connection, and also the dynamic temp-table definitions in the Client and Server side must be the same. You have to use the function 'getBufferFields' -- it returns the field definitions for the specified table in the following format:
FieldName1,fieldType1,FieldFormat1 + CHR(1) + FieldNamen,fieldTypen,FieldFormatn?.
The value returned by the 'getBufferFields' function is used in the ADD-NEW-FIELD function in order to create the dynamic temp-table fields without references to the Database.
Following are the example processes. The structured procedure, prcServer.p, has to be created. The 'getTableRecord' procedure and the 'getBufferFields' function have to be added as internal procedures of it.
/*-------------------------------------------------------*/
/* PROCEDURE dynBrowser.p */
/*-------------------------------------------------------*/
ASSIGN CURRENT-WINDOW:HEIGHT-CHARS = 18
CURRENT-WINDOW:WIDTH-CHARS = 132.
DEFINE BUTTON bQuit LABEL "&Quit" AUTO-ENDKEY.
DEFINE VARIABLE Browse-Hndl AS HANDLE NO-UNDO.
DEFINE VARIABLE bufFieldHandle AS HANDLE NO-UNDO.
DEFINE VARIABLE qh AS HANDLE NO-UNDO.
DEFINE VARIABLE bh AS HANDLE NO-UNDO.
DEFINE VARIABLE hTempTable AS HANDLE NO-UNDO.
DEFINE VARIABLE hServer AS HANDLE NO-UNDO.
DEFINE VARIABLE hProc AS HANDLE NO-UNDO.
DEFINE VARIABLE lConnect AS LOGICAL NO-UNDO.
DEFINE VARIABLE iFields AS INTEGER NO-UNDO.
DEFINE VARIABLE cBufferFields AS CHARACTER NO-UNDO.
DEFINE VARIABLE cBufferField AS CHARACTER NO-UNDO.
DEFINE VARIABLE cFields AS CHARACTER NO-UNDO INITIAL "city,state,country,postalcode".
CREATE SERVER hServer.
ASSIGN lConnect = hServer:CONNECT("-AppService MyApp -S 5162 -H tstst70") NO-ERROR.
IF NOT lConnect THEN ASSIGN hServer = SESSION:HANDLE.
RUN procServer.p PERSISTENT SET hProc ON SERVER hServer.
CREATE TEMP-TABLE hTempTable.
ASSIGN cBufferFields = DYNAMIC-FUNCTION('getBufferFields' IN hProc,"customer").
DO iFields = 1 TO NUM-ENTRIES(cBufferFields,CHR(1)):
ASSIGN cBufferField = ENTRY(iFields,cBufferFields,CHR(1)).
hTempTable:ADD-NEW-FIELD(ENTRY(1,cBufferField),ENTRY(2,cBufferField),0,ENTRY(3,cBufferField)).
END.
hTempTable:TEMP-TABLE-PREPARE("temptable").
RUN getTableRecrds IN hProc (OUTPUT TABLE-HANDLE hTempTable, "Customer").
bh = hTempTable:DEFAULT-BUFFER-HANDLE.
CREATE QUERY qh.
qh:SET-BUFFERS(bh).
DEFINE FRAME F1 SKIP(13) bQuit WITH SIZE 132 BY 18 THREE-D NO-LABELS.
RUN createBrowser.
PROCEDURE createBrowser:
DEFINE VARIABLE iFields AS INTEGER .NO-UNDO.
DEFINE VARIABLE Field-hdl AS HANDLE NO-UNDO.
CREATE BROWSE Browse-Hndl
ASSIGN FRAME = FRAME F1:HANDLE
QUERY = qh
TITLE = " "
X = 2
Y = 2
WIDTH = 130
DOWN = 12
VISIBLE = TRUE
SENSITIVE = TRUE
READ-ONLY = NO
COLUMN-SCROLLING = TRUE
SEPARATORS = YES
TRIGGERS:
ON 'ROW-LEAVE':U PERSISTENT RUN brRowLeave.
END TRIGGERS.
qh:QUERY-PREPARE("for each temptable NO-LOCK":U).
qh:QUERY-OPEN.
/* Adding the fields custnum and Name, these fields will be not enabled */
Browse-Hndl:ADD-LIKE-COLUMN(bh:BUFFER-FIELD(1),1).
Browse-Hndl:ADD-LIKE-COLUMN(bh:BUFFER-FIELD(3),2).
/* Fields that will be enabled */
DO iFields = 1 TO NUM-ENTRIES(cFields):
ASSIGN Field-hdl = Browse-Hndl:ADD-LIKE-COLUMN(bh:BUFFER-FIELD(ENTRY(iFields,cFields)))
Field-hdl:READ-ONLY = FALSE.
END.
END PROCEDURE.
ON CHOOSE OF bQuit DO:
APPLY "window-close" TO CURRENT-WINDOW.
END.
ENABLE ALL WITH FRAME F1.
WAIT-FOR CLOSE OF CURRENT-WINDOW.
/*-------------------------------------------------------*/
/* FUNCTION getBufferFields */
/*-------------------------------------------------------*/
FUNCTION getBufferFields RETURNS CHARACTER (pcTable AS CHARACTER):
DEFINE VARIABLE cFields AS CHARACTER NO-UNDO.
DEFINE VARIABLE hBuffer AS HANDLE NO-UNDO.
DEFINE VARIABLE hField AS HANDLE NO-UNDO.
DEFINE VARIABLE iFields AS INTEGER NO-UNDO.
CREATE BUFFER hBuffer FOR TABLE pcTable.
DO iFields = 1 TO hBuffer:NUM-FIELDS.
ASSIGN hField = hBuffer:BUFFER-FIELD(iFields).
IF cFields NE "" THEN ASSIGN cFields = cFields + CHR(1).
ASSIGN cFields = cFields + hField:NAME + "," + hField:DATA-TYPE + "," + hField:FORMAT.
END.
RETURN cFields.
END FUNCTION.
/*-------------------------------------------------------*/
/* PROCEDURE getTableRecrds */
/*-------------------------------------------------------*/
PROCEDURE getTableRecrds:
DEFINE OUTPUT PARAMETER TABLE-HANDLE hTempTable.
DEFINE INPUT PARAMETER pcTable AS CHARACTER NO-UNDO.
DEFINE VARIABLE hQuery AS HANDLE NO-UNDO.
DEFINE VARIABLE hBufferTT AS HANDLE NO-UNDO.
DEFINE VARIABLE hBuffer AS HANDLE NO-UNDO.
DEFINE VARIABLE hField AS HANDLE NO-UNDO.
CREATE BUFFER hBuffer FOR TABLE pcTable BUFFER-NAME "BufferTable":U.
CREATE TEMP-TABLE hTempTable.
hTempTable:ADD-FIELDS-FROM(pcTable).
hTempTable:TEMP-TABLE-PREPARE("tt").
hBufferTT = hTempTable:DEFAULT-BUFFER-HANDLE.
CREATE QUERY hQuery.
hQuery:SET-BUFFERS(hBuffer).
hQuery:QUERY-PREPARE("FOR EACH BufferTable NO-LOCK").
hQuery:QUERY-OPEN().
REPEAT:
hQuery:GET-NEXT().
IF hQuery:QUERY-OFF-END THEN LEAVE.
hBufferTT:BUFFER-CREATE.
hBufferTT:BUFFER-COPY(hBuffer).
END.
hQuery:QUERY-CLOSE().
hBuffer:BUFFER-RELEASE().
DELETE OBJECT hTempTable.
DELETE OBJECT hQuery.
END PROCEDURE. .