For Each command

Official Content
This documentation is valid for:

The GeneXus procedural language command used to get a dataset from the database. When used in Procedure objects, besides reading the database, it can also be used to update it.

Within a For Each command you define the information you want to read (also write if inside a Procedure object) by specifying the Transaction Level from which you want to retrieve information and the name of the attributes you want to use. In addition, it has many optional clauses that let you fine-tune your query.


For each [<BaseTrnList>]

[SKIP <Expression> COUNT <Expression>]







[When duplicate


[When none




<BaseTrnList> ::=
<Trn1> {, <Trni>}...

i.e. a list of Transaction Level names. See more on Base Transaction clause.


<OrderList> ::=

{ {order <attributeList>i [when <cond>i] } | [order none] [when <cond>x] }...

Allows to indicate the order in which the query will be returned. As the syntax indicates, you can write many conditional order clauses as well as undefined order (order none).

<UsingDataSelector> ::=
using <DataSelectorName>( [ <parameterList> ] )

Allows ordering & filtering according to the criteria set out in the Data selector specified by its name <DataSelectorName>.

<UniqueAttributeList> ::=
unique <attributeList>

Returns only those records where the set of values of the referred attributes is unique. See more on Unique Clause.

<ConditionList> ::=
{where {<condition> [when <condition>] } |
  { [not]<attribute> in <DataSelectorName>( [<parameterList>]) }

Allows indicating a list of conditions that must be matched by the data in order to be processed within the for each (inside the <MainCode>). The conditions are boolean expressions, simple ones or very complex nested ones.
See more on Where clause (<condition> syntax included).

<BlockingGroup> ::=
blocking <numericExpression>

Available in procedures (when updating/deleting). It indicates the amount of records that will constitute a database block, when you are updating or deleting, in order to reduce the number of roundtrips to the DBMS. See more on Blocking clause.

<MainCode> ::=
<CodeWhenDuplicate> ::=

Available in procedures, when inside <MainCode> certain attribute is updated (overwritten) and there exists a unique index for it. When you intend to overwrite the record with a previously existing value, this code will be executed instead of <MainCode> for that record. See more on When duplicate clause

<CodeWhenNone> ::=

When there is no data meeting the filter conditions, the <MainCode> commands will not be executed; the <CodeWhenNone> commands will be executed instead. See more on When None Clause.


The Defined By Clause from previous versions of GeneXus (located between <ConditionList> and <BlockingGroup> in syntax), although allowed, becomes meaningless against the Base Transaction clause.


Boolean expressions in the where clause constraints the dataset that is obtained. However, more than that is meant here. There is a great difference between a full scan table access and an index-optimized random access. If applying some rules of logic, GeneXus determines that the order clause (or the primary key order) is compatible with the where boolean expression(s), it optimizes the access to the table using indices and not doing a full table scan. This is obviously the desired behavior whenever possible.

See Conditional Orders and Filters for further information.

Smart Devices applications

For Each command can be used when developing applications for Native Mobile Generator but with some considerations. It can only be used in Work With for Smart Devices object and Panel object and only in the System Native Mobile Applications Events, this means Start, Refresh and Load events.

See Also

Nested For Each commands


Start Video Introduction to For Each command to access the database
Start Video More on nested For eachs. Cases and navigation
Start Video Syntax of the For each command