Progress
Programming
Handbook
Record Scoping
When Progress reads a record from the database, it stores that record in a record buffer. The scope of the record is the portion of the procedure where that record buffer is active. Record scope determines when Progress clears the record from the buffer, when it writes the record to the database, and how long a record lock is in effect.
Generally, the scope of a record is the smallest enclosing block that encompasses all references to the record. That is, the record is active until the block ends. However, there are exceptions to this rule depending on whether the record is weak scoped, strong scoped, or introduced by a free reference.
The exceptions are as follows:
- A strong-scoped reference occurs for buffers that are referenced in the header of a REPEAT FOR or DO FOR block. Any reference to that buffer within the REPEAT FOR or DO FOR block is a strong-scoped reference.
- A weak-scoped reference occurs for buffers that are referenced in the header of a FOR EACH or PRESELECT EACH block. Any reference to that buffer within the FOR EACH or PRESELECT block is a weak-scoped reference.
- All other references to records are free references.
The general scoping rules are as follows:
- If you have a strong-scoped reference to a buffer, you cannot reference that buffer in a containing block. The buffer is always scoped to the strong-scope block. You can however, have two sequential blocks that each contain strong-scoped references to the same buffer.
- If you have a weak-scoped reference to a buffer, you can reference that same buffer outside the weak-scope block. This raises the scope of the buffer to the outer block. You cannot, however, nest two weak-scope blocks for the same buffer. Also, a weak-scope block cannot contain any free references to the same buffer.
- If you have a free reference to a buffer, Progress tries first to scope that buffer to the nearest enclosing block with record scoping properties. However, other references to the same buffer outside that block cause Progress to raise the scope to a higher block.
The following example contains two DO FOR blocks that each contain a strong-scoped reference to the customer buffer:
p-strscp.p
![]()
In
p-strscp.p
, the customer buffer is scoped to each of the DO FOR blocks. Because strong-scoped blocks cannot be nested, you cannot change the outer DO to a DO FOR customer.You cannot make a free reference to the customer buffer outside the DO FOR block. For example, the following code does not compile:
p-stscp2.p
![]()
If you try to compile
p-stscp2.p
, you get a compile error.The following example contains two FOR EACH blocks that each contain a weak-scoped reference to the customer buffer:
p-wkscp.p
![]()
In
p-wkscp.p
, the customer buffer is scoped to each of the FOR EACH blocks. However, because these blocks apply a weak scope, you can reference the buffer outside these blocks and Progress automatically enlarges the scope. For example, the following procedure contains a weak-scope reference and a free reference to the customer buffer:p-wkscp1.p
![]()
In
p-wkscp1.p
, the scope of the customer buffer is referenced in the FOR EACH block, but a free reference also occurs outside the FOR EACH block. The scope is raised to the procedure block.You cannot nest two blocks that apply a weak scope to the same buffer. For example, the following code does not compile:
p-wkscp2.p
![]()
You can however, enclose a weak-scoping block within a strong-scoping block, as in the following example:
p-wkspc3.p
![]()
In
p-wkscp3.p
, the scope of the customer buffer is raised from the weak-scope FOR EACH block to the strong-scope DO FOR block.You can also have sequential strong-scope and weak-scope blocks for the same record, as in the following example:
p-wkstr.p
![]()
Note that the scope is not raised in
p-wkstr.p
. Instead, the DO FOR and FOR EACH blocks each scope the customer record separately. A reference to the customer buffer outside these blocks would be invalid and would cause a compiler error.Any reference that is neither a strong-scope reference nor a weak-scope reference is a free reference. For example, the following code contains two free references to the customer buffer:
p-frref1.p
![]()
In
p-frref1.p
, the first free reference occurs within the REPEAT block. Progress initially tries to scope the customer buffer to that block. However, because another free reference occurs after the REPEAT block, Progress raises the scope to the procedure.The following example also contains two free references to the customer buffer. However, in this case each reference is enclosed in a REPEAT block:
p-frref2.p
![]()
In this case, Progress still raises the scope to the procedure block. This means that the first iteration of the second REPEAT block finds the second customer record.
To determine the scope of a block, compile your procedure using the LISTING option. For example, to compile the
p-frref2.p
procedure, issue this command:
The p-frref2.out argument specifies the file in which you want Progress to store the listing information. You can use any valid filename. When you view this file, you see the following screen:
This listing shows that the buffer sports.customer is scoped to the procedure block.
Record scoping provides several services. The scope of a record tells Progress:
- When to write the record to the database. Progress automatically writes a modified record to the database at the end of the record scope, as shown in this procedure.
- When to release a record for use by other users in a multi-user system. Progress releases a record at the end of each iteration of the block to which the record is scoped. Whether the record will then be available for other users depends on the type of lock on the record and on whether a transaction is still active. See "Transactions" and "Locks" for more details.
- When to validate the record against any unique index and mandatory field criteria defined in the Dictionary.
- When to reinitialize the current position within an index. Progress maintains this position for each index used within a record’s scope. The position is initialized upon entry to the block to which the record is scoped.
- How to resolve references to unqualified field names. Within a record’s scope, you can use field names (without specifying the table) to refer to fields that do not share a name with fields in other tables in the database. You must include the table name when you reference fields of the same name from two or more tables.
Copyright © 2004 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |