Calls an ABL procedure. This procedure can be local to or remote from the current session, external from or internal to the current procedure, and either synchronous or asynchronous. When a local or remote procedure is called synchronously, the calling procedure resumes execution only after the called procedure completes execution. When a remote procedure is called asynchronously, the calling procedure resumes execution immediately after the remote request is sent to the AppServer.
RUN
{ extern-proc-name
| VALUE ( extern-expression )
| path-name<<member-name>>
}
[ PERSISTENT [ SET proc-handle ] ]
[ ON [ SERVER ] { server-handle | session-handle }
[ TRANSACTION DISTINCT ]
[ ASYNCHRONOUS
[ SET async-request-handle ]
[ EVENT-PROCEDURE event-internal-procedure
[ IN procedure-context ] ]
]
]
[ ( parameter [ , parameter ] ... ) ]
[ argument ] ...
[ NO-ERROR ]
|
RUN
{ intern-proc-name | VALUE ( intern-expression) }
[ IN proc-handle ]
[ ASYNCHRONOUS
[ SET async-request-handle ]
[ EVENT-PROCEDURE event-internal-procedure
[ IN procedure-context ] ]
]
[ ( parameter [ , parameter ] ... ) ]
[ NO-ERROR ]
|
RUN portTypeName [ SET hPortType ] ON SERVER hWebService [ NO-ERROR ] .
|
RUN operationName IN hPortType
[ ASYNCHRONOUS
[ SET async-request-handle ]
[ EVENT-PROCEDURE event-internal-procedure
[ IN procedure-context ] ]
[ ( parameter [ , parameter ] ... ) ]
[ NO-ERROR ].
|
Specifies that the external procedure be run and created (instantiated) as a persistent procedure. You can return the handle to the persistent procedure in
proc-handle , a field, variable, or output parameter defined with the HANDLE data type. If you do not specify
proc-handle , you can find the procedure handle for this procedure using the FIRST-PROCEDURE and LAST-PROCEDURE attributes of the SESSION system handle. You can use PERSIST as an abbreviation for PERSISTENT.
ON [SERVER
] server-handle
With the ASYNCHRONOUS option, server-handle causes the called procedure to run
asynchronously in the remote session. Control returns immediately to the statement following the RUN statement. Execution of any specified
event-internal-procedure occurs in the context of an input-blocking or PROCESS EVENTS statement.
ON [SERVER
] session-handle
With the ASYNCHRONOUS option, session-handle causes the called procedure to run
synchronously in the local session, followed immediately by execution of any specified
event-internal-procedure. Only after execution of the specified
event-internal-procedure does control return to the statement following the RUN statement.
Specifies that the remote procedure is to be called as an asynchronous request. By default, the remote procedure is called synchronously. The handle to the asynchronous request is returned in
async-request-handle, which must be a field, variable, or parameter defined with the HANDLE data type. If you specify ASYNCHRONOUS but do not specify SET
async-request-handle, you can find the handle for the asynchronous request using the LAST-ASYNC-REQUEST attribute of the
server-handle specified by the ON option. You can also locate the asynchronous request handle by walking the chain between the FIRST-ASYNC-REQUEST and LAST-ASYNC-REQUEST attributes of
server-handle, searching on the PROCEDURE-NAME attribute of each request handle.
Specifies a quoted string or character expression representing the name of an internal procedure that resides within
procedure-context. When the response from the asynchronous request is received (that is, a PROCEDURE-COMPLETE event occurs), the specified internal procedure is called during subsequent execution of a PROCESS EVENTS or input-blocking statement (such as WAIT-FOR). The specified
event-internal-procedure processes any parameters and errors returned from the asynchronous request. If not specified, no event procedure is executed when the PROCEDURE-COMPLETE event occurs for the asynchronous request.
For information on how the event-internal-procedure handles parameters from the asynchronous request, see the
parameter option. For information on how the
event-internal-procedure handles errors from the asynchronous request, see the NO-ERROR option.
( parameter [ , parameter ] ... )
For OUTPUT parameters of an asynchronous remote procedure call only, you can specify
parameter-name AS
primitive-type-name as a prototype. The
parameter-name is an arbitrary place-holder name and
primitive-type-name must specify the ABL data type of the corresponding OUTPUT parameter in the asynchronous remote procedure. You can also specify OUTPUT parameters for an asynchronous remote procedure using a local
field,
variable, or TABLE
temp-table-name. However, note that the asynchronous remote procedure does not return any values to OUTPUT or INPUT-OUTPUT parameters on the RUN statement. These parameters are place holders only for values returned by the remote procedure to the specified
event-internal-procedure.
Any specified event-internal-procedure can define only INPUT parameters and must define one INPUT parameter for each OUTPUT or INPUT-OUTPUT parameter defined in the asynchronous remote procedure. Each
event-internal-procedure INPUT parameter must match the corresponding remote procedure OUTPUT or INPUT-OUTPUT parameter in order and data type. (As with other procedures, the AVM attempts to convert the values for data types that do not match.) The asynchronous remote procedure returns the values of these parameters to the INPUT parameters of the
event-internal-procedure after the remote procedure completes execution and the client session processes the associated PROCEDURE-COMPLETE event.
If you are running an internal procedure declared as a Windows dynamic link library (DLL) or UNIX shared library routine, you must match any RETURN parameter specified by a DEFINE PARAMETER statement with a corresponding OUTPUT parameter in the RUN statement. If the internal procedure does not specify the RETURN parameter, do not specify the corresponding OUTPUT parameter in the RUN statement.
When you pass arguments to an external procedure, the AVM converts those arguments to character format. ABL recompiles the called procedure, substitutes arguments, and then runs the procedure. You cannot precompile a procedure to which you pass arguments. (If you use shared variables instead of arguments, the procedure can be precompiled. This yields more efficient code.)
Specifies that any ERROR conditions that occur in the attempt to run the procedure are suppressed. This does
not mean that all errors produced by the called procedure are suppressed; only errors caused by the RUN statement itself. Also, if a specified local or synchronous remote procedure performs a RETURN ERROR, an ERROR is raised for the RUN statement. After the RUN statement completes, you can check the ERROR-STATUS system handle for information on any errors that occurred.
For an asynchronous remote procedure, the result depends on where the errors occur. If the errors occur during the send phase of the asynchronous request, this raises the ERROR condition on the RUN statement in the client (which you can suppress with NO-ERROR). If the errors occur during execution of the remote request and are returned by the AppServer, this results in an implied NO-ERROR on the RUN statement, and you must check the ERROR-STATUS system handle as well as the attributes of the asynchronous request handle (
async-request-handle) for any error returns in the specified
event-internal-procedure. If the asynchronous remote procedure returns an unhandled STOP condition, ERROR-STATUS:ERROR and
async-request-handle:ERROR are both set to FALSE and
async-request-handle:STOP is set to TRUE.
Table 60 summarizes when the AVM raises ERROR or STOP for each type of procedure.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The server-handle is not currently connected to some AppServer.
|
|
|
|
The PROXY attribute of proc-handle (from the IN proc-handle option) is TRUE and the associated server handle is no longer connected to an AppServer.
|
|
|
|
|
|
|
|
The AVM cannot locate the specified event-internal-procedure, for example, because the spelling of event-internal-procedure is not identical to the name of the internal procedure definition intended for use as the event procedure.
|
Suppresses ABL errors or error messages that would otherwise occur and diverts them to the
ERROR-STATUS system handle. If an error occurs, the action of the statement is not done and execution continues with the next statement. If the statement fails, any persistent side-effects of the statement are backed out. If the statement includes an expression that contains other executable elements, like methods, the work performed by these elements may or may not be done, depending on the order the AVM resolves the expression elements and the occurrence of the error.
|
Check if the ERROR-STATUS:NUM-MESSAGES attribute is greater than zero to see if the AVM generated error messages. ABL handle methods used in a block without a CATCH end block treat errors as warnings and do not raise ERROR, do not set the ERROR-STATUS:ERROR attribute, but do add messages to the ERROR-STATUS system handle. Therefore, this test is the better test for code using handle methods without CATCH end blocks. ABL handle methods used in a block with a CATCH end block raise ERROR and add messages to the error object generated by the AVM. In this case, the AVM does not update the ERROR-STATUS system handle.
|
|
A CATCH statement, which introduces a CATCH end block, is analogous to a NO-ERROR option in that it also suppresses errors, but it does so for an entire block of code. It is different in that the error messages are contained in a class-based error object (generated by the AVM or explicitly thrown), as opposed to the ERROR-STATUS system handle. Also, if errors raised in the block are not handled by a compatible CATCH block, ON ERROR phrase, or UNDO statement, then the error is not suppressed, but handled with the default error processing for that block type.
|
|
When a statement contains the NO-ERROR option and resides in a block with a CATCH end block, the NO-ERROR option takes precedence over the CATCH block. That is, an error raised on the statement with the NO-ERROR option will not be handled by a compatible CATCH end block. The error is redirected to the ERROR-STATUS system handle as normal.
|
|
If an error object is thrown to a statement that includes the NO-ERROR option, then the information and messages in the error object will be used to set the ERROR-STATUS system handle. This interoperability feature is important for those integrating code that uses the traditional NO-ERROR technique with the newer, structured error handling that features error objects and CATCH end blocks.
|
The name of the (local or remote) internal procedure you want to run. The procedure must be declared in the same procedure file as the RUN statement that calls it unless you specify the IN
proc-handle option or use a super procedure. If you do not specify the IN
proc-handle option and there is no internal procedure declared by the specified name, the AVM tries to run an external procedure with the specified name. If the internal procedure is remote, you must specify the IN
proc-handle option to identify the remote persistent procedure that defines the internal procedure on an AppServer.
The following procedure displays a simple menu. The user’s selection is stored in the selection variable. The INDEX function returns an integer value that indicates the position of the user’s selection in a string of characters ("12345"). If the value in the selection variable is not in the list of values, the INDEX function returns a 0. The VALIDATE statement ensures that the INDEX function did not return a zero. If it did, VALIDATE displays the message,
"Not a valid choice".
In the RUN statement, the INDEX function returns the position of the user’s selection in a character string. Suppose you chose option 2 from the menu. That option occupies the second position in the "12345" character string. Therefore, the INDEX function returns the number two (2). Using this number, the RUN statement reads, RUN VALUE(programs[2]). According to the assignments at the top of the procedure, the value of programs[2] is custedit.p. Now the RUN statement reads, RUN custedit.p, and the
r-run.p procedure runs the
custedit.p procedure.
The following two external procedures, r-runper.p and
r-perprc.p, illustrate the PERSISTENT and IN
proc-handle options of the RUN statement. The first procedure, a non-persistent control procedure, sets up a window to run and manage the second procedure as a persistent procedure.
The control procedure, r-runper.p, runs
r-perprc.p each time you choose the Start Customer Query button. Each time it runs,
r-perprc.p creates (instantiates) an additional context instance for the persistent procedure, including an additional window to open customer queries. When you choose the Recall All Hidden Queries button from the control window,
r-runper.p calls the recall-query internal procedure in each instance of
r-perprc.p to redisplay its window. Similarly, when you choose the Exit button,
r-runper.p calls the destroy-query internal procedure in each instance of
r-perprc.p to delete its context instance;
r-runper.p then applies the RETURN event to itself to terminate by completing the WAIT-FOR statement.
The r-perprc.p procedure sets up a customer query that you can re-open three different ways: by name, by balance, or by credit. Each instance of
r-perprc.p maintains a separate query for its own local customer buffer. Note that by testing and setting attributes of the THIS-PROCEDURE system handle,
r-perprc.p can run either persistently or non-persistently. The basic difference is how the procedure maintains its own context. For example, when running persistently, it defines a trigger on the bCancel button to run its own deletion procedure, destroy-query, to terminate; when running non-persistently, it completes a WAIT-FOR statement with the bCancel button to terminate.
When r-async.p returns, the user-interface trigger ends and the application returns to its WAIT-FOR state. The user continues to use the application in the normal way while the inventory report runs on the AppServer.
When runReport.p finishes running, a PROCEDURE-COMPLETE event occurs. This event causes the internal procedure reportDone to run automatically within the context of the application’s WAIT-FOR statement. Whatever the user is doing in the application, reportDone displays an alert box indicating whether or not the inventory report completed successfully and the number of lines (numLines) that were output for the report. (The bolded ABL statements indicate the code required to support asynchronous requests to run
runReport.p.)
|
Progress Version 6 uses time stamps by default to verify that r-code is consistent with the database schema. Some releases of Version 6 provide optional support for CRC codes instead of time stamps. Progress Version 7 and later uses CRC codes by default. If you want to use time stamps instead, specify the Time Stamp (-tstamp) parameter when you connect to a database.
|
|
You can run an internal procedure that is declared in the current external procedure or in the procedure you specify with the IN proc-handle option. The procedure handle specified by the IN proc-handle option can specify either a valid persistent procedure instance or an external procedure that is active on the procedure call stack. The handle can also specify the current external procedure using the THIS-PROCEDURE system handle. You can check the validity of any procedure handle using the VALID-HANDLE function.
|
|
A called external procedure uses any arguments passed to it from the calling procedure by referring to those arguments as numbers enclosed in braces { }. The first argument is {1}, the next is {2}, etc. Any arguments the called procedure does not use are ignored, and any missing arguments are treated as null values. (Note that the null is a legal value in a WHERE or WITH clause, but its occurrence can cause an error at other points in a called procedure.)
|
|
To run an r-code file stored in a library that is not on PROPATH, you must specify the name of the library and the name of the r-code file in the library. Specify these names in the form path-name<< member-name>>, where path-name is the pathname of the library and member-name is the name of the r-code file. For example, if you have an r-code file called appmenu.r in a library whose pathname is /usr/foo/app.pl, you use this command to run it:
|
|
When you run a procedure and do not specify the PERSISTENT option, the AVM first looks for an internal procedure with the name you specify (this search is not case sensitive). If you specify a procedure in the form path-name<< member-name>>, the AVM looks for an internal procedure with a name in that form. If you specify the PERSISTENT option, or if no internal procedure is found, the AVM searches all the directories and libraries in PROPATH for a usable r-code file of the same name. The AVM also checks to see if the procedure was modified since the last time it was run. If there is a usable r-code file, there is no point in performing the compilation. The RUN statement always uses an existing r-code file before using a session compile version of a procedure.
|
When you specify a suffix or file extension (such as .p), the AVM first tries replacing that suffix or extension with .r and searches the first directory on your
PROPATH for a file with that name. If the r-code file is not found, then it reverts to the original suffix and searches for a source file with that name. If the source file is not found in the first
PROPATH directory, then the AVM searches for an r-code file and then a source file in each subsequent directory on your
PROPATH until a file is found.
|
The procedure does not go out of scope when it returns: its context and most of its allocated resources remain active, including input parameters, widgets, variables, buffers, temp-tables, work tables, and triggers created during procedure execution. However, all static dialog boxes, their child widgets, and related triggers created during its execution are destroyed when the procedure returns to the caller. This makes all other windows and dialog boxes in the application available for input.
|
|
All buffers passed as parameters to a persistent procedure are treated as local buffers in the persistent context. When the procedure instantiation returns, the output value of the buffer parameter is returned, as usual, to the calling procedure. However, any cursor positioning established during execution of the instantiating RUN statement is lost to the persistent context once the procedure returns; the AVM creates a copy of the buffer parameter and resets its cursors as an initially defined local buffer.
|
|
To run a UNIX shared library routine as an internal procedure, you must reference the UNIX shared library in a PROCEDURE statement and define its parameters in the associated internal procedure block. You can declare an internal procedure as a routine in a UNIX shared library in the same manner as declaring a DLL routine. The one exception is that the ORDINAL option is not applicable to UNIX and will be ignored. For example:
|
|
Increments the proc-handle:ASYNC-REQUEST-COUNT attribute, if PERSISTENT is specified for a remote external procedure or IN proc-handle is specified for a remote internal procedure
|
|
Sets the async-request-handle:COMPLETE attribute to FALSE, indicating that the request has not completed execution
|
|
Sets the async-request-handle:EVENT-PROCEDURE attribute to the value of event-internal-procedure, if event-internal-procedure is specified
|
|
Sets the async-request-handle:EVENT-PROCEDURE-CONTEXT attribute to the value of procedure-context, if procedure-context is specified
|
With the ASYNCHRONOUS option, using the ON SERVER SESSION option causes the called procedure to run
synchronously in the local session, followed immediately by execution of any specified
event-internal-procedure. Only after execution of the specified
event-internal-procedure does control return to the statement following the RUN statement. This synchronous local execution includes the following differences in error handling from asynchronous execution on an AppServer using ON SERVER
server-handle:
|
If the called local procedure causes an ERROR or STOP condition to be raised in the calling procedure (a file not found, mismatched parameters, a compile error, and explicit execution of a RETURN ERROR or STOP statement), the AVM sends the associated message to the standard output device and sets ERROR-STATUS:ERROR appropriately. This is different from remote execution, where the AVM in most cases attaches the associated message to the ERROR-STATUS system handle.
|
|
Also, if the called local procedure causes an ERROR or STOP condition to be raised in the calling procedure (as in the previous note), the AVM raises the condition on the RUN statement, as for a local RUN statement without the ON SERVER option. This is different from remote execution, where the AVM does not raise the condition on the calling RUN statement. You can work around this for the ON SERVER SESSION case by coding each asynchronous RUN statement with the NO-ERROR option and possibly surrounding it with a DO ON STOP UNDO, LEAVE block.
|
|
For more information on AppServers and calling remote procedures synchronously or asynchronously, see OpenEdge Application Server: Developing AppServer Applications.
|
{ } Argument reference,
{ } Include file reference,
APPLY statement,
Asynchronous request object handle,
CODEBASE-LOCATOR system handle,
COMPILE statement,
CREATE SERVER statement,
DEFINE PARAMETER statement,
DELETE PROCEDURE statement,
ON statement,
Parameter passing syntax,
PROCEDURE statement,
Procedure object handle,
RUN STORED-PROCEDURE statement,
THIS-PROCEDURE system handle,
VALID-HANDLE function,
Widget phrase