DEFINE PARAMETER statement
- Last Updated: February 11, 2026
- 18 minute read
- OpenEdge
- Version 13.0
- Documentation
Defines a run-time parameter in an ABL procedure (internal or external), Windows dynamic link library (DLL) routine, UNIX shared library routine, or ActiveX control event procedure.
Each parameter requires its own DEFINE statement. The parameters must be specified in the RUN statement in the same order they are defined with DEFINE statements. In addition, the parameter types (INPUT, OUTPUT, INPUT-OUTPUT, RETURN, TABLE, TABLE-HANDLE, DATASET, DATASET-HANDLE, and BUFFER) specified in the DEFINE and RUN statements must agree. The corresponding data types and run-time values must also be compatible enough to allow the AVM to perform any necessary conversions.
Syntax
|
|
|
- INPUT PARAMETER
- Defines a parameter that gets its value from one of the
following sources:
- If the calling procedure runs the current (called) procedure synchronously, the value comes from the corresponding INPUT parameter of the RUN statement.
- If the current procedure or method is specified to handle the PROCEDURE-COMPLETE callback event for an asynchronous remote procedure, the value comes from the corresponding OUTPUT or INPUT-OUTPUT parameter of the remote procedure.
- OUTPUT PARAMETER
- Defines a parameter that returns a value to one of the
following destinations:
- If the calling procedure runs the current (called) procedure synchronously, the value is returned to the corresponding OUTPUT parameter of the RUN statement in the calling procedure.
- If the calling procedure runs the current (called) procedure as an asynchronous remote procedure, the value is returned to the corresponding INPUT parameter of the event procedure or method specified to handle the PROCEDURE COMPLETE event for the current procedure.
- INPUT-OUTPUT PARAMETER
- Defines a parameter that receives an initial value passed
from the calling procedure that can be subsequently modified by the called
procedure. The calling procedure cannot pass a literal value. The called
procedure returns the modified value to one of the following destinations:
- If the calling procedure runs the current (called) procedure synchronously, the value is returned to the corresponding INPUT-OUTPUT parameter of the RUN statement in the calling procedure.
- If the calling procedure runs the current (called) procedure as an asynchronous remote procedure, the value is returned to the corresponding INPUT parameter of the event procedure or method specified to handle the PROCEDURE COMPLETE event for the current procedure.
- RETURN PARAMETER
- Defines a parameter that holds the return value of a DLL or UNIX shared library routine. When the DLL routine returns, the value of this parameter is passed back to the calling procedure. You can only have one RETURN parameter per routine.
- parameter
- Identifies the name of the parameter you want to define.
- AS [ HANDLE TO ]primitive-type-name
- Specifies a primitive type for the parameter.
For ABL procedures, primitive-type-name can specify any built-in primitive type used to define variables. For more information on the available primitive types, see the Data types reference entry. For more information on defining primitive type variables, see the DEFINE VARIABLE statement reference entry.
For DLL or UNIX shared library routines, primitive-type-name can specify an ABL DLL data type. ABL DLL data types include the built-in ABL data types CHARACTER and MEMPTR, Windows DLL-equivalent data types, and UNIX shared library data types.
The following table shows how Windows DLL and UNIX shared library data types map to ABL DLL data types.
Table 1. Data types for DLL and UNIX shared library routine parameters Example C data type ABL DLL parameter data type Windows DLL and UNIX shared library data type charBYTE8-bit unsigned integer shortSHORT16-bit signed integer unsigned shortintUNSIGNED-SHORT16-bit unsigned integer long(32-bit UNIX, Win32)int1LONG232-bit signed integer unsigned intUNSIGNED-LONG32-bit unsigned integer __int64(Win32)long long(UNIX 32-bit)long(UNIX 64-bit)INT6464-bit signed integer floatFLOAT4-byte floating point doubleDOUBLE8-byte floating point char*CHARACTERAddress (usually 32 bits) c-data-type3 HANDLE TOparameter-data-type3
Address (usually 32 bits) char*, output-pointer (which can bechar**,short**, and so on), or a pointer to a structure.MEMPTRAddress (usually 32 bits) CAUTION: For CHARACTER parameters, the AVM always passes the routine a pointer to the character or character string value rather than the value itself. If the routine modifies the value, it can also modify the AVM memory outside the bounds of the CHARACTER value with unpredictable results. For this reason, ABL does not allow you to use OUTPUT or RETURN for CHARACTER or LONGCHAR parameters, as well as CHARACTER or LONGCHAR array parameters, and does not recommend you use INPUT-OUTPUT for CHARACTER or LONGCHAR parameters. Rather, pass the character string as a MEMPTR parameter. For more information, see OpenEdge Programming Interfaces.Note: You cannot useRETURNfor any type of array parameter.To indicate that the DLL or UNIX shared library parameter is a pointer to a value rather than the value itself, use the HANDLE TO option. The HANDLE TO option is required when the DLL routine expects a pointer to the value. Note that the CHARACTER data type implies the HANDLE TO option, whether or not you specify it.
For ActiveX control event procedures, primitive-type-name can specify the built-in ABL data type that maps to the COM object data type of an ActiveX event parameter. The following table shows how the COM object data types for event parameters (shown as ActiveX data types) map to ABL data types.
Table 2. Data types for ActiveX control event procedures ActiveX data type4 ABL data type Array ABL array variable Array of bytes RAW Boolean (2-byte integer) LOGICAL Currency (8-byte integer with fixed decimal point) DECIMAL Date DATE DATETIME
DATETIME-TZ
Decimal DECIMAL Double (8-byte floating point) DECIMAL Error Code INTEGER Float (Single) DECIMAL Integer (2-byte integer) INTEGER Long (4-byte integer) INTEGER Object (32-bit value) COM-HANDLE String (character string type) CHARACTER LONGCHAR
Signed Byte INTEGER Signed Long (4-byte integer) INTEGER Signed Short (2-byte integer) INTEGER Signed 8-byte integer INT64 Unsigned Byte INTEGER Unsigned Long (4-byte integer) INT64 Unsigned Short (2-byte integer) INTEGER Unsigned 4-byte integer INT64 Unsigned 8-byte integer DECIMAL Variant (variable type) <ANYTYPE>5 - AS [ CLASS ]{object-type-name}
- Defines the parameter as an object reference with the data
type of a class or interface. The default value of the parameter is the
Unknown value (
?). You cannot assign an initial value using the INITIAL option. - object-type-name
- Specifies the type name of an ABL or .NET class or
interface. Specify an object type name using the syntax described in the
Type-name syntax
reference entry. With an appropriate USING statement, you can also specify a
class or interface name alone, without the qualifying package or
namespace.
You cannot directly specify the type name of a .NET mapped object type (such as System.Int32). To define a parameter that matches a .NET mapped type, you must define it as the corresponding ABL primitive type (primitive-type-name).
- CLASS
- If the specified class or interface type name conflicts
with an abbreviation for a built-in primitive type name, such as INT for
INTEGER, you must specify the CLASS keyword.
For a class or interface return value, ABL passes an object reference associated with the class or interface, not a class instance itself. For more information on object references, see the Class-based object reference reference entry.
- LIKE, CASE SENSITIVE, FORMAT, DECIMALS, INITIAL, COLUMN-LABEL, LABEL, NO-UNDO
- For descriptions of these options, see the DEFINE VARIABLE statement reference entry.
- EXTENT [constant ]
- Defines the parameter as an array of data elements, where
the element data type is specified by the AS primitive-type-name option, the LIKE field option, or the AS object-type-name option. This option can
specify an array parameter as either determinate (has a defined number of
elements) or indeterminate (has an undefined number of elements). To define
a determinate array parameter, specify the EXTENT option with the constant argument. This optional argument is
an integer value that represents the number of data elements in the array
parameter. To define an indeterminate array parameter, specify the EXTENT
option without the constant argument.
The EXTENT is part of the parameter data type. For more information, see the Type-name syntax reference entry.
For more information about arrays, see Work with one-dimensional arrays in Basic ABL.
You cannot pass an indeterminate array with no size to a COM object, DLL routine, or UNIX shared library routine.
If you want to define a parameter that is like an array variable or field, using the LIKE option, but if you do not want the parameter to be an array, you can use EXTENT 0 to indicate a non-array parameter.
If you are using the AS option and you do not use the EXTENT option (or you specify constant as 0), the parameter is not an array parameter. If you are using the LIKE field option and you do not use the EXTENT option, the parameter uses the extent defined for the database field you name (if any).
- PARAMETER BUFFER buffer-name FOR [TEMP-TABLE]table-name[PRESELECT]
- Defines a buffer parameter, where buffer-name is the name you specify for the buffer and
table-name is the name of a
temp-table or database table to which the buffer is attached. You can pass a
buffer associated with a database table to a buffer parameter. You cannot
pass a work table to a buffer parameter. A buffer parameter is always
INPUT-OUTPUT. You cannot pass buffer parameters to the application server.
Use the TEMP-TABLE option to define a buffer parameter for a temp-table when the temp-table has the same name as a database table. Otherwise, ABL associates the buffer with the database table by default. Note that you can define a temp-table buffer parameter only for an internal procedure that you define in an external procedure where the temp-table specified by table-name is already defined.
If you use the PRESELECT option and access the buffer parameter in a DO or REPEAT block, the AVM creates an internal list of the records selected. The PRESELECT option tells the AVM to apply that internal list to the buffer you define.
Note: Buffer parameters are intended for database tables and only allow you to view an individual buffer for a temp-table. Use aTABLE BY-REFERENCEparameter if you need more functionality. - TABLE FOR temp-table-name
- Defines a temp-table parameter.
You can pass a temp-table parameter to both local and remote procedures. The AVM passes the parameter by value, by default. That is, the caller and the called routine each have their own instance of the temp-table. When you invoke the RUN statement, the AVM deep-copies the parameter from one instance to the other. The table that is copied depends on whether the parameter is INPUT, OUTPUT, or INPUT-OUTPUT. When you pass a temp-table as an INPUT parameter, the AVM replaces the receiving instance with the source instance, by default. You can also append the copied instance to the end of the receiving instance by specifying the APPEND option. For more information about the APPEND option, see the option description later in this reference entry.
When passing a temp-table parameter to a local procedure, you can override the default deep copy and pass the parameter by reference or by binding (that is, by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option). Passing a temp-table parameter by reference or by binding allows the caller and the called routine to access the same object instance (instead of deep-copying the parameter).
Note: When you specify the BIND option in the DEFINE PARAMETER statement, you must also specify the BIND option in the RUN statement.For more information about passing a temp-table parameter by reference or by binding, see the Parameter passing syntax reference entry. For more information about temp-table parameters, see Develop ABL Applications.
- TABLE-HANDLE temp-table-handle
- Defines a temp-table handle parameter.
- DATASET dataset-name
- Defines a compile-time defined ProDataSet object
parameter.
You can pass a ProDataSet object parameter to both local and remote procedures. The AVM passes the parameter by value, by default. That is, the caller and the called routine each have their own instance of the object. When you invoke the RUN statement, the AVM deep-copies the parameter from one instance to the other. The ProDataSet that is copied depends on whether the parameter is INPUT, OUTPUT, or INPUT-OUTPUT. When you pass a ProDataSet as an INPUT parameter, the AVM replaces the receiving instance with the source instance, by default. You can also append the copied instance to the end of the receiving instance by specifying the APPEND option. For more information about the APPEND option, see the option description later in this reference entry.
When passing a ProDataSet object parameter to a local procedure, you can override the default deep copy and pass the parameter by reference or by binding (that is, by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option). Passing a ProDataSet object parameter by reference or by binding allows the caller and the called routine to access the same object instance (instead of deep-copying the parameter).
Note: When you specify the BIND option in the DEFINE PARAMETER statement, you must also specify the BIND option in the RUN statement.For more information about passing a ProDataSet object parameter by reference or by binding, see the Parameter passing syntax reference entry. For more information on ProDataSet object parameters, see Use ProDataSets.
- DATASET-HANDLE dataset-handle
- Defines a ProDataSet object handle parameter.
- APPEND
- Specifies whether or not to append the data from a source instance to the receiving instance of a passed temp-table or ProDataSet parameter. To append input parameter data, specify the APPEND option in the DEFINE PARAMETER statement. To append output parameter data, specify the APPEND option in the RUN statement.
- BIND
- Indicates that a TABLE, TABLE-HANDLE, DATASET, or
DATASET-HANDLE parameter binds a reference-only object in one routine to an
object instance defined and instantiated in another local routine.
When you define a reference-only object in the calling routine, and you want to bind that object definition to an object instance in the called routine, define the parameter by specifying the BIND option in an INPUT or INPUT-OUTPUT parameter definition. When you define a reference-only object in the called routine, and you want to bind that object definition to an object instance in the calling routine, define the parameter by specifying the BIND option in an OUTPUT parameter definition. In either case, the reference-only object definition remains bound to the object instance until the routine containing the reference-only object definition is deleted or terminates.
CAUTION: Do not delete the object or routine to which a reference-only object is bound, or you might be left with references to an object that no longer exists.You can bind multiple reference-only object definitions to the same object instance. You can also bind a single reference-only object definition to the same object instance multiple times without generating an error. However, you cannot bind a single reference-only object definition to multiple object instances.
When passing one of these parameters to a remote procedure, the AVM ignores the BIND option and deep-copies the parameter based on the specified parameter mode.
For more information about passing these parameters by binding, see the Parameter passing syntax reference entry.
- BY-VALUE
- Specified for an INPUT, OUTPUT, or INPUT-OUTPUT TABLE, TABLE-HANDLE, DATASET, or DATASET-HANDLE parameter in a called routine, this option forces the parameter to be passed to the local routine by value, which overrides any BY-REFERENCE option in the corresponding routine invocation. For more information on BY-REFERENCE, see the Parameter passing syntax reference entry.
Examples
In the following examples, the r-runpar.p procedure runs a subprocedure called r-param.p and passes the subprocedure an INPUT parameter. The subprocedure r-param.p displays the INPUT parameter.
r-runpar.p
|
r-param.p
|
In the following example, the r-runpr1.p procedure runs a subprocedure called r-param1.p. This example illustrates the use of multiple parameters and shows that the parameters must be passed in the proper order and must be of the same data type. Note that if you do not specify a parameter type in the RUN statement, the AVM assumes it is an input parameter.
r-runpr1.p
|
r-param1.p
|
In the following example, the r-runpr2.p procedure displays information from a database table and assigns the value of a database field to a variable called io-param. The variable is passed as an INPUT-OUTPUT parameter to a subprocedure called r-param2.p. The subprocedure r-param2.p performs a calculation on the INPUT-OUTPUT parameter, then passes it back to the main procedure. The r-runpr2.p assigns the value io-param to a database field, then displays io-param.
r-runpr2.p
|
r-param2.p
|
The following example uses a buffer parameter. The procedure
r-bufp.p passes the Customer buffer to the
getCustomer internal procedure, which attempts
to find a record using that buffer.
r-bufp.p
|
The following example defines parameters for the DLL routine, MessageBox, which displays a message on the screen:
r-dllex1.p
|
Notes
- All procedure parameters are normally passed by value, by
default. This means that for any INPUT-OUTPUT or OUTPUT parameter, the field or
variable that receives the output value is not set by the called procedure until
the procedure returns without error. An exception is made for local DATASET,
DATASET-HANDLE, TABLE, and TABLE-HANDLE parameters, which you may pass by
reference or by binding by specifying the parameter in a RUN statement using
either the BY-REFERENCE or BIND option. If you specify the BIND option in the
RUN statement, you must also specify the BIND option in the DEFINE PARAMETER
statement.
For more information about passing parameters by reference or by binding, see the Parameter passing syntax reference entry.
- You cannot pass a BLOB or CLOB field as a parameter. To pass a BLOB or CLOB field as a parameter, you must include the field in a temp-table or convert the field to its MEMPTR or LONGCHAR counterpart, respectively.
- Buffer parameters are scoped in the same way as shared buffers. They also affect cursors defined in the calling procedure in the same way as shared buffers.
- For DLL or UNIX shared library routine declarations:
- The LIKE field option can only specify a database field of type CHARACTER or a variable of type CHARACTER or MEMPTR.
- The COLUMN, COLUMN-LABEL, DECIMALS, INITIAL, FORMAT, LABEL, and NO-UNDO options have no effect.
- You cannot pass a DATE, DATETIME, or DATETIME-TZ as a parameter to or from a DLL routine or a UNIX shared library routine.
- You can pass a LONGCHAR as a parameter to a DLL routine or a UNIX shared library routine. When passing a LONGCHAR parameter, the AVM passes only the text string (not the code page information). You are responsible for setting the code page of a LONGCHAR parameter.
- You can pass an array of type INTEGER, INT64, or DECIMAL as a parameter to or from a DLL routine or a UNIX shared library routine. You can pass an array of type CHARACTER to (not from) a DLL routine or a UNIX shared library routine.
- You cannot pass a variable or array that contains the Unknown
value (
?) to a DLL. - RETURN parameters are supported only for DLL or UNIX shared library routines. The RETURN parameter type must match the OUTPUT parameter that returns the DLL function value in the RUN statement for the routine. You cannot pass an array as a RETURN parameter to DLL or UNIX shared library routines. Use a MEMPTR instead.
- If you specify a RETURN parameter as MEMPTR to return a character string, use the GET-STRING function to extract the CHARACTER value.
- For more information on DLL routine parameters and how they map to ABL data types, see the topics on DLLs in OpenEdge Programming Interfaces.
- You cannot pass a MEMPTR as a parameter to or from a COM object.
- You can pass a LONGCHAR, a DATETIME, a DATETIME-TZ, and an
array as a parameter to or from a COM object.
When passing a LONGCHAR parameter to a COM object, the AVM passes only the text string (not the code page information). When receiving a text string from a COM object into a LONGCHAR parameter, the AVM converts the text string to the code page associated with the LONGCHAR parameter only if the LONGCHAR has a fixed code page. Otherwise, the AVM sets the LONGCHAR code page to UTF-16. If the AVM cannot convert a LONGCHAR, it raises a run-time error.
When passing a DATETIME or DATETIME-TZ parameter to a COM object, the AVM represents the time to the millisecond. When passing a DATETIME-TZ parameter to a COM object, the AVM first converts the DATETIME-TZ value relative to the local session's date and time, and then drops the time zone.
When receiving a date from a COM object into a DATETIME or DATETIME-TZ parameter, the AVM represents the time to the millisecond. When receiving a date from a COM object into a DATETIME-TZ parameter, the AVM sets the time zone to the local session's time zone.
- For more information on ActiveX event parameters, or using COM objects, see OpenEdge Programming Interfaces.
- When passing temp-table or ProDataSet parameters, the caller and callee parameters must be compatible. Compatible temp-tables must have the same number of fields, with each field matching in data type, extent, and position, but not in field name or any other field attribute. The temp-tables must have the same number of indexes, with index components matching in every way (except in field name), and the index names must also match. The temp-table names do not have to match. Compatible ProDataSets must have the same number of member buffers, in the same order, and the tables of those buffers must match in the same way as compatible temp-tables. Names of either the ProDataSet or its buffers do not have to match.
- For dynamic temp-table parameters:
- If the parameter is INPUT TABLE-HANDLE, the temp-table definition behind the handle plus the temp-table contents are sent from the caller to the called routine. The called routine may have either the dynamic INPUT TABLE-HANDLE or the compile-time defined INPUT TABLE as a matching parameter.
- When running remotely with the application server, if the parameter is INPUT TABLE-HANDLE, a new instance of the temp-table is created along with its handle, completely separate from the caller's table, and is populated with the contents from the caller's table.
-
You can override this default behavior to allow the calling procedure and the called procedure to access the same object instance by passing the TABLE-HANDLE parameter by reference or by binding (that is, by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option). If you specify the BIND option in the RUN statement, you must also specify the BIND option in the DEFINE PARAMETER statement.
- The OUTPUT TABLE-HANDLE parameter, just like any other OUTPUT variable, cannot change the data in the caller procedure: in this case, the definition of the temp-table).
- If the parameter is OUTPUT TABLE-HANDLE, the called
routine sends back the definition behind the handle along with the
contents of the output temp-table. In the caller, if the original handle
was the Unknown value (
?), a new instance of the temp-table is created and populated with the output contents. The temp-table object is created in the default widget-pool of the caller's OpenEdge session. To avoid memory leaks, the temp-table object must be manually destroyed. For more information on deleting objects, see the reference entry for the DELETE OBJECT statement. -
If the original handle is not the Unknown value (
?), the caller's existing table must match the table being received from the called routine. - If the APPEND option is used, the new data is added to the existing table's data.
- If the parameter is INPUT-OUTPUT TABLE-HANDLE, a combination of the above occurs.
- If you call a remote procedure asynchronously (using the ASYNCHRONOUS option of the RUN statement) and pass a parameter as OUTPUT TABLE-HANDLE temp-table-handle APPEND, the event procedure or method must specify a corresponding DEFINE INPUT PARAMETER TABLE-HANDLE FOR temp-table-handle APPEND statement, and temp-table-handle must be global to both the calling procedure and the event procedure or method.
- If you define an INPUT TABLE parameter for an asynchronous event procedure with a data type that is different from the data type of the corresponding OUTPUT TABLE parameter passed from the application server, any failure to convert the passed value causes the event procedure or method to fail and the AVM to display an error message on the client.
- The AVM creates the temp-table object for an OUTPUT TABLE-HANDLE parameter in the session's default widget pool. Remember to delete this object at the appropriate point to avoid memory leaks.
- You cannot specify a ProDataSet object or ProDataSet object handle as a parameter for an asynchronous remote procedure.
- For dynamic ProDataSet object parameters:
- If the parameter is INPUT DATASET-HANDLE, the ProDataSet object definition behind the handle plus the ProDataSet object contents are sent from the caller to the called routine. The called routine may have either the dynamic INPUT DATASET-HANDLE or the compile-time defined INPUT DATASET as a matching parameter.
- If the parameter is INPUT DATASET-HANDLE, a new instance of the ProDataSet object is created along with its handle, completely separate from the caller's table, and is populated with the contents from the caller's table.
-
You can override this default behavior to allow the calling procedure and the called procedure to access the same object instance by passing the DATASET-HANDLE parameter by reference or by binding (that is, by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option). If you specify the BIND option in the RUN statement, you must also specify the BIND option in the DEFINE PARAMETER statement.
- If the parameter is OUTPUT DATASET-HANDLE, the handle plus the definition behind the handle are sent from the caller to the called routine. The called routine may have either the dynamic OUTPUT DATASET-HANDLE or the compile-time defined OUTPUT DATASET as a matching parameter.
-
If the parameter is OUTPUT DATASET-HANDLE, and the caller's handle is the Unknown value (
?), no definition is sent to the called routine. - If the parameter is OUTPUT DATASET-HANDLE, the called
routine sends back the definition behind the handle along with the
contents of the output ProDataSet object. In the caller, if the original
handle is the Unknown value (
?), a new instance of the ProDataSet object is created and populated with the output contents. If the original handle is not the Unknown value (?), the caller's existing object must match the object being received from the called routine. - If the APPEND option is used, the new data is added to the existing object's data.
- If the parameter is INPUT-OUTPUT DATASET-HANDLE, a combination of the above occurs.
- A BUFFER parameter cannot be a REFERENCE-ONLY buffer or a BEFORE-TABLE buffer. The use of them as a BUFFER type of parameter (as opposed to INPUT or OUTPUT) is a compiler error. Instead of passing the buffer, the buffer's table can be passed by-reference.
See also
DEFINE BUFFER statement, DEFINE VARIABLE statement, DELETE PROCEDURE statement, Parameter passing syntax, RUN statement, Type-name syntax, USING statement, VAR statement
int generally specifies a size that
depends on the operating system.null pointer value to a DLL
routine, pass 0 using a LONG parameter. Do not use a null MEMPTR
variable to pass a null value.
However, you can pass a null value in
one or more elements of a MEMPTR array. If this conflicts with another
way to call the DLL routine, specify a second declaration for the same
routine using the ORDINAL option of the PROCEDURE statement.char, short, unsigned, short, long, int, float, and double). For
a CHARACTER or MEMPTR parameter, it is redundant because this data type
is always passed using a pointer (char*).