The FEEDBACK= option
in the INFILE statement specifies a SAS variable that is set to the
VSAM feedback code when VSAM detects a logical error. You can determine
what caused the error by inspecting the FEEDBACK= variable value.
You can then design program logic that takes appropriate action depending
on the value of the FEEDBACK= variable. You must reset the values
of both the FEEDBACK= variable and the _ERROR_ variable to 0 in order
to continue processing.
Resetting the variable
to 0 enables you to continue processing in a meaningful way. That
is, you can continue both to read and write records and detect other
errors in the DATA step. If you do not reset the FEEDBACK= and _ERROR_
variables before the next INPUT or PUT statement, SAS assumes that
your program cannot handle the error condition, and it executes the following:
-
prints a message that
includes information about the data set and the VSAM logical error
code on the SAS log
-
The DATA step also terminates
when the FEEDBACK= option is
not specified,
and a logical error occurs while it attempts to write with a PUT statement.
VSAM cannot return data
to the input buffer when there is a logical or physical I/O error.
Subsequent INPUT statements cannot read from an empty INPUT buffer,
which leaves variables without values. To avoid this situation, test
the values of _IORC_ and the FEEDBACK= variable by using a trailing
@ with the INPUT statement that initiates the VSAM read request:
infile indata vsam feedback=NOERROR;
input @; /* Read: look at values of FEEDBACK= variable */
/* and _IORC_. If OK, finish reading values */
/* into variables and write them to the SAS */
/* print file. */
if _IORC_ = 0 and NOERROR=0 then do;
input var1 $ var2 var3 $;
file print;
put var1 var2 var3;
end; /* If _IORC_ and NOERROR=0 */
else if _IORC_= 12 then do;
/* Physical error has occurred. */
/* INPUT buffer is empty: nothing to read. */
_ERROR_ = 0; /* Reset the _ERROR_ variable. */
file log; /* Write message on the SAS log. */
put 'Physical error has occurred for observation ' _N_ '.'
'I/O return code is ' _IORC_ '.';
input; /* Ignore blank buffer: release trailing @. */
return;
end; /* Else: _IORC_=12 */
else if NOERROR ^= 0 then do;
/* Logical error has occurred. */
/* INPUT buffer is empty: nothing to read. */
_ERROR_ = 0;
file log; /* Write message on the SAS log. */
put 'Logical error has occurred for observation ' _N_ '.'
'Feedback code is ' noerror '.';
NOERROR=0; /* Reset FEEDBACK= variable back to 0. */
input; /* Ignore blank buffer: release trailing @ */
_ERROR_ = 0; /* Above INPUT stmt. sets both the _ERROR_ */
NOERROR=0; /* and the FEEDBACK= variables. Both need */
/* to be reset to 0 again. */
return;
end; /* Else: NOERROR ^= 0 */
...more SAS statements...
Using the INPUT @ statement
gives you the opportunity to examine the FEEDBACK= variable for a
nonzero value, which indicates that a logical error has occurred.
If both the _IORC_ and the FEEDBACK= variables are zero, continue
with the INPUT statement to read data into variables.
Notice that the _ERROR_
and the FEEDBACK= variable, NOERROR, need to be reset to 0
twice when set to a nonzero value by an INPUT statement
with a trailing @. They need to be reset to 0 the first time in order
to continue processing. The processing continues by releasing the
held record from the input buffer with an INPUT statement without
a trailing @. This sets the _ERROR_ and FEEDBACK= variables to nonzero
values again. Therefore, they need to be reset to 0 a second time
in order to proceed.
You might want to print
error messages warning you that either a physical error was encountered
(if _IORC_ is 12) or a logical error was encountered (if the FEEDBACK=
variable is not 0). You might also design logic to handle specific,
anticipated FEEDBACK= variable values.