Skip to main content

EXECUTE

Executes a MultiValue command from within a program, passing and returning values.

Synopsis

Use any of the following three syntactical forms:

EXECUTE command 
                   [CAPTURING {dynarray | NULL} |  OUTPUT oref]
                   [PASSLIST [dynarray]] 
                   [RTNLIST var] 
                   [{SETTING | RETURNING} dynarray]

EXECUTE command 
                   [ , IN < expression] 
                   [ , OUT > var]
                   [ , SELECT[ (list) ] < dynarray]
                   [ , SELECT[ (list) ] > var]
                   [ , PASSLIST[ (dynarray) ]]
                   [ , STATUS > var]

EXECUTE command 
                   [ ,//IN. < expression] 
                   [ ,//OUT. > var]
                   [ ,//SELECT.[ (list) ] < dynarray]
                   [ ,//SELECT.[ (list) ] > var]
                   [ ,//PASSLIST.[ (dynarray) ]]
                   [ ,//STATUS. > var]

Arguments

command One or more MultiValue commands, each command specified as a quoted string. A string can be quoted using single quotes ('cmd arg'), double quotes ("cmd arg"), or backslashes (\cmd arg\). To specify multiple commands, separate the commands with a Field Mark ("cmd1 arg":@FM:"cmd2 arg").
var A variable used to hold a value.
dynarray A dynamic array.
oref An object reference. The corresponding class must have (at minimum) a WriteLine() method (which inserts a newline at the end of the write operation) and a Write() method (which does not insert a newline).

Description

The EXECUTE command executes the specified Caché MultiValue command(s), then returns execution to the next MVBasic statement following the EXECUTE. It initially searches the VOC for the command; if the command is not found in the VOC, it searches the global catalog. For lookup details, refer to CATALOG in the Caché MultiValue Commands Reference.

The first syntactical form supports the following optional clauses:

  • The CAPTURING clause diverts all terminal output from the MultiValue command to the supplied dynarray variable. This output is stored as a dynamic array, with lines separated by Field Marks. If command executes successfully, the resulting terminal output is captured; if command fails, the error message is captured. CAPTURING NULL discards all terminal output, with the following exceptions: Output from the OUT statement is displayed. Output from non-MultiValue commands or shell commands cannot be captured, and is therefore displayed. If command includes the HUSH ON command, output is not stored in dynarray based on that command, and terminal display is disabled upon return from the EXECUTE command.

  • The OUTPUT clause diverts all terminal output from the MultiValue command to the supplied oref. (One use of this object is to invoke a class from which you can execute write methods to write to a sequential file.) This is especially useful when handling extremely large command outputs (>3.6 Mbytes). The following example:

    oref = "%Stream.FileCharacter"->%New()
    EXECUTE "LIST BIGFILE ID-SUPP A1" OUTPUT oref
    

    directs the output to the standard Caché %StreamOpens in a new tab class using the standard Write()Opens in a new tab and WriteLine()Opens in a new tab methods. An object derived from a user-written class can be used if it has both a Write() and WriteLine() method, as shown in the example below. A WriteLine() method ends by forcing a new line; a Write() method does not force a new line.

    If an error occurs, such as specifying a filevar that is not an existing sequential file, EXECUTE fails without displaying an error message. It is the programmer’s responsibility to check the @SYSTEM.RETURN.CODE for -1, indicating an error. If using a Unicode version of Caché, you must change the file translation in the locale. The OUTPUT clause and the CAPTURING clause are mutually exclusive.

  • The PASSLIST clause supplies the specified dynarray to the executed command as the current default external select list.

  • The RTNLIST clause receives the default select list (if any) produced by the executed command.

  • The RETURNING clause receives the ERRMSG error message string with which the command terminated. The format is a dynamic array containing the ERRMSG number followed by the parameters.

The second and third syntactical forms support the following optional clauses:

  • The IN clause specifies the input value for command.

  • The OUT clause assigns the output from command to var. The var variable must be simple variable name. It cannot include a system variable, an EQUATE, a dynamic array reference, or a substring reference.

  • The PASSLIST clause supplies the specified dynarray to the executed command as the current default external select list.

  • The STATUS clause var variable contains the execution status of the last executed list or select command. If the command completed successfully, var contains the number of items listed, selected, or otherwise processed. If the command failed, var contains -1. If the specified command name is not a valid command, var contains -1. Commands that do not list or select items do not set var; var is set to 0 regardless of whether the command succeeded or failed. var can be a simple variable, or a single dynamic array reference (A<i>), a single substring reference (A[s,l]), or a substring reference nested inside a dynamic array reference (A<i>[s,l]).

EXECUTE, PERFORM, and CHAIN

The EXECUTE command executes one or more MultiValue commands from within MVBasic, then returns execution to the next MVBasic statement. EXECUTE can pass values to the MultiValue command(s) and return values from the MultiValue command(s).

The PERFORM command executes one or more MultiValue commands from within MVBasic, then returns execution to the next MVBasic statement. PERFORM cannot pass or return values.

The CHAIN command executes a single MultiValue command from within MVBasic. It does not return execution to MVBasic. CHAIN cannot pass values.

Emulation

In Reality emulation, EXECUTE executes all stacked data, regardless of list status. In Caché and all other emulations, only the EXECUTE command argument is executed. For all emulations (except Reality) EXECUTE either clears or maintains stacked data on the DATA queue, depending on the STACK.GLOBAL option.

EXECUTE supports the STACK.GLOBAL option, which can be set using $OPTIONS. When STACK.GLOBAL is on, EXECUTE does not clear unused items from the DATA queue upon completion. By default, STACK.GLOBAL is on for Caché, and for UniVerse, UniData, PICK, Prime, PIOpen, and IN2 emulations. STACK.GLOBAL is off for all other emulations.

In jBASE emulation, the RTNLIST clause returns the select list expanded to a dynamic array. All other emulations return the select list name. The PASSLIST clause requires that the select list be designated as external. This external select list bit setting is only used for jBASE emulation.

EXECUTE supports the RETURNING.CODE option, which can be set using $OPTIONS.

In UniData and UDPICK emulations, a command name with an initial character of * is handled as a global name. EXECUTE removes the leading * and then looks up the resulting command name in the global catalog in SYS.MV, rather than looking up in the VOC. If the runtime environment is not a UniData emulation, a normal VOC lookup is done on the *command name.

Invoking Other Command Shells

You can use the $XECUTE command to issue an ObjectScript command from within Caché MVBasic.

You can use the PCPERFORM command to issue an operating system command from within Caché MVBasic.

Examples

The following example issues the MultiValue LISTME command, captures its output in the dynamic array variable currusers and then returns execution to the MVBasic program:

PRINT TIME()
EXECUTE "LISTME" CAPTURING currusers
PRINT TIME()
PRINT currusers

The following example shows how to use EXECUTE to execute multiple MultiValue commands:

PRINT TIME()
EXECUTE "SLEEP 2":@FM:"SLEEP 3"
PRINT TIME()

This following example directs output to a sequential file using the OUTPUT clause. It uses the standard Caché-supplied %Stream.FileCharacterOpens in a new tab class, which uses an operating system file as temporary storage. The location of the file is determined by the class itself, although a method allows you to override the default location. This example uses the default location. Once the object is closed, the temporary file is deleted. In this example, the size of the output from the LIST command is limited only by the maximum size of the file:

* Execute the LIST command to an object.
* 
oref = "%Stream.FileCharacter"->%New() 
EXECUTE "LIST BIGFILE ID-SUPP A1 SAMPLE 100" OUTPUT oref 
* 
* Read back that object, one line at a time. 
* 
oref->Rewind() 
lineno = 1 
LOOP WHILE oref->AtEnd = 0 DO 
line = oref->ReadLine() 
PRINT lineno "R%4":": " : OCONV(line,"MCP") 
lineno = lineno + 1 
REPEAT

The following example uses an OUTPUT clause with a user-defined MVExecute.Output class:

0001: oref = "MVExecute.Output"->%New() 
0002: EXECUTE "LIST BIGFILE ID-SUPP A1 SAMPLE 100" OUTPUT oref 
0003: * 
0004: * Read back that object, one line at a time. 
0005: * 
0006: LineCount = oref->LineCount 
0007: PRINT "Line count = ":LineCount 
0008: FOR I = 1 TO LineCount 
0009: PRINT I "R%4" : ": " : oref->ReadLine(I) 
0010: NEXT I

The following is the definition of this user-defined MVExecute.Output class. It contains the required Write() and WriteLine() methods, and a ReadLine() method:

Class MVExecute.Output Extends %Persistent 
{ 

Property LineCount As %Integer; 

Property Lines As array Of %String; 

Method Write(line As %String) As %Integer [ Language = mvbasic ] 
{ 
    IF NOT(@ME->LineCount) THEN 
        @ME->LineCount = 1 
        dummy = @ME->Lines->SetAt("",1) 
    END 
    LineNew = @ME->Lines->GetAt(@ME->LineCount) : line 
    dummy = @ME->Lines->SetAt(LineNew , @ME->LineCount) 
    RETURN 0 
} 

Method WriteLine(line As %String) As %Integer [ Language = mvbasic ] 
{ 
    IF NOT(@ME->LineCount) THEN 
        @ME->LineCount = 1 
        dummy = @ME->Lines->SetAt("",1) 
    END 
    LineNew = @ME->Lines->GetAt(@ME->LineCount) : line 
    dummy = @ME->Lines->SetAt(LineNew , @ME->LineCount) 
    @ME->LineCount = @ME->LineCount + 1 
    RETURN 0 
} 

Method ReadLine(LineNumber As %Integer) As %String [ Language = mvbasic ] 
{ 
    IF LineNumber LE 0 OR LineNumber GT @ME->LineCount THEN RETURN "??" 
    RETURN @ME->Lines->GetAt(LineNumber) 
} 

}

See Also

FeedbackOpens in a new tab