RUN statement
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.
The RUN statement can also call functions or routines that reside in the Windows Dynamic Link Libraries (DLLs) or in UNIX shared libraries. The called routine must first be declared like an ABL internal procedure. The procedure declaration must be in the same file as the RUN statement.
You can also use the RUN statement to create and associate a procedure object with a Web service, and invoke a Web service operation.
Syntax
Use the following syntax to create and associate a procedure object with a Web service:
Use the following syntax to invoke a Web service operation:
extern-proc-name
The name of the (local or remote) external procedure to run. On UNIX, external procedure names are case sensitive; in Windows, they are not. If you specify a relative pathname, ABL searches the directories (and libraries, on platforms that support libraries) defined in thePROPATH
environment variable. Withextern-proc-name
, you can specify a local or remote procedure.VALUE (extern-expression
)path-name
<<member-name
>>PERSISTENT [SETproc-handle
]
Specifies that the external procedure be run and created (instantiated) as a persistent procedure. You can return the handle to the persistent procedure inproc-handle
, a field, variable, or output parameter defined with the HANDLE data type. If you do not specifyproc-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.A persistent procedure creates and maintains its context after it returns to the caller. Other external procedures can access this context through procedure triggers and internal procedures defined in the persistent procedure. Thus, a RUN statement that runs and creates a persistent procedure context is referred to as aninstantiating RUN statement
.The order of the PERSISTENT option and the ON SERVER option is interchangeable.ON [SERVER]server-handle
Tells the AVM to run the procedure remotely in the AppServer that the HANDLE variable,server-handle
, refers to.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 specifiedevent-internal-procedure
. occurs in the context of an I/O blocking or PROCESS EVENTS statement.The order of the PERSISTENT option and the ON SERVER option is interchangeable.ON [SERVER]session-handle
Tells the AVM to run the procedure locally in the current ABL session, specified by the value of the SESSION system handle (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 specifiedevent-internal-procedure
. Only after execution of the specifiedevent-internal-procedure
does control return to the statement following the RUN statement.Note: This order of execution is different than for a remote procedure call using theserver-handle
.The order of the PERSISTENT option and the ON SERVER option is interchangeable.TRANSACTION DISTINCT
Tells the AVM not to propagate the calling procedure’s transaction to the AppServer. Although the current version of ABL does not allow transaction propagation, future versions might. Thus, to accommodate this possibility without breaking current code, the current version of ABL allows you to specify this option withserver-handle
.Note: It is an error to specify TRANSACTION DISTINCT with asession-handle
.ASYNCHRONOUS [ SETasync-request-handle
]
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 inasync-request-handl
e, which must be a field, variable, or parameter defined with the HANDLE data type. If you specify ASYNCHRONOUS but do not specify SETasync-request-handle
, you can find the handle for the asynchronous request using the LAST-ASYNC-REQUEST attribute of theserver-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 ofserver-handle
, searching on the PROCEDURE-NAME attribute of each request handle.For a Web service operation invoked asynchronously, the handle that is set to the asynchronous request object created for the asynchronous request.EVENT-PROCEDUREevent-internal-procedure
Specifies a quoted string or character expression representing the name of an internal procedure that resides withinprocedure-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 I/O-blocking statement (such as WAIT-FOR). The specifiedevent-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 theevent-internal-procedure
handles parameters from the asynchronous request, see theparameter
option. For information on how theevent-internal-procedure
handles errors from the asynchronous request, see the NO-ERROR option.INprocedure-context
(
parameter
[
,
parameter
]
...
)
Specifies one or more parameters to pass to the called procedure.For the parameter passing syntax, see the Parameter passing syntax reference entry.Parameters must be defined in the called procedure. (See the DEFINE PARAMETER statement reference entry.) They must be passed in the same order as they are defined, and they must have compatible data types. The AVM attempts to convert values for data types that do not match. If the AVM cannot convert the value for a mismatched data type, the RUN statement fails with an error condition.For OUTPUT parameters of an asynchronous remote procedure call only, you can specifyparameter-name
ASprimitive-type-name
as a prototype. Theparameter-name
is an arbitrary place-holder name andprimitive-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 localfield
,variable
, or TABLEtemp-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 specifiedevent-internal-procedure
.Any specifiedevent-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. Eachevent-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 theevent-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.For external procedures, the parenthesized list of run-time parameters must precede any compile-time arguments.argument
A constant, field name, variable name, or expression that you want to pass as a compile-time argument to the external procedure you are running.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.)Note: You cannot pass compile-time arguments in a call to an internal procedure.NO-ERROR (RUN statement specific behavior)Note: See the next entry for a description of general NO-ERROR option behavior. This entry describes special cases for the RUN statement.
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 specifiedevent-internal-procedure
. If the asynchronous remote procedure returns an unhandled STOP condition, ERROR-STATUS:ERROR andasync-request-handle
:ERROR are both set to FALSE andasync-request-handle
:STOP is set to TRUE.The RUN statement returns ERROR or STOP for a variety of events depending on the type of procedure that is executed, which includes any of the following:Table 59 summarizes when the AVM raises ERROR or STOP for each type of procedure.
Table 59: RUN statement ERROR and STOP conditions Procedure type Condition Event All procedures ERROR The run-time parameters are not compatible. ERROR Any specified INproc-handle
option is invalid. ERROR A called internal procedure is not found in the specified external procedure. ERROR The procedure returns ERROR. STOP The procedure returns an unhandled STOP. Local procedures STOP The specified procedure is not found.1 STOP An attempted compile of the procedure failed.1 All remote procedures ERROR The specified procedure is not found. ERROR An attempted compile of the procedure failed. ERROR The specified ON SERVERserver-handle
option is invalid. ERROR Theserver-handle
is not currently connected to some AppServer. ERROR One of the parameters specified byparameter
has a data type of BUFFER. ERROR The PROXY attribute ofproc-handle
(from the INproc-handle
option) is TRUE and the associated server handle is no longer connected to an AppServer. Synchronous remote procedures ERROR The ASYNC-REQUEST-COUNT attribute on theserver-handle
is greater than zero (0). Asynchronous remote procedures ERROR The REMOTE attribute ofprocedure-context
is set to TRUE. In addition, under the following conditions, a STOP condition occurs in the context of the I/O-blocking or PROCESS EVENTS statement that invokes any specifiedevent-internal-procedure
:
- The AVM cannot locate the specified
event-internal-procedure
, for example, because the spelling ofevent-internal-procedure
is not identical to the name of the internal procedure definition intended for use as the event procedure.- The procedure handle that specifies the
procedure-context
to contain the definition ofevent-internal-procedure
is not a valid procedure handle.NO-ERROR (general behavior)Note: See the previous entry for a description of specific RUN statement NO-ERROR option behavior. This entry describes general NO-ERROR behavior.
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.To check for errors after a statement that uses the NO-ERROR option:
- Check the ERROR-STATUS:ERROR attribute to see if the AVM raised the ERROR condition.
- 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.
- Use ERROR-STATUS:GET-MESSAGE(
message-num
) to retrieve a particular message, wheremessage-num
is 1 for the first message.If the statement does not include the NO-ERROR option, you can use a CATCH end block to handle errors raised by the statement.Some other important usage notes on the NO-ERROR option:
- NO-ERROR does not suppress errors that raise the STOP or QUIT condition.
- 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.
intern-proc-name
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 INproc-handle
option or use a super procedure. If you do not specify the INproc-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 INproc-handle
option to identify the remote persistent procedure that defines the internal procedure on an AppServer.VALUE (intern-expression
)INproc-handle
portTypeName
hPortType
hWebService
operationName
ExamplesThe 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 thecustedit.p
procedure.The following two external procedures,
r-runper.p
andr-perprc.p
, illustrate the PERSISTENT and INproc-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
, runsr-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 ofr-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 ofr-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 ofr-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.The following example shows how you might implement an asynchronous request. The procedure
r-async.p
runs persistently from a user-interface trigger, perhaps in response to a menu choice. This procedure, in turn, sends a request to runrunReport.p
on an AppServer, which provides an inventory report for the specified date.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 runrunReport.p
.)
Notes
- ABL procedures can be run recursively (a procedure can run itself).
- 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.
- When a RUN statement raises the STOP condition, the AVM displays the resulting messages on the current output device, even if you specify NO-ERROR. The AVM also writes these messages to the ERROR-STATUS system handle, but sets ERROR-STATUS:ERROR to FALSE.
- 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 INproc-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 formpath-name
<<member-name
>>, wherepath-name
is the pathname of the library andmember-name
is the name of the r-code file. For example, if you have an r-code file calledappmenu.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 inPROPATH
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.If you do not want the AVM to check whether the procedure has been modified before using the r-code, use the Quick Request (-q) parameter.- When running an external procedure, it is good practice to specify the name of the source file in the RUN statement. For example, to run
r-exit.p
you specify the following:
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 yourPROPATH
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 firstPROPATH
directory, then the AVM searches for an r-code file and then a source file in each subsequent directory on yourPROPATH
until a file is found.If you specify the .r suffix in the RUN statement, then the AVM searches only for an r-code file in each directory on yourPROPATH
. If you omit the extension, then the AVM first adds a .r to the name you specify and searches the first directory for an r-code file with that name. If none is found, then the AVM searches for a source file with no suffix or extension.- You cannot run an internal procedure with the PERSISTENT option.
- An external procedure called with the PERSISTENT option runs in the same way as a non-persistent procedure with these differences:
- 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.
- If the procedure obtains any schema share locks (through database access) while executing, these remain in effect after the procedure returns, until the procedure is deleted.
- Each time you run a procedure persistently, you create a new instance of its procedure context. All of its data, buffers, and widgets are duplicated and separately managed by the new instantiation until the procedure instance is deleted.
Note: If you run an application that creates persistent procedures from an ADE tool (for example, the Procedure Editor or User Interface Builder), that tool removes all instances of persistent procedures still created when the application terminates.- Transaction scoping is the same whether you run a procedure as persistent or not. Any transaction which begins inside a persistent procedure is scoped to the block that starts the transaction.
- If you run a procedure with the PERSISTENT option and a STOP or QUIT condition or a RETURN ERROR occurs during execution of the procedure, the procedure returns as a non-persistent procedure.
- All shared variables, buffers, temp-tables, ProDataSet objects, work tables, and queries remain in scope as long as a persistent procedure instance remains that accesses them. This is true even if the procedure (persistent or non-persistent) that originally defined the shared data has gone out of scope. Shared data can go out of scope only when no persistent procedure remains that references it.
- You cannot run a procedure with the PERSISTENT option in which you have defined shared streams or shared frame, browse, or menu widgets. Doing so causes the AVM to raise ERROR on the RUN statement.
- You can remove an instance of a persistent procedure using the DELETE PROCEDURE statement. When you delete the procedure instance, its context goes out of scope and all allocated resources are returned to the system. If the procedure has shared dependencies on the call stack, the delete pends until the dependencies are cleared.
- To run a Windows DLL routine as an internal procedure, you must reference the DLL in a PROCEDURE statement and define its parameters in the associated internal procedure block. For more information on accessing DLL routines from ABL, see OpenEdge Development: Programming Interfaces.
- 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:
- You can define triggers on procedure handles (procedure triggers). You can apply events to any procedure trigger defined either within a persistent procedure or within any external procedure that is active on the procedure call stack. For example:
This code fragment assumes that a trigger is defined withinpersproc.p
for the RETURN event on the THIS-PROCEDURE handle.- If you are using ABL with a DataServer that supports stored procedures, the RUN statement has extensions that allow you to execute a stored procedure. For more information, see the entry for the RUN STORED-PROCEDURE statement and the appropriate OpenEdge DataServer Guides (OpenEdge Data Management: DataServer for Microsoft SQL Server, OpenEdge Data Management: DataServer for ODBC, and OpenEdge Data Management: DataServer for Oracle).
- If you RUN a procedure multiple times within a session, changing the procedure between runs, you must manually recompile the procedure each time. Otherwise, the procedure’s last r-code, which persists for a session, is what is run and the changes do not appear.
- An asynchronous call to a remote procedure (using the ASYNCHRONOUS option) causes the RUN statement to return control immediately to the following statement in the local context, whether or not the remote procedure has completed execution.
- If an asynchronous call to a remote procedure does not raise a STOP or ERROR condition, the AVM:
- Increments the
server-handle
:ASYNC-REQUEST-COUNT attribute- Increments the
proc-handle
:ASYNC-REQUEST-COUNT attribute, if PERSISTENT is specified for a remote external procedure or INproc-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 ofevent-internal-procedure
, ifevent-internal-procedure
is specified- Sets the
async-request-handle
:EVENT-PROCEDURE-CONTEXT attribute to the value ofprocedure-context
, ifprocedure-context
is specified- Submits the request for execution by the AppServer
- The AVM checks the syntax of the ON SERVER option at run time. This allows you to use a single HANDLE variable that you can set either to a server handle value or the value of the current SESSION handle. Thus, you can use the same RUN statement to execute a procedure remotely in an AppServer or locally depending on application conditions.
- When you specify the ON SERVER option with the SESSION system handle, the RUN statement is functionally similar to not specifying the ON SERVER option at all. That is, the two RUN statements in the following code perform the same function:
Allowing the same ON SERVER option to specify either a local session or a remote AppServer session facilitates code generation for applications like the OpenEdge AppBuilder.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 specifiedevent-internal-procedure
. Only after execution of the specifiedevent-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 SERVERserver-handle
:
- If an unhandled ERROR condition occurs during execution of the called local procedure, the error message is displayed on the local output device. This is different from remote execution, where any error message is written to the AppServer log file.
- 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.
- For more information on asynchronous invocation of Web service operations, see OpenEdge Development: Web Services.
See also{ } 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
OpenEdge Release 10.2B
|