# CHAPTER 3: Script Statements

The following chapters contain an alphabetical listing of all Empress GUI Builder script statements and functions. Each entry contains:

- A description of the statement or function
- A syntax diagram
- Relevant notes
- Information returned
- Related functions
- Examples of use

## call
Description | Call an action or an Empress GUI Builder function
Syntax |
    call funcname ([expr {, expr}]);
where:
`funcname` | is a function name.
`expr` | is an expression.
Notes | The `funcname` may be a GUI function or an action. If `expr`s are specified, they are evaluated and the results passed as arguments to the action or function.
Example | To call a script action named `menu` which does not take any parameters, use the command:
    call menu ();
To call the GUI function which displays a message:
    call empgui_dialog_info ("message", "Hello world!");

## call application
Description | Call an Empress GUI Builder application.
Syntax |
    call application appl_name ([expr {, expr}]);
where:
`appl_name` | is the name of an Empress GUI Builder application.
`expr` | is an expression.
Notes | The `appl_name` can be a string variable or a quoted string. The expressions are evaluated and passed as arguments to the application. If the application does not take parameters, the parentheses must be empty. If an argument is a string containing spaces, the string must be enclosed in additional quotation marks; otherwise, the spaces will be interpreted as argument separators. The application is executed as a separate process. Both the calling application and the called application will be active.
Returns | None.
Example | To call an application name `test`, use the command:
    call application "test"();
If application `test2` has two parameters, and the arguments passed to it are strings containing spaces:
    call application "test2" ("'first arg'", "'second arg'");
This would be equivalent to executing the following command from the UNIX shell:
    empgui mydb test2 'first arg' 'second arg'

## check
Description | Check whether the result of an expression is a valid value for the attribute.
Syntax |
    check expr for attr;
where:
`expr``` | is an expression which evaluates to the value to be assigned to the attribute.
`attr` | is an attribute specified as `tab_inst.attr`.
Notes | If `expr` evaluates to a value which is not valid for the attribute specified, an error message is displayed in dialog box. This statement will take into account the data type and any range check defined on the attribute. It also checks whether the attribute allows null values.
Returns | None.
Example | To verify that the data keyed into the field `name` in window `names` is a valid entry for the attribute `name` in `nametable`, use:
    check "names"@"name" for "nametable"."name";

## close
Description | Remove the given `cursor`.
Syntax |
    close cursor_name;
where:
`cursor_name` | is the name of the cursor on which the `close` is performed.
Notes | It closes cursors initialized with `open`s but does not discard the cursor declaration. Since a table instance can only support one cursor, this statement frees the table instance to be used for another cursor. This statement will fail giving an error if the cursor was never opened. If a cursor on a table is established, and another table instance is to be opened on the table, a `close` should be done on the cursor first. This guarantees that any work on the cursor is written from program buffers for the new table instance to pick up.
Returns | None.
See Also | `open`, `declare`, `undeclare`
Example | To close the cursor `namesakes`, use:
    close "namesakes";

## close table
Description | Close one or more table instances.
Syntax |
    close table tabinst {, tabinst};
where:
`tabinst` | is the name of the table instance to be closed.
Notes | This command cannot close a table instance currently in use in a cursor. To close such a table, first issue a `close` `cursor` and an `undeclare`.
Returns | None.
See Also | `open` `table`
Example | To close the table `nametable`, use:
    close table "nametable";

## commit
Description | Commit the current transaction.
Syntax |
    commit [transaction];
Notes | The current transaction is committed. The transaction must have been started with a `start` `transaction` command. All database operations subsequent to the start of the transaction are committed. If no transaction is in progress, an error message is reported. To roll back a transaction, see the rollback command.
Returns | None.
See Also | `start` `transaction`, `rollback`, `savepoint`
Example | To commit the current transaction, use:
    commit transaction;

## declare
Description | Declare a cursor, associating it with a select statement
Syntax |
    declare cursor_name cursor for query [ with count ];
where:
`cursor_name` | is a string identifying this cursor
`query` | is a SQL `SELECT` statement as follows:
`select [| distinct |] [| select_item {, select_item}|]` `| all | | * |` `from tab_inst [[alias] aliasname] {, tab_inst [[alias] aliasname]} [where_clause] [group_clause [having_clause]] [sort_clause]`
Notes | This statement declares a cursor without executing the `SELECT` statement. The actual query is executed using the `open` cursor statement. The `with` `count` option causes the `sqlcount` variable to be set to the number of records selected when the cursor is opened. The cursor declared with this statement can be removed with the `undeclare` statement. Attributes are specified using the form `tab_inst.attr` where `tab_inst` is the table instance, and `attr` is the name of the attribute. The query can only refer to attributes which are in the table instances specified in the `from` clause. A `select_item` is either an attribute or an expression. Values of expressions can be accessed using the form `cursor_name`."`expression_n`", where `n` is an integer identifying the expression. If the `select_item` has a `PRINT` clause, its value can also be accessed using the form `cursor_name`.`print_item_name`. The value of a `select_item` can also be accessed using the form `cursor_name`.`i` where `i` is an integer indicating the column number of the `select_item`. The `where_clause` consists of conditions similar to those in Empress SQL. In addition, expressions in the `where_clause` can refer to objects (such as fields, radio boxes etc.). An expression will be eliminated from the `where_clause` if a null value (for example, if a field is empty) appears on the right side of a comparison operator opposite an attribute. If a `group_clause` is used, the result of the query will contain an aggregate record after each group of records. The aggregate record will have the results of aggregate expressions, and will contain null values for non-aggregate `select_items`. Refer to the Empress SQL: Reference manual for details of the `SELECT` statement.
See Also | `undeclare`, `open`, `close`
Example | `declare "c1" cursor for` `select name, dept, salary, avg(salary) print "average"` `from staff` `where "staff"."name" match "win"@"name"` `group by "staff"."dept"` `with count;` The cursor `c1` defines a query to retrieve records from table instance `staff`. Only records where attribute name matches the pattern in field `name` will be selected, but if field `name` is `NULL`, all records will be selected. The value of the aggregate expression can later be accessed using one of these forms:
    "c1"."expression_1"
    "c1"."average"
    "c1".i
where `i` is an integer with the value 4.

## delete
Description | Delete a record.
Syntax |
    delete from tabinst;
where:
`tabinst` | is a name given to an Empress database table when it is opened for access.
Notes | The record deleted is the current record of the cursor generated from the `tabinst`. If there is no current record for a `tabinst`, a warning message is displayed in a dialog box. The `tabinst` must have been opened in update or deferred mode.
Returns | None.
Example | To delete a record in `nametable`, use:
    delete from "nametable";

## disable
Description | Disable access to the current record within a given cursor.
Syntax |
    disable cursor;
where:
`cursor` | is the selected cursor to be disabled.
Notes | The `disable` command effectively disestablishes the current record without losing its position. The lock on the record is released, and attempts to update or delete the record will fail. The cursor is disabled until a current record is established with a `fetch` or `enable` statement.
Returns | None.
See Also | `enable`
Example | To disable any update or delete operations on `namesakes`, use:
    disable "namesakes";

## enable
Description | Enable access to the current record of a `cursor`.
Syntax |
    enable cursor;
where:
`cursor` | is the selected cursor to be enabled.
Notes | If the cursor was disabled, `enable` re-establishes the current record if it still exists or is not locked by another user. If a multilist has been associated to the cursor with the function `empgui_multirecord`_`define()`, `enable` causes the highlighted row in the multilist to become the current record.
Returns | None.
See Also | `disable`, `fetch`
Example | To enable the cursor `namesakes`, use:
    enable "namesakes";

## exit
Description | Stop execution of a script or a module.
Syntax | `exit[ | confirm | ];` `| script |`
Notes | Whenever you exit a module, the module exit script is executed. If the `confirm` option is specified, the user will be prompted for exit confirmation with a "`Confirm exit? (y/n)`" message. If the script option is specified, the current script action is exited, but the module is still running. If the script action was called by another action, control is not returned to that action.
Returns | None.
Example | To exit the current module, use:
    exit;
To stop execution in the current script action but not exit the current application, use:
    exit script;

## fetch
Description | Retrieve a row in a cursor
Syntax | `fetch [ [| next | ] from ] cursor_name;` `| prior |` `| first |` `| last |` `|relative n|` where:
`cursor_name` | is the name of a cursor
`n` | is an expression evaluating to an integer value
Notes | The cursor must be opened before a fetch can be performed. The `next` option specifies that the row to be retrieved is the one after the current row in the cursor. The `prior` option specifies that the row to be retrieved is the one before the current row in the cursor. The `first` option specifies that the row to be retrieved is the first one in the cursor. The `last` option specifies that the row to be retrieved is the last one in the cursor. The `relative` option specifies that the row to be retrieved is `n` rows away from the current row in the cursor. If `n` is 0, the current row is fetched again. Note that `n` can be a negative integer. The default option is `next`. A successful `fetch` automatically enables the cursor, establishes a current row, and initializes each attribute of the table instances in the cursor with the values of the selected row's attributes. The system variable `sqlresult` is 1 after a successful `fetch`. If there was no such row, `sqlresult` is 0. For example, if the current row is the last one, and a `fetch` `next` if performed, `sqlresult` returns 0, and there is no current row. If a row cannot be fetched because of locks, `sqlresult` is set to -1, and the row becomes current, although the values of its attributes could not be read.
See Also | `open`, `fetch` `group`, `disable`
Example | Fetching the next row in the cursor. If the row was locked, attempt to retrieve it again. If the previous row was the last row, display a message. `fetch next from "c1";` `switch sqlresult` `case 0:` `call empgui_dialog_info ("Next", "No more row");` `case 1:` `call empgui_objects_set ("win", "c1");` `case -1:` `fetch relative 0 from "c1";` `if (sqlresult = 1)` `call empgui_objects_set ("win", "c1");` `else` `call empgui_dialog_info ("Next", "Locked row");` `end;` `end;`

## fetch group
Description | Retrieve a group of rows in a cursor
Syntax | `fetch group [ [| next | ] from ] cursor_name;` `| prior |` `| first |` `| last |` `|relative n|` where:
`cursor_name` | is the name of a cursor
`n` | is an expression evaluating to an integer value
Notes | The cursor must be opened before a fetch can be performed. If the query for which the cursor was declared does not have a `group_clause`, all the rows selected are considered to be part of the same group. The `next` option specifies that the group to be retrieved is the one after the current group in the cursor. The `prior` option specifies that the group to be retrieved is the one before the current group in the cursor. The `first` option specifies that the group to be retrieved is the first group in the cursor. The `last` option specifies that the group to be retrieved is the last one in the cursor. The `relative` option specifies that the group to be retrieved is `n` groups away from the current group in the cursor. If `n` is 0, the current group is fetched again. Note that `n` can be a negative integer. The default option is `next`. A successful `fetch` `group` advances the current row pointer to the aggregate row of the specified group. The system variable `sqlresult` is 1 after a successful `fetch` `group`. If there was no such group, `sqlresult` is 0. For example, if the current group is the last one, and a `fetch` `group` `next` if performed, `sqlresult` returns 0, and there is no current row.
See Also | `declare`, `open`, `fetch`
Example | Fetching the next group in the cursor. If the previous group was the last group, display a message, otherwise update the display. `fetch group next from "c1";` `switch sqlresult` `case 0:` `call empgui_dialog_info ("Next", "No more group");` `case 1:` `call empgui_multirecord_display ("c1");` `end;`

## global
Description | Declare variable to be global in scope.
Syntax |
    global type variable {; type variable} ; end;
where:
`type` | is the data type of the variable.
`variable` | is the name of the variable.
Notes | The named variables are declared to be global to the application and of the given types. See Chapter 1.2 - "Variables". A `global` variable may only be declared in the global script action of the module. The variable may be an array available, in which case the number of elements must be specified on an integer constant between square brackets after the variable name.
Returns | None.
See Also | `parameters`, `local`
Example | To define variables `name` and `age` array and variable `children` so that they will be known throughout the application, do the following in the global script: `global` `char name;` `integer age;` `char children [5];` `end;`

