John and Maria have
concurrent access to the SAS data set FUEL in their respective sessions.
While Maria is editing the data set DATALIB.FUEL in an FSEDIT window,
John can use a SET, a MERGE, or an UPDATE statement in a DATA step
to read DATALIB.FUEL. Although John cannot create a new version of
DATALIB.FUEL, he can create other data sets or written reports.
The following program
shows the effect of implicit locking when two clients access the same
SAS data set at the same time:
data _null_;
set datalib.fuel;
file report ps=24 n=ps;
...
run;
data composit;
merge datalib.fuel fuel96;
run;
If John uses a SET statement
to read DATALIB.FUEL, he cannot specify the KEY= or POINT= option
unless he overrides the member-level control. By default, member-level
control is required when either of these options are included in a
SET statement. Here's an example.
data pressure;
set fuel (keep=fuel maxpress);
set datalib.fuel (cntllev=rec) key=fuel;
...
run;
If John uses an UPDATE
statement or a SET or a MERGE statement with a BY statement to read
DATALIB.FUEL, he should consider specifying member-level control to
ensure that the data set remains correctly ordered while his DATA
step runs. Here's an example.
data composit;
merge datalib.fuel (cntllev=mem) fuel96;
by grade;
run;
John
cannot create a new version of DATALIB.FUEL, but he can use a MODIFY
statement in a DATA step to update the shared data set. Here's an
example.
data datalib.fuel;
modify datalib.fuel;
if (grade='03N') then
do;
grade='3Np';
revised=today();
replace datalib.fuel;
end;
run;
When John uses the preceding
DATA step to update an observation that Maria is editing in her FSEDIT
window, the replace operation for that observation fails because Maria
has the observation locked. This failure causes the DATA step to terminate
as soon as the locked observation is encountered. However, any observations
that are updated before the termination retain their updated values.
For applications
that update shared data by using a MODIFY statement, it is very important
to include error-checking statements to prevent failure in the updating
process and premature termination. The automatic variable _IORC_ includes
the return codes from the read operation (performed by the MODIFY
statement) and the update operations (performed by the REPLACE, OUTPUT,
and REMOVE statements). The preceding DATA step would be more effective
if it was written as follows:
data datalib.fuel;
modify datalib.fuel;
if (grade='03N') then
if (_iorc_ = 0) then
/* read with lock for successful update */
do;
grade='3Np';
revised=today();
replace datalib.fuel;
end;
else
put 'Observation' _n_
'(fuel' fuel ') was not replaced.';
run;
The preceding DATA step
checks the value of _IORC_ to determine whether a warning or an error
condition occurred while reading an observation in DATALIB.FUEL. If
the observation was read successfully, it can be replaced. If the
observation could not be read, a message is written to the SAS log
to record the failure and to identify the observation that was not
updated.
To check for
specific values of _IORC_, use the SYSRC macro. For example:
data datalib.fuel;
modify datalib.fuel;
if (grade='03N') then
if (_iorc_ = 0) then
/* read with lock for successful update */
do;
grade='3Np';
revised=today();
replace datalib.fuel;
end;
else if (_iorc_ = %sysrc(_SWNOUPD)) then
put 'Observation' _n_
'(fuel' fuel ') was not replaced.';
else
put 'Observation' _n_
'(fuel' fuel ') read with rc' _iorc_;
run;
For complete information
about the MODIFY statement, see
SAS Statements: Reference. For
information about the SYSRC macro and _IORC_ return code checking,
see
SAS Macro Language: Reference.