RUN statement
- Last Updated: January 18, 2024
- 26 minute read
- OpenEdge
- Version 12.8
- Documentation
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 application server.
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 run an external procedure or method:
|
Use the following syntax to run an internal procedure or method:
|
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 the
PROPATHenvironment variable. With extern-proc-name, you can specify a local or remote procedure. In Windows, the pathname cannot contain characters outside of the non-Unicode code page. See Internationalize ABL Applications for more information about Unicode and code pages. - VALUE ( extern-expression )
- An expression that returns the name of the (local or remote) external procedure you want to run.In Windows, the pathname cannot contain characters outside of the non-Unicode code page.
- path-name<<member-name>>
- The pathname of an r-code library and the name of an r-code file in that library. To specify an r-code file in a library, you must use the double angle brackets as shown. If you specify a relative library pathname, ABL searches the libraries defined in the PROPATH environment variable. In Windows, the pathname cannot contain characters outside of the non-Unicode code page.
- PERSISTENT [SET proc-handle]
- Specifies that the external procedure be instantiated and
run as a persistent procedure.
You can return the handle to the persistent procedure in proc-handle specified as a field, variable, class property, 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-PROCEDUREorLAST-PROCEDUREattributes of theSESSIONsystem handle.For remote persistent procedures, proc-handle returns the proxy (remote) handle to the persistent procedure. You can also find the proxy handle by using the
FIRST-PROCEDUREorLAST-PROCEDUREattributes of the server object handle for the application server specified with theON SERVERoption.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 or user-defined functions defined in the persistent procedure. A
RUNstatement that runs and creates a persistent procedure context is referred to as an instantiating RUN statement. Thus, a persistent procedure has the following characteristics:- 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 AppBuilder), 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.
The order of the
PERSISTENToption and theON SERVERoption is interchangeable.You can use
PERSISTas an abbreviation forPERSISTENT.If you want to invoke persistent procedures on a session-free Progress Application Server (PAS) for OpenEdge server, use either
SINGLE-RUNorSINGLETONas an alternative to thePERSISTENToption. - SINGLE-RUN
SET proc-handle][ - Initializes the specified external procedure to run on an
application server or on the client (by using a
SESSIONhandle) in single-run mode, but it does not initially run the procedure.The
SINGLE-RUNoption is particularly useful for a session-free PAS for OpenEdge instance because it allows you to call internal procedures or user-defined functions in a remote external procedure without binding the client to a single application server session. In addition, network traffic is reduced when you run a procedure as a single-run.In single-run mode, the external procedure is instantiated only when an internal procedure or user-defined function that it defines is invoked remotely. The single-run procedure is deleted when the internal procedure or user-defined function completes. Compare with the
SINGLETONoption, where the singleton procedure remains instantiated after the internal procedure or user-defined function completes. See the description under intern-proc-name for more information on how internal procedures and user-defined functions run inSINGLE-RUNmode.You can return the proxy handle to the single-run procedure in proc-handle specified as a field, variable, class property, or output parameter defined with the HANDLE data type. If you do not specify proc-handle, you can find the proxy handle for this procedure using the
FIRST-PROCEDUREandLAST-PROCEDUREattributes of the server object handle for the application server specified using theON SERVERoption.Each time you call an internal procedure or user-defined function on a single-run procedure, you create a new instance of its procedure context, which only exists during the execution of the internal procedure or user-defined function. All of its data, buffers, and widgets are duplicated and separately managed by the new instantiation until the procedure instance is deleted.
Note:You must use the
ON SERVERoption when you use theSINGLE-RUNoption.You cannot use
SINGLE-RUNwith external procedures that have parameters.If you attempt to delete a single-run procedure from a client, you only delete the proxy handle. A single-run procedure remains instantiated for an application server session only until its instantiating internal procedure or user-defined function completes execution.
When a single-run procedure is invoked and the procedure is already instantiated as a singleton, the application server or client deletes the singleton procedure. The procedure is re-instantiated as a single-run. When the execution of the internal procedure or user-defined function completes, the application server or client deletes the single-run procedure but does not re-instantiate the procedure as a singleton.
You cannot use the
ASYNCHRONOUSoption withSINGLE-RUNwhen instantiating an external procedure. However you can run an internal procedure of aSINGLE-RUNprocedure asynchronously using the following syntax:RUNintern_proc-nameINproc-handle. . . ASYNCHRONOUS.You can use the
EXPORT( )method on theSESSIONhandle to add a procedure that will be run in single-run mode to the list of authorized remote procedures on the application server.For single-run procedures, the main block does not run until the internal procedure or user-defined function first runs. Therefore, an
ERRORorSTOPcondition occurring in the main block is raised during the first execution of the internal procedure or user-defined function. - SINGLETON
SET proc-handle][ - Initializes the specified external procedure to run on an
application server or on the client (by using a
SESSIONhandle) in singleton mode, but it does not initially run the procedure.The
SINGLETONoption is particularly useful for a session-free application server session because it allows you to call internal procedures or user-defined functions in a remote external procedure without binding the client to a single application server session. In addition, network traffic is reduced when you run a procedure as a singleton.In singleton mode, the external procedure is instantiated only when an internal procedure or user-defined-function that it defines is invoked remotely, and only if the singleton procedure is not already instantiated for a previous internal remote invocation.
The external procedure remains instantiated after its internal procedure or user-defined function completes execution. Compare with the single-run mode, where the procedure is deleted after an internal procedure or user-defined function completes execution. With the
SINGLETONoption, the external procedure remains instantiated and is used the next time one of its internal procedures or user-defined functions is run. See the description under intern-proc-name for more information on how internal procedures and user-defined functions run in singleton mode.You can return the proxy handle to a singleton procedure in proc-handle specified as a field, variable, class property, or output parameter defined with the HANDLE data type. If you do not specify proc-handle, you can find the proxy handle for this procedure using the
FIRST-PROCEDUREandLAST-PROCEDUREattributes of the server object handle for the application server specified using theON SERVERoption.An external procedure called with theSINGLETONoption runs in the same way as other procedures, but with these differences:- The procedure does not go out of scope when it returns. Most of its allocated resources remain active, including objects, variables, buffers, temp-tables, work tables, and triggers created during procedure execution. However, you should not keep or rely on any context information maintained for a singleton procedure. Each application server session maintains its own context information independent of (and probably differing from) other application server sessions. Since there is no guarantee which application server session will process a given request, there is no way of knowing what context information will be available.
- 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.
Note:You must use the
ON SERVERoption when you use theSINGLETONoption.You cannot use the
SINGLETONoption with external procedures that have parameters.Only one instance of a given singleton procedure exists for a given application server session, no matter how many clients initialize the procedure with the
SINGLETONoption. Therefore, all clients access the same instance of a singleton procedure in requests to the same application server session.If you attempt to delete a singleton procedure from a client using the DELETE PROCEDURE statement, you only delete the proxy handle. A singleton remains instantiated for an application server session until session code deletes it or the session terminates.
When a single-run procedure is invoked and the procedure is already instantiated as a singleton, the application server or client deletes the singleton procedure. The procedure is re-instantiated as a single-run. When the execution of the internal procedure or user-defined function completes, the application server or client deletes the single-run procedure but does not re-instantiate the procedure as a singleton.
You cannot use the
ASYNCHRONOUSoption withSINGLETONwhen instantiating an external procedure. However you can run an internal procedure of aSINGLETONprocedure asynchronously using the following syntax:RUNintern-proc-nameINproc-handle. . . ASYNCHRONOUS.You can use the
EXPORT( )method on theSESSIONhandle to add a procedure that will be run as a singleton to the list of authorized remote procedures on the application server.For singleton procedures, the main block does not run until the internal procedure or user-defined function first runs. Therefore, an
ERRORorSTOPcondition occurring in the main block is raised during the first execution of the internal procedure or user-defined function. - ON [SERVER]server-handle
- Tells the AVM to run the procedure remotely in the
application server that the HANDLE variable, server-handle , refers to.
With the
ASYNCHRONOUSoption, server-handle causes the called procedure to run asynchronously in the remote session. Control returns immediately to the statement following theRUNstatement. Execution of any specified event procedure or method occurs in the context of an input-blocking orPROCESS EVENTSstatement.The order of any
PERSISTENT,SINGLE-RUN, orSINGLETONoption and theON SERVERoption 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
SESSIONsystem handle (session-handle).With the
ASYNCHRONOUSoption, 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 theRUNstatement.Note: This order of execution is different than for a remote procedure call using the server-handle.The order of the
PERSISTENT,SINGLE-RUN, orSINGLETONoption and theON SERVERoption is interchangeable. - TRANSACTION DISTINCT
- Tells the AVM not to propagate the calling procedure's
transaction to the application server. 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 with server-handle.Note: It is an error to specify TRANSACTION DISTINCT with a session-handle.
- ASYNCHRONOUS [ SET async-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 in
async-request-handle, which must be
a field, variable, or parameter defined with the HANDLE data type. If you
specify
ASYNCHRONOUSbut do not specifySETasync-request-handle, you can find the handle for the asynchronous request using theLAST-ASYNC-REQUESTattribute of the server-handle specified by theONoption. You can also locate the asynchronous request handle by walking the chain between theFIRST-ASYNC-REQUESTandLAST-ASYNC-REQUESTattributes of server-handle, searching on thePROCEDURE-NAMEattribute 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.
Note: You cannot use theASYNCHRONOUSoption with either theSINGLE-RUNorSINGLETONoption when instantiating an external procedure. However you can run an internal procedure of aSINGLETONprocedure asynchronously using the following syntax:RUNinternal_procedureINproc-handle. . . ASYNCHRONOUS. - EVENT-PROCEDURE event-internal-procedure
- 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-COMPLETEevent occurs), the specified internal procedure is called during subsequent execution of aPROCESS EVENTSor input-blocking statement (such asWAIT-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 thePROCEDURE-COMPLETEevent 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 theNO-ERRORoption.Note: TheEVENT-PROCEDUREandINkeyword syntax are now replaced by theEVENT-HANDLERand theEVENT-HANDLER-CONTEXTkeywords. Progress recommends that you use the new syntax that supports both procedures and methods as callback forASYNCHRONOUS RUN.. - IN procedure-context
- A handle to an active procedure that contains the internal
procedure specified by event-internal-procedure. If not specified,
THIS-PROCEDUREis used as the procedure-context value.Note: TheEVENT-PROCEDUREandINkeyword syntax are now replaced by theEVENT-HANDLERand theEVENT-HANDLER-CONTEXTkeywords. Progress recommends that you use the new syntax that supports both procedures and methods as callback forASYNCHRONOUS RUN. - EVENT-HANDLER event-handler-name
- A character expression that results in the name of an
internal procedure or a method that is specified as a callback handler. When
the response from the asynchronous request is received (that is, a
PROCEDURE-COMPLETEevent occurs), the specified event-handler-name (procedure or method) is called during subsequent execution ofPROCESS EVENTSor input-blocking statement (such asWAIT-FOR). The specified event handler procedure or method processes any parameters and errors returned from the asynchronous request. If not specified, no event procedure or method is executed when thePROCEDURE-COMPLETEevent occurs for the asynchronous request. For information on how the event procedure or method handles parameters from the asynchronous request, see the parameter option. For information on how the event handler (procedure or method) handles errors from the asynchronous request, see theNO-ERRORoption.When using a method as a callback handler, you can overload the method and the AVM will identify the most appropriate method to run by using the the signature of the method. The signature of the method is determined based on the output and input-output parameters passed to the asynchronous procedure executed by the
RUNstatement. - EVENT-HANDLER-CONTEXT event-handler-context
-
The event-handler-context value resolves to either a handle to an active procedure or the object-oriented ABL object containing the method specified by event-handler-name.
- If the value of event-handler-context is an object-oriented ABL object, then the event-handler-name specified must be a public method.
- The value of event-handler-context may optionally be
THIS-PROCEDUREwhen theRUNstatement is invoked from within a runnable block of a procedure. - The value of event-handler-context may optionally be
THIS-OBJECTwhen theRUNstatement is invoked from within a runnable block of an object-oriented ABL object.
(parameterparameter ][,...)- Specifies one or more parameters to pass to the called
procedure or method.
For the parameter passing syntax, see the Parameter passing syntax reference entry.
Parameters must be defined in the called procedure or method. (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 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 or method using a local field, variable, TABLE temp-table-name, TABLE-HANDLE temp-table-handle, DATASET dataset-name, or DATASET-HANDLE dataset-handle. However, note that the asynchronous remote procedure or method 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-handler-name procedure or method.
Any specified event-handler-name procedure or method 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 INPUT parameter for the event-handler-name procedure or method, must match the corresponding remote procedure OUTPUT or INPUT-OUTPUT parameter in order and data type. (As with other procedures or methods, 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-handler-name procedure or method after the remote procedure completes execution and the client session processes the associated PROCEDURE-COMPLETE event.
If you are running a event-handler-name procedure or method declared as a Windows dynamic link library (DLL) or UNIX shared library routine, you must match any RETURN parameter specified by a
DEFINE PARAMETERstatement 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 theRUNstatement.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
- The NO-ERROR option is used to prevent the statement from raising
ERRORand displaying error messages. This does not mean that all errors produced by the called procedure are suppressed; only errors caused by theRUNstatement itself.If a specified local or synchronous remote procedure throws an error back to the
RUNstatement, you can check theERROR-STATUSsystem handle for information on 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
ERRORcondition on theRUNstatement in the client which will be handled by theNO-ERRORoption. If the errors occur during execution of the remote request and are returned by the application server, theRUNstatement completes successfully and you must check forERRORorSTOPconditions in the specified event-handler-name (procedure or method) for thePROCEDURE-COMPLETEevent. In the event handler, you check the attributes of the async-request-handle.If the specified procedure is not found or if an attempted compile of the same fails, the AVM raises the
STOPcondition (for local procedures) orERRORcondition (for remote procedures). So only in the remote case canNO-ERRORbe used to handle these conditions. - 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
RUNstatement that calls it unless you specify theINproc-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 theINproc-handle option to identify the remote persistent, single-run, or singleton procedure that defines the internal procedure on an application server.If an internal procedure or user-defined function is run using the proc-handle associated with a single-run procedure, the application server session or client:
- Instantiates the single-run procedure.
- Runs the main block.
- Runs the internal procedure or user-defined function.
- Returns any output parameters or return values to the caller.
- Deletes the single-run procedure.
If an internal procedure or user-defined function is run using the proc-handle associated with a singleton procedure, the application server session or client:
- Instantiates the singleton procedure if it is not already instantiated by a previous client singleton request.
- Runs the main block.
- Runs the internal procedure or user-defined function.
- Returns any output parameters or return values to the caller.
- The singleton procedure remains instantiated.
Note: For more information on running remote user-defined functions, see the FUNCTION statement section. - VALUE ( intern-expression )
-
An expression that evaluates to the name of the internal procedure you want to run.
- IN proc-handle
-
Specifies the handle of the external procedure that declares the internal procedure you want to run. You can specify proc-handle as a field, variable, parameter, or expression that specifies a valid procedure handle or proxy (remote) persistent procedure handle.
- portTypeName
-
The name of a Web service PortType as specified in the WSDL file.
- hPortType
-
A handle to a procedure object that encapsulates a Web service operation.
- hWebService
-
A handle to the server object bound to the Web service.
- operationName
-
The name of a Web service operation specified in a WSDL file.
Examples
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".
r-run.p
|
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.
r-runper.p
|
r-perprc.p
|
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.
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 run runReport.p on an application server, 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 application
server.
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 bold ABL statements indicate the code required to
support asynchronous requests to run runReport.p.)
|
This example shows an asynchronous call that potentially returns an
error object through the ERROR-OBJECT attribute of
the Asynchronous request object handle. When server-error.p completes, procDone checks the value of ERROR, and if true, it assigns the instance
referenced by ERROR-OBJECT to myAppErrorObj via a cast and then displays the
information available, including the attributes inherited from Progress.Lang.Error and an ErrorCode attribute from the user-defined UserDefinedAppError class.
r-client-async-error.p
|
The example r-singlerun.p illustrates how to run any internal procedure in aproc.p as a single-run. The application server does not become bound to the client and network traffic is minimized when you run a procedure as single-run.
When the client executes the RUN aproc.p
statement, a proxy handle to the single-run procedure on the application
server is set without sending a message to the application server. When the client
sends the request to run internalProcA, the
application server runs the main block of aproc.p
and then runs the internal procedure internalProcA. After internalProcA
completes and ends, the application server deletes the single-run
procedure. The final line deletes the proxy handle on the client without sending a
message to the application server.
r-singlerun.p
|
Compare r-singlerun.p with
r-singleton.p. In both cases, the
application server does not become bound to the client and network traffic is
minimized. However, after internalProcA runs in
r-singleton.p, the singleton procedure
aproc.p is not deleted. It remains
instantiated and is available when the call is made to run internalProcB.
r-singleton.p
|
Notes
- When you run a procedure and do not indicate that the procedure
is external, the AVM first looks for an internal procedure with the specified
name. You indicate that a procedure is external in a
RUNstatement by specifying one or more of these options: path-name<<member-name>>,PERSISTENT,ON SERVER,SINGLE-RUN,SINGLETON. If no internal procedure is found, or if you indicated the procedure is external, the AVM (local or remote) searches all the directories and libraries in its PROPATH for a usable r-code file of the same name. If the AVM cannot find an r-code file and there is a source code file of the same name, the AVM attempts to compile and run the source code file. Note that all searches for procedure names are not case sensitive. - ABL procedures can be run recursively (a procedure can run itself).
- When a
RUNstatement raises theSTOPcondition, the AVM displays the resulting messages on the current output device, even if you specifyNO-ERROR. The AVM also writes these messages to theERROR-STATUSsystem handle, but setsERROR-STATUS:ERRORto FALSE. - You can run an internal procedure that is declared in the
current external procedure or in the procedure you specify with the
INproc-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 theTHIS-PROCEDUREsystem handle. You can check the validity of any procedure handle using theVALID-HANDLEfunction. - 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
WHEREorWITHclause, 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:
RUN /usr/foo/app.pl<<appmenu.r>>. - When running an external procedure, it is good practice to
specify the name of the source file in the
RUNstatement. For example, to run r-exit.p you specify the following:RUN r-exit.pWhen 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
PROPATHfor 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 firstPROPATHdirectory, then the AVM searches for an r-code file and then a source file in each subsequent directory on yourPROPATHuntil a file is found.If you specify the .r suffix in the
RUNstatement, 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,SINGLE-RUN, orSINGLETONoptions. - If you run a persistent, single-run, or singleton procedure and
a
STOP,QUIT, or aRETURN ERRORoccurs during execution of the procedure, the procedure is deleted. - 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 persistent, single-run, or singleton procedure
in which you have defined shared streams or shared frame, browse, or menu
widgets. Doing so causes the AVM to raise
ERRORon theRUNstatement. - You can remove an instance of a persistent or single-run
procedure that you run using the
PERSISTENToption using theDELETE PROCEDUREorDELETE OBJECTstatement. 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
PROCEDUREstatement and define its parameters in the associated internal procedure block. For more information on accessing DLL routines from ABL, see OpenEdge Programming Interfaces. - To run a UNIX shared library routine as an internal procedure,
you must reference the UNIX shared library in a
PROCEDUREstatement 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:RUN atoi (INPUT in-string, OUTPUT out-int). - 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:
DEFINE VARIABLE phand AS HANDLE NO-UNDO. RUN persproc.p PERSISTENT SET phand. . . . APPLY "RETURN" TO phand.This code fragment assumes that a trigger is defined within persproc.p for the RETURN event on the
THIS-PROCEDUREhandle. -
If you are using ABL with a DataServer that supports stored procedures, the
RUNstatement has extensions that allow you to execute a stored procedure. For more information, see the entry for theRUN STORED-PROCEDUREstatement and the appropriate OpenEdge DataServer Guides (Use the Microsoft SQL Data Server and Use the Oracle Data Server). - If you
RUNa 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
ASYNCHRONOUSoption) causes theRUNstatement 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
STOPorERRORcondition, the AVM:- Increments the
server-handle:ASYNC-REQUEST-COUNTattribute - Increments the
proc-handle:ASYNC-REQUEST-COUNTattribute, ifPERSISTENTis specified for a remote external procedure orINproc-handleis specified for a remote internal procedure - Sets the
async-request-handle:COMPLETEattribute to FALSE, indicating that the request has not completed execution - Sets the
async-request-handle:EVENT-PROCEDUREattribute to the value ofevent-internal-procedure, ifevent-internal-procedureis specified - Sets the
async-request-handle:EVENT-PROCEDURE-CONTEXTattribute to the value ofprocedure-context, ifprocedure-contextis specified - Submits the request for execution by the application server
- Increments the
- An asynchronous call to a remote procedure can return a
class-based error object. The object is returned via the
ERROR-OBJECTattribute on the Asynchronous request object handle. - The AVM checks the syntax of the
ON SERVERoption 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 currentSESSIONhandle. Thus, you can use the sameRUNstatement to execute a procedure remotely in an application server or locally depending on application conditions. - When you specify the
ON SERVERoption with theSESSIONsystem handle, theRUNstatement is functionally similar to not specifying theON SERVERoption at all. That is, the twoRUNstatements in the following code perform the same function:DEFINE VARIABLE hServer AS HANDLE NO-UNDO. hServer = SESSION. RUN foo.p. RUN foo.p ON SERVER hServer.Allowing the same
ON SERVERoption to specify either a local session or a remote application server session facilitates code generation for applications like the OpenEdge AppBuilder.With the
ASYNCHRONOUSoption, using theON SERVER SESSIONoption causes the called procedure to run synchronously in the local session, followed immediately by execution of any specified event-handler-name. Only after execution of the specified event-handler-name does control return to the statement following theRUNstatement. This synchronous local execution includes the following differences in error handling from asynchronous execution on an application server usingON SERVERserver-handle:- If an unhandled
ERRORcondition occurs during execution of the called local procedure or method, the error message is displayed on the local output device. This is different from remote execution, where any error message is written to the application server log file. - If the called local procedure or method causes an
ERRORorSTOPcondition to be raised in the calling procedure (a file not found, mismatched parameters, a compile error, and explicit execution of aRETURN ERRORorSTOPstatement), the AVM sends the associated message to the standard output device and setsERROR-STATUS:ERRORappropriately. This is different from remote execution, where the AVM in most cases attaches the associated message to theERROR-STATUSsystem handle. - Also, if the called local procedure or method causes
an
ERRORorSTOPcondition to be raised in the calling procedure (as in the previous note), the AVM raises the condition on theRUNstatement, as for a localRUNstatement without theON SERVERoption. This is different from remote execution, where the AVM does not raise the condition on the callingRUNstatement. You can work around this for theON SERVER SESSIONcase by coding each asynchronousRUNstatement with theNO-ERRORoption and possibly surrounding it with aDO ON STOP UNDO, LEAVEblock.
- If an unhandled
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, DELETE OBJECT statement, ERROR-OBJECT attribute, ON statement, Parameter passing syntax, PROCEDURE statement, Procedure object handle, RUN STORED-PROCEDURE statement, THIS-PROCEDURE system handle, VALID-HANDLE function, Widget phrase