## if
Description | Choose one of two branches of statements based on the evaluation of a condition.
Syntax | `if condition [then]` `{statement;}` `[|else{statement;}|]` `|elseif_clause |` `end;` where `elseif_clause` has the format: `elseif condition [then]` `{statement;}` `[|else{statement;|]` `|elseif_clause |` and `condition` may be one of the following: `TRUE` `FALSE` `(condition)` `condition or condition` `condition and condition` `not condition``` `exprrange value[|exclusive|]to value[|exclusive|]` `|inclusive| |inclusive|` `exprbetween value[|exclusive|]and value[|exclusive|]` `|inclusive| |inclusive|` `expr[|= |] null` `|!=|` `|~=|` `null expr` `` `expr |= | expr` `|< |` `|> |` `|<= |` `|>= |` `|!= |` `|<> |` `|~= |` `|like |` `|not like|` `|match |` `|!match |` `|smatch |` `|!smatch |` where:
`(condition)` | guarantees precedence.
`or` | is an `or` conjunction which returns true if either condition is true.
`and` | is an `and` conjunction which returns true if both conditions are true.
`range` `between` | is a `range` or `between` condition which returns true if the value falls in the given range. The `exclusive` keyword means that the boundary values are not included in the range. The `inclusive` keyword means that the boundary values are included in the range. The keyword `excl` is a synonym for `exclusive` and `incl` is a synonym for `inclusive`. The default is `inclusive`.
`Patterns` | are operators `like`, `match`, `smatch` (single-case pattern match), `!match` and `!smatch` providing pattern matching. Pattern matching is as for Empress Query Language `WHERE` clauses. The interpretation of patterns is in the following table.
Pattern Matching Characters
Character | Use | Example
`?` | Matches any character in the position. |
`*` | Matches 0 or more occurrences of any character. |
`[...]` | Matches any of a set of characters in the position. | `[abc]` matches "a", "b", "c"
`{...}` | Matches 0 or more occurrences of a fixed length pattern. | `{[a-z]}` matches any string of lower case letters
`[.-.]` | Matches any range of characters in the position. | `[a-cf-i]` matches "a", "b", "c", "f", "g", "h", "i"
`[^...]` | Matches anything but a set or range of characters in the position. | `[^123]` matches everything but 1, 2, and3; `[^a-d]` matches anything but "a", "b", "c", and "d"
`...|...` | Requires a match on either side of the bar. | "`ab|cd`" requires a match on "ab" or "cd"
`...&...` | Requires match on both sides of the ampersand. | `[a-z]`&`[^x]` matches any letter except "x"
`\` | Placed before any of the special characters "?", "*", "|", "&", "{,}", "[,]", and "\", causes the character to be interpreted as an ordinary character. |
``
Notes | If the `condition` is true, the statements after the `then` are executed. If the condition is false, the statements following the `else` or `elseif` are executed. In a `condition` that compares two expressions, neither expression should evaluate to null, else an error is flagged. To prevent this from occurring, test for null explicitly before using an expression that may have a null value. Attempting to compare a string and a number results in an expression failure. An error message will be generated.
Returns | None.
Example 1 | Suppose you are writing an exit action for the field `name` in the window `names`. If you want to be able to leave the application by typing `stop` in the `name` field, you could use this statement: `if "names"@"name" = "stop" then` `exit;` `end;`
Example 2 | Extending the above example, suppose you wish to take the following actions in the exit action for the `name` field: If the field is empty prompt for a value. If the value is `stop` exit the application. If there is a value and it is not `stop` call the script `get_details`. You can use the `if` statement as follows: `if "names"@"name" = null then` `call empgui_dialog_info ("Name missing", "Please enter a name");` `elseif "names"@"name" = "stop" then` `exit;` `else` `call get_details ();` `end;`

## insert
Description | Insert a record into a table
Syntax |
    insert into tab_inst;
where:
`tab_inst` | is the name of a table instance
Notes | The values of the attributes in the table instance are used to create a new record in the table associated with the table instance. The table instance must have been opened in update or deferred mode. Inserting a record does not affect the position of the current row of a cursor (if any) associated with the table instance. In other words, the record inserted does not become the current record. To prevent confusion on the part of the user, the cursor should be disabled immediately after an `insert`.
See Also | `open` `table`, `fetch`, `disable`
Example | The attributes in table instance `staff` are assigned values from objects in window `n`, and a new record is inserted into the table:`` `let "staff"."name" = "win"@"name_field";` `let "staff"."dept" = "win"@"dept_radio_box";` `let "staff"."salary" = "win"@"salary_scale";` `insert into "staff";`

## let
Description | Assign a value to a variable.
Syntax | `let variable =|expr |;` `|NULL |` `|TRUE |` `|FALSE|` where:
`variable` | is one of: `attribute`, `object`, `system` `variable` , or `variable`.
Notes | Remember that an object is usually cited as `window@object`. A `window` is the name of a window or bin. An `object_name` is the name of an object.
Returns | None.
Example | To assign the value of the attribute `nametable.address` to the field `names@address`, use:
    let "names"@"address" = "nametable"."address";
To place the values of attribute `nametable.name` for several records into an array `names`. `let i = 0;` `while (i<20)` `let i = i+1;` `fetch next from "names_cursor";` `let names[i] = "nametable"."name";` `end;`

## local
Description | Declare a variable to be local in scope.
Syntax |
    local type variable {; type variable} ; end;
where:
`type` | is the data type of the variable.
`variable` | is the name of the variable.
Notes | The named variables are declared to be local to the script and of the given types. See Chapter 1.2 - "Variables". A `local` variable may have the same name as a global variable created in the global script. Within the current script the local variable is recognized, while outside the script the global variable is recognized. There may be only one `local` statement in a script. It must follow the `parameters` statement, if any, and precede all other statements. The variable may be an array variable, in which case the number of elements must be specified as an integer between square brackets after the variable name.
Returns | None.
See Also | `parameter`, `global`
Example | To declare variables `name` and `age` and array `children` so that they will be known only in the script where they are declared, use:`` `local` `char name;` `integer age;` `char children [3];` `end;`

## lock
Description | Apply locking to the specified table.
Syntax | `lock table [in]|exclusive| [mode];` `|share |` where:
`table` | is the name of the table instance to be locked.
Notes | The `lock` statement locks the table known by the table name. It is only effective during a transaction. A table may be locked in exclusive or share modes. An exclusive lock gives exclusive access to the table. No one else may select from or update the table and no other locks may be placed on it concurrently. A share-mode lock guarantees only that you will be able to select from the table and precludes update operations from others. Several share-mode locks can be placed on a table at one time. If there is more than one share-mode lock on a given table it may not be updated. If you have placed the only share-mode lock on a table you may perform updates on that table. Records so updated will not be accessible to others for the remainder of the transaction. The `lock` command will only have effect if some level of locking has been set for the table using the Empress `LOCK` `LEVEL` Query Language command.
Returns | None.
Example | To lock the table `nametable` in exclusive mode during a transaction, type:
    lock "nametable" in exclusive mode;

## on
Description | Trap exception conditions and determine how the system responds to them.
Syntax | `on || event | [num {, num }] | | call function(..) |;` `|| warning | | | display |` `|| database error| | | ignore |` `| error |` where:
`function` | is an Empress GUI Builder function or a user-defined action
`num` | is an integer identifying the exception condition
Note | An `event` is a minor exception condition that is not reported by default. A `warning` is an exception that would normally cause a message to be displayed in a pop-up dialog box. A `database` `error` is an error related to a database command. An `error` is a serious exception. The `call` `function` (...) option allows an action or GUI function to be called with the appropriate arguments. These arguments may not reference local variables. The `display` option causes a message related to the exception condition to be displayed in a dialog box. This is the default for most exceptions except events. The `ignore` option causes the exception condition to be ignored. This is the default for events. If one or more `num` codes are specified, only exceptions with those codes will be trapped. Otherwise, all exceptions of the specified class are trapped.
Events
num | Meaning
3001 | Record inserted
3002 | Record updated
3003 | Record deleted
3004 | Null record ignored
3005 | Null record deleted
3006 | Some records are locked
3007 | No next record
3008 | No previous record
3009 | No records selected
3010 | Record unattainable
3011 | No next group
3012 | No previous group
Warnings
num | Meaning
2001 | No current record
2002 | Table instance already exists
2003 | Table instance being used
2004 | Table instance does not exist
2005 | Cursor already exists
2006 | Cursor does not exist
2007 | `call` `application` error
2008 | `call` `empgui_system_command` error
2009 | No transaction in progress
2010 | Transaction already in progress
2011 | Error starting transaction
2012 | Transaction not started in application
2013 | Transaction label not defined in application
2014 | Index value out of range in array
Database Errors
num | Meaning
501 | Null value for attribute in `check` command
502 | Delete invalid on aggregate
503 | Update invalid on aggregate

## open
Description | Open a cursor to select records.
Syntax |
    open cursor_name;
where:
`cursor_name` | is the name of a cursor established by a `declare` statement.
Notes | The `open` statement effectively executes the `SELECT` statement defined by the cursor declaration, and initializes or re-initializes the cursor with records. There is no current record immediately after an `open`. A cursor can be re-opened without explicitly closing it first. If the cursor is associated with a multilist with the function `empgui_multirecord`_`define()`, opening the cursor automatically causes the multilist to be updated.
Returns | None.
See Also | `declare`, `cursor`, `undeclare`
Example | Given the `declare` command:
    declare "namesakes" cursor for select from "nametable"
    where "nametable"."name" = "names"@"name";
You can initialize the cursor with records using:
    open "namesakes";

## open table
Description | Open database tables for access.
Syntax | `open table tablename |read | [as tabinst {, tabinst}]` `|update |` `|deferred|` where:
`tablename` | is the name of an Empress table.
`tabinst` | are the "instance names" by which the `table` is to be known and referenced.
Notes | The `tablename` may be specified using `database:tablename` where `database` is the database containing the table and `tablename` is the name of the table in the database. The `database` may be other than the current user database. `tabinst`s are names by which the tables are known in the application. If no `tabinst` is specified, the value of `tablename` is taken as the "instance name". Tables may be opened in one of several modes. If a table is opened in read mode no update type operations can be done on it. With record level locking defined for the table, a read lock is in effect for each record while it is current. If a table is opened in update mode records may be inserted, updated and deleted from it. With record-level locking defined for the table an update lock (i.e., exclusive access lock) is in effect for each record while it is current. If a table is opened in deferred mode records may also be inserted, updated and deleted from it. However, if locking for the table is set at the record level only a read lock is placed on each record when it becomes current. The read lock is exchanged for an update lock only when an update type operation occurs. The update lock lasts for the duration of the update type operation, then it is replaced with a read lock again. The read lock is removed when the record is no longer current. Opening a table in deferred mode thus keeps the table in a shareable state more of the time (given record level locking on the table). Locking levels are described in the Empress SQL: Reference under the `LOCK` `LEVEL` command. Update type operations on a table via any instance name affect the records accessed through all the instance names. The Empress variables `MSIAEXCLRETRY`, `MSIAEXCLSLEEP`, `MSIALOCKRETRY` and `MSIALOCKSLEEP` are used when attempting to place locks on a table. The time required to open a large number of tables in the same database can be reduced if the `open`s are issued consecutively in a script.
Returns | None.
See Also | `close` `table`
Example | To open the table `nametable` in update mode, use:
    open table "nametable" update;
The table instance name becomes `nametable` by default since no `tabinst` was specified. On the other hand:
    open table "nametable" update as "exampletable";
opens the table to the name `exampletable`. Any references to this table will then be to `exampletable`. For instance, the attribute `name` of the Empress table `nametable` would be known in the application as `"exampletable"."name"`.

## parameters
Description | Declare variables to receive values passed to a script.
Syntax |
    parameters type variable {; type variable} ; end;
where:
`type` | is the data type of the variable.
`variable` | is the name of the variable.
Notes | Parameters are values that are passed to a script action when that action is run. The values are stored in the named `variable` and must be of the given `type`s. See Chapter 1.2 - "Variables". A `variable` defined as a parameter is known only in the script action where it is so defined, i.e., it is local in scope. Parameters are initialized when the action is invoked with arguments. The parameters assume the values of the arguments. Empress reports an error if a script is invoked with a different number of arguments than the number of parameters defined in it. There can be only one `parameters` statement in an action and it must precede all other statements. The variable may be an array variable, in which case the variable name is followed by open and close square brackets, without specifying the dimension. Arrays are passed by reference.
Returns | None.
Example | Suppose you have an action `family` which begins by defining parameters `name`, `age`, and `children`: `parameters` `char name;` `integer age;` `char children [ ];` `end;` You could then execute the statements: `let offsprings[1] = "Jimmy";` `let offsprings[2] = "Betsy";` `let offsprings[3] = "Lilian";` `call family ("John", 30, offsprings);` The `family` script action would be invoked, the `name` parameter would have the value `John`, the `age` parameter the value `30`, and `children` would be an array of three elements containing values `Jimmy`, `Betsy` and `Lilian`.

## return
Description | Cause an immediate return from a script action.
Syntax |
    return [expr];
where:
`expr` | is a value to be returned.
Notes | Control returns to the script that invoked the script with the `return` statement.
Returns | None.
Example | A script that computes a value called `result` could return the result with the statement:
    return result;
If the action is named `calculation`, and accepts two arguments, then it would be invoked as in:
    let store_result = calculation (argument1, argument2);
Here, the arguments are the contents of `argument1` and `argument2`, and the returned result is stored in the variable `store_result`.

## rollback
Description | Roll back a transaction.
Syntax | `|rollback|[transaction] [to savepoint];` `|cancel |`
Notes | This rolls back a transaction. A `savepoint` (given as a string starting with a letter) may be specified to roll back to the start of that nested transaction. If no `savepoint` is specified, the entire transaction is rolled back. A transaction is started with a `start transaction`. A save point is set with a `savepoint` statement. All database operations subsequent to the start of the transaction (or the save point) are rolled back. If no transaction is in progress, an error message is reported. To commit a transaction, see `commit`.
Returns | None.
See Also | `commit`, `savepoint`, `start transaction`
Example | The following group of statements rolls back the transaction to the save point `t1`.
    start transaction;
    ...
    savepoint t1;
    ...
    rollback transaction to t1;
This returns the database(s) to the state immediately following the setting of the save point.

## savepoint
Description | Set a save point in a transaction.
Syntax |
    savepoint savepoint;
where:
`savepoint` | is a name of savepoint given by user, it is a string starting with a letter.
Notes | A transaction must be in progress for the statement to succeed. A save point is marked in the transaction, starting a nested transaction. A `rollback` `transaction` `to` `savepoint` statement can be used to rollback the transaction to any defined save point. A commit transaction statement will commit the entire transaction. If the application ends before the transaction is explicitly committed or rolled back, it is committed by default.
Returns | None.
See Also | `start transaction`, `commit`, `rollback`
Example | The following sequence starts a transaction, sets a save point, then rolls back. The operations up to the save point are then committed.
    start transaction;
    ...
    savepoint t1;
    ...
    rollback transaction to t1;
    commit transaction;

## start transaction
Description | Start a transaction.
Syntax | `start transaction;`
Notes | A transaction is started. Any database operation on any database subsequent to this statement is part of the transaction until the transaction is either committed or rolled back. If a transaction is already in progress, a `savepoint` can be used to roll back to later. To commit a transaction, see `commit`. To roll back a transaction, see `rollback`. If the application ends before the transaction is explicitly committed or cancelled, it is committed by default. When one application is called by another, the transaction in the called application can be started and ended without affecting the calling application.
Returns | None.
See Also | `commit`, `rollback`, `savepoint`
Example | The following sequence starts a transaction, then sets a savepoint which is later rolled back. The operations up to the save point are then committed.
    start transaction;
    ...
    savepoint t1;
    ...
    rollback transaction to t1;
    commit transaction;

## switch
Description | Test whether an expression matches one of a number of constants and branch accordingly.
Syntax | `switch expr` `{ case constant {, constant}: {statement;} }` `[ default: {statement;} ]` `end;` where:
`expr` | is an expression that evaluates to a string, an integer, or a decimal.
`constant` | is a constant of the same data type as `expr`.
`statement` | is the statement to be executed on a match.
Notes | The default case is chosen if the expression does not match any constant.
Returns | None.
Example | In this example, the variable `name` is set to the selected toggle button in a radio box. After printing the message, control leaves the `case` statement. `let name = "window1"@"radiobox";` `switch name` `case "Jim": call empgui_dialog_info ("Name", "It's Jim");` `case "Joe": call empgui_dialog_info ("Name", "It's Joe");` `case "Ann": call empgui_dialog_info ("Name", "It's Ann");` `default: call empgui_dialog_info ("Name", "Neither Jim,` `Joe nor Ann");` `end;`

## undeclare
Description | Remove a cursor created by `declare`.
Syntax |
    undeclare cursor_name;
where:
`cursor_name` | is the name of a selected cursor.
Notes | This statement will fail giving an error if the cursor was never established.
Returns | None.
See Also | `declare`, `open`, `close`
Example | To disable the cursor `namesakes`, use:
    undeclare "namesakes";

## update
Description | Update the current record in a table.
Syntax |
    update tab_inst;
where:
`tab_inst` | is the name of a table instance
Notes | The values of the attributes in the table instance are used to update the current record in the table associated with the table instance. The table instance must have been opened in update or deferred mode.
See Also | `open` `table`
Example | The attribute `salary` in table instance `staff` is assigned a value and the current record in the table is updated:`` `let "staff"."salary" = "win"@"salary_scale";` `update "staff";`

## while
Description | Repeatedly execute one or more statements while a condition is true.
Syntax |
    while condition {statement;} end;
where:
`condition` | is a condition to be evaluated.
`statement` | is an Empress statement to be executed.
Notes | The `statement`s are performed as long as the `condition` is true. See the `if` statement for the list of allowable conditions.
Returns | None.
Example | A script that counts from one to a hundred is: `let number = 1;` `while number < 100` `let number = number + 1;` `end;`