Using the Callproc Statement
The callproc statement calls a procedure from a frame or 4GL procedure in an application. A procedure is a series of statements written in 4GL, Ingres SQL (called a database procedure), or a 3GL (also called host language). You can include procedures anywhere in your application that you would use a frame (including the start frame.) When you call the procedure, Ingres executes the commands it contains.
You can pass parameters (in the form of expressions) to the procedure. A parameter list can include any 4GL expressions. You can pass parameters to a procedure by reference if you use the reserved word byref in front of the parameter name. You must specify, in the parameter list of the called procedure, the names of the parameters to which the values of the expressions are to be assigned.
Ingres checks at run time that any field or column that you pass to a procedure has a data type that is compatible with the parameter in the procedure. See the section Callproc for a complete description of callproc syntax.
Calling 3GL Procedures
An application can call a procedure written in a 3GL. A 3GL is a programming language such as C. These procedures generally include embedded query language statements.
For example, this 4GL statement calls the procedure named compute:
callproc compute;
The procedure name compute must be declared to ABF or Vision and its source code file must have the correct file extension. You declare a procedure with the Create a Procedure frame for the procedure type.
Just as you can pass arguments to frames, you can pass them to procedures, but the syntax is slightly different. 4GL requires the following syntax for calling a procedure with arguments:
callproc procedurename (argument {; argument});
The called procedure must be written to accept arguments in the same order in which the application passes them.
Parameters to 3GL procedures must be simple fields, simple variables, individual array attributes, record attributes, or table field cells; you can not pass records and arrays as parameters. Also, you cannot pass more than 40 parameters to a 3GL procedure.
Calling 4GL Procedures
An application also can call a procedure written in 4GL. This feature can help minimize the number of statements in your application in cases in which several frames or operations must perform an identical function. You can place the 4GL statements required to perform the common function into a 4GL procedure and call the procedure as required, with or without an argument list.
A 4GL procedure can be global or local to its source file. The following considerations apply:
• You must declare a global 4GL procedure on the ABF Create a Procedure frame, specifying the name of a source file that contains the procedure. The 4GL code that defines the procedure must appear at the beginning of the source file that you specify.
• A local 4GL procedure is a series of 4GL source statements that appear in the source file for a user-defined frame or a global procedure.
You only can call local 4GL procedures from the source file in which they appear. The ABF Frame Catalog has no record of local procedures.
The syntax for calling a 4GL procedure with arguments is similar, but not identical, to that used in calling a programming language procedure:
callproc procedurename (parameter = argument
{,parameter = argument});
The parameter is the name of the parameter in the called procedure to which the argument is being assigned. Its name must be the same as the name given it inside the procedure. Because of this restriction, you can pass the parameters in any order to the called procedure.
Every parameter when calling a 4GL procedure is not called. Any parameter in the called procedure that is not passed a value is given a default value according to its data type. However, any parameter specified in the callproc statement must exist as named in the called procedure. The parameter names are 4GL names.
The following simple example shows the basic pattern for writing 4GL procedures. Note that the data type of each argument must be declared in the procedure heading:
procedure addtax (tax=float4,cost=float8) =
begin
cost := cost + (cost * tax);
end
Call the procedure addtax with the following statement:
callproc addtax (cost = byref(costfield),
tax = taxpercent);
This statement illustrates some of the issues discussed above. First, note that the order in which the parameters are specified in the callproc statement is not the same as the order in which they appear in the procedure's heading. They are, however, identical in name to the parameters within the procedure. Second, the procedure call passes the form field costfield as a way of extracting a value from the procedure.
When the operation that calls the procedure is completed, costfield is updated to reflect its new value. If this is a displayed field, the new value for the field also appears on the form.
You can use the reserved word all in the parameter list to a 4GL procedure, as shown below:
callproc procname (calling_formname.all |
calling_tablefield_name[[integer_expr]].all)
This syntax maps the simple fields in the calling form (or columns in the named table field) to the parameter list inside the procedure. Any field or column that does not correspond to a parameter is ignored.
Local variables and hidden columns are not mapped. When all is used with a table-field name, values are taken from the row on which the cursor is currently resting. To override this, specify an integer expression enclosed by brackets following the table-field name. In this case values are taken from the row with that number.
Using a Procedure to Test Global Variables
In order for global variables in an application to work correctly, set the values of global variables before you execute any frames or procedures that use the variables.
You can create a procedure that uses an integer global variable in ABF to check whether another global variable in an application has been set and, if necessary, sets it. You can call this procedure from any frame that uses the second global variable.
The following example performs such a check and initialization:
if (G_init = 0) then
G_sess_info := select dba = dbmsinfo('dba'),username =
dbmsinfo('username');
G_init = 1;
endif ;
The example uses an integer variable G_init to check whether the global variable G_sess_info has been initialized. The first time you call the procedure, G_init has the initial 4GL default value of 0. This causes the if clause to be executed.
G_sess_info is a global variable of a record type that has two attributes, dba and username. The procedure uses the 4GL dbmsinfo function to retrieve the current values for the DBA and application user into the attributes of G_sess_info.
The procedure then sets the value of G_init to 1, so that the select is not executed again unnecessarily the next time the procedure is called.
Calling Database Procedures
Database (SQL) procedures are library procedures. Call these as you do any library procedure. The following example calls the database procedure addtax:
totcost = callproc addtax
(cost = costfield;
tax = taxpercent);
For more information on database procedures, see the SQL Reference Guide.
Calling Ingres Applications
A variant of the call statement allows the user to start up a second Ingres application on the currently executing DBMS connection. The syntax for calling an application is an instance of the syntax for calling any Ingres tool. There are two versions:
call application (name = filename, frame = framename)
call application (executable = filename, frame =
framename);
The value of filename can be either a full pathname or the name of a file in the current working directory. The filename and framename can be any expressions that evaluate to appropriate string constants.
The parameters executable and name are interchangeable.
VMS: The parameters executable and name have different syntax. The first syntax is:
call application (name = applicationname, frame = framename);
The applicationname is the name of an application in your current database, defined as a DCL command in your environment. The framename is the name of the first frame to be called in the application. These names can be any expressions that evaluate to appropriate string constants.
For example, the following statement starts up the application inventory beginning in the frame parts:
call application (name = 'inventory', frame = 'parts');
The second syntax is:
call application (executable = full_directory_specification,
frame = framename);
The parameter executable must have as its value the full directory specification of the application's executable file. The full_directory_specification and framename can be any expressions that evaluate to appropriate string constants.
This statement uses the executable parameter:
call application (executable =
'usr_disk:[devel.joe]myapp.exe',
frame = 'start');