| Shared Appendix 9: Exits for the Process Task -- Generic Collector Specifics and MVS Specifics | |
Index to Topics in this File:
Contents of this File:
Note: For each exit point mentioned in this table, the information in the table is designed to be read in conjunction with the exit point's position in the sample code that follows the table.
Note: In this table, "open" means not in the middle of a statement, DATA step, or PROC step.
Exit Exit Placement Purpose Frequency Number in Point of Code Name Execution Example
#1 proc005 The very Enables any Once per
first initial process
exit one-time run.
point. open code
This is processing.
before
the %LET
CPTABLE
statement
but after
the %LET
CPTABLES=
statement.
#2 proc010 Directly Enables Once per
before setting of table.
the first options
DATA and
step. unconditional
pre-
processing
before the
final
staging.
#3 proc015 Directly Enables the Once per
after the user to table.
KEEP= specify
list for data set
the options.
output
staged
data set.
#4 proc020 Directly Enables the Once per
before the user to table.
closing ; add his/her
in the DATA own output
statement. data set.
#5 proc025 Directly Enables Once per
after the user- observation.
ATTRIB specified
statement attributes
in the and open
first DATA step
DATA code.
step.
#6 proc030 Directly Enables Once per
before user to observation.
the override
closing ) data set
of the options.
data set
OPTIONS
clause in
the SET
statement
for the
staged
data set.
#7 proc035 Directly Enables Once per
after the user to observation.
closing ) specify
of the additional
data set data sets
OPTIONS for SET
clause in processing.
the SET
statement
for the
staged
data set.
#8 proc040 Directly Open DATA Once per
after the SET step code observation.
statement point for
in the user.
first
DATA
step.
#9 proc045 Directly Enables user Once per
before to handle observation
the observations that has a
DELETE that have missing
statement missing DATETIME
for DATETIME value.
observations values
that have
missing
DATETIME
values in
the first
DATA
step.
#10 proc050 Directly Enables Once per
after the user to observation.
HOUR override the
variable setting of
has been HOUR.
set in
the first
DATA
step.
#11 proc055 Directly Enables Once per
after user to observation
LSTPDATE override in which
has been setting of LSTPDATE
set to LSTPDATE. had a
the missing
current LSTPDATE
datetime value.
stamp in
the first
DATA step,
if
LSTPDATE
is
currently
missing.
#12 proc060 Directly Open DATA Once per
before the step code observation.
SHIFT point for
variable user.
calculations
begin.
#13 proc065 Directly Enables Once per
after the user to observation
SHIFT override that has a
variable the shift blank
has been set matrix. SHIFT variable
using the value.
shift matrix.
This
happens
only if
the SHIFT
variable
is not
set in
the
staged
data set.
#14 proc070 After the Enables Once per
SHIFT user to observation.
variable override
value has the SHIFT
been set, variable
regardless value,
of whether prior to
it was set calculation
in the using
staged the
data set. Holiday
This List.
occurs
before
the
Holiday
List.
#15 proc075 After the Enables Once per
SHIFT user to observation
value has SHIFT that has been
been set, variable set by the
if the date value, if Holiday
matches an set by the List.
entry in the Holiday
Holiday List.
List.
#16 proc077 Inside the Enables you Once
IF _LAST to perform per
clause, any final table.
directly actions in
before the staging
the macro view DATA
variable step.
CPLDATM is
populated,
with the
latest value
of DATETIME
in the
incoming
data.
#17 proc080 Directly Final open Once per
before DATA step observation.
the code point
OUTPUT available
statement before the
for the observation
staged is
data set written to
/ DATA the staged
step view data set /
in the DATA step
first view.
DATA
step.
#18 proc085 Directly Enables Once per
after the user observation.
OUTPUT OUTPUT
statement statements
for the and open
staged DATA step
data set code.
/ DATA
step view
in the
first
DATA
step.
#19 proc090 Directly Enables Once per
before pre-sort table.
the PROC processing
SORT of of the
the staged
staged data.
data.
#20 proc095 Directly Enables Once per
before user to table.
the NODUP specify
clause of additional
the PROC sort
SORT options.
statement
for the
staged
data.
#21 proc097 Directly Enables Once per
before user to table.
the BY override
statment of the default
the PROC BY list for
SORT the sort of
statement the staged
for the data.
staged
data.
#22 proc100 Directly Enables Once per
after the post-sort table.
RUN statement processing
for the of the
PROC SORT staged
of the data.
staged
data.
#23 proc105 Directly This exit Once per
after the is only table, if
PROC SORT invoked if detail
of the the detail data is
staged data set not going
data, if is not to be
there is being sorted.
no PROC sorted.
SORT of
the
detail
data.
#24 proc110 Directly This exit Once per
after the is only table, if
PROC SORT invoked if detail
of the the detail data is
staged data set going to
data, if is being be sorted.
there is sorted.
a PROC Allows
SORT of pre-sort
the code
detail for
data. detail.
#25 proc115 Directly Enables Once per
before the user to table.
closing ; in specify
the PROC additional
SORT sort
statement options.
for the
detail
data.
#26 proc120 Directly This exit Once per
after the is invoked table, if
PROC SORT only if detail
of the the detail- data was
detail level data sorted.
data, if set was
there is sorted.
a PROC Allows
SORT of post-sort
the code
detail for
data. detail.
#27 proc125 Directly Enables Once per
before setting of table.
the "merge" options
DATA and open
step. DATA step
code prior
to the
merge of
the DETAIL
and staged
data.
#28 proc130 Directly Enables the Once per
before user to table.
the override
closing ) data set
on the options.
data set
options
for the
DETAIL
data set.
#29 proc135 Directly Enables the Once per
before the user to table.
closing ; in add his/her
the DATA own output
statement. data set.
#30 proc140 Directly Enables Once,
before first-pass during the
the END -only first pass
statement code. of the
in the IF DATA step.
_N_=1
block.
#31 proc145 Directly Enables Once per
after the user- observation.
last specified
ATTRIB attributes
statement and open
in the DATA step
"merge" code.
DATA
step, and
before
the SET
statement
for the
detail
and
staged
data
sets.
#32 proc150 Directly Enables Once per
after the user to observation.
datetime override/
(age limit extend
trimming) age limit
value in trimming.
the WHERE
clause
for
detail.
#33 proc155 Directly Enables Once per
before user to observation.
the override
closing ) data set
in options.
the data
set
OPTIONS
statement
in the
SET
statement
for the
detail
data set.
#34 proc160 Directly Enables Once per
before the user to observation.
closing ) in override
the data set
the data options.
set
OPTIONS
statement
in the
SET
statement
for the
staged
data set.
#35 proc165 Directly Enables Once per
after the user to observation.
SET include
clause his/her own
for the data set
staged in the SET
data. data sets
for BY
(merge)
processing.
#36 proc170 Before Enables the Once per
the user to observation.
closing ; override
in the or add SET
SET options.
statement.
#37 proc175 After the Open code Once per
BY point. observation.
statement. This is
the
recommended
exit
point to
use for
deleting
observations.
#38 proc180 Duplicate Enables user Once
BY variable to handle per
observation observations observation
encountered. that have encountered
duplicate with
BY- duplicate
variable BY variable
values. values.
#39 proc185 Earlier Enables user Once per
datetime code to be observation
encountered. executed that has
. each time an
a new earlier
(earliest) datetime
datetime stamp than
stamp is any
found in previous
the DATA observations.
step. The
earliest
datetime
stamp
value is
stored in
the
variable
_oet .
#40 proc190 Later Enables user Once per
datetime code to be observation
encountered. executed that has
each time a
a new later
(latest) datetime
datetime stamp than
stamp is any
found in previous
the DATA observations.
step. The
latest
datetime
stamp
value is
stored in the
variable
_olt .
#41 proc195 When the Enables user Once per
observation code to be observation
is executed read
found each time from the
to have an output detail-level
come from observation data set.
the is
detail-level found
data set. to have
come from
the detail
data set.
A count of
these
observations
is
accumulated
in the
variable
_oldobs .
#42 proc200 When the Enables user Once per
observation code to be observation
is executed read
found each time from the
to have an output staged
come from observation data set.
the new is
(staged) found
data set. to have
come from
the new
(staged)
data set.
A count of
these
observations
is
accumulated
in the
variable
_addobs .
#43 proc205 Directly Enables the Once per
before user to observation.
the modify the
OUTPUT observation
statement before it
in the is finally
"merge" written to
DATA the detail
step. level.
#44 proc210 Directly Enables the Once per
after the OUTPUT observation.
OUTPUT statements
statement for any
in the user-created
"merge" data
DATA sets.
step.
#45 proc215 After Enables Once per
duplicate user to table, if
warning perform any
message his/her own observations
has been end-of- have
issued. table been
duplicate determined
reporting. to have
This exit duplicate
is called BY variable
only values.
when
observations
have
been
found that
have
duplicate
BY variable
values.
#46 proc220 After Enables the Once per
symbol user to table, on
values perform the last
have been end-of- pass of
set for table the DATA
end-of- reporting. step.
table
reporting.
#47 proc225 After the Open DATA Once per
RUN step code table.
statement point to
in the allow the
"merge" user to
DATA work with
step. the new
merged
data,
and/or any
user data
sets that
may have
been
created.
#48 proc230 After Enables Once per
processing return- run of
has code setting, process.
been or other
completed final
for all operations.
tables.
The following is an example of the code submitted by the process step when the value of the COLLECTOR= parameter on the %CxPROCES macro is set to the generic collector. The location of an exit point is indicated by #n, where n is the number of the item in the above table.
/* list of global macro variables that are needed */
%GLOBAL CPCUTDT CPTABLES CPTABLE CPBYVAR CPVWNM;
%GLOBAL CPARCTBS CPARCTB;
%GLOBAL CPTOTOBS CPADDOBS CPOLDOBS CPDUPOBS CPEDATM CPLDATM ;
%LET CPVWNM = WORK.EJLDPCV; /* unique name per process run */
%LET CPTABLES = XDCVOLS XDCDSET ;
%LET CPARCTBS = ; /* list of tables to archive while processed */
#1
/* name of table to process */
%LET CPTABLE = XDCVOLS;
%LET CPARCTB = N; /* Archive this table? Y or N */
/* list of BY variables for this table */
%LET CPBYVAR = MACHINE DCVSGTC DCVVOLS DCVDVNU DATETIME ;
#2
/************************************************************/
/* Data step view created from the staged data. This is */
/* to add and set variables, such as SHIFT, HOUR, and */
/* DATETIME, that will be needed for sorting. The */
/* bizarre-looking name for the view is generated as a */
/* unique name, to avoid any sort of namespace conflict. */
/************************************************************/
data WORK.EJLDPCV(keep=
DCUTMSTP
. . .
ZDATE
#3 ) #4 /view=WORK.EJLDPCV; /* Output: TEMP View */
/* Assign labels to the BY-variables. This forces the */
/* variables used for sorting to the first-most portion */
/* of each observation for improved sort efficiency. */
attrib MACHINE label='Machine';
attrib DCVSGTC label='Storage Class';
attrib DCVVOLS label='Volume Label';
attrib DCVDVNU label='Unit number';
attrib DATETIME label='Datetime';
attrib shift length=$1
_odate format=date9.
_hshift length=$1
_charval length=$10 ;
#5
set GENLIB.DCOLVOLS(in=_new
rename=(
DCUTMSTP = DATETIME
. . .
DCUSYSID = MACHINE
)
#6) #7 end=_last;
#8
retain _odate _hshift ;
if datetime=. then do ;
put 'WARNING: Invalid value for DATETIME on obs '_n_ ' ,obs deleted.' ;
put 'NOTE: Data for obs. '_n_ ' follows:' ;
put _all_;
#9
if _last then _dellast = 1;
else delete;
end ;
hour = hour(datetime) ;
#10
if lstpdate = . then do;
lstpdate = '22MAR1999:13:42:22.15'dt ;
#11
end;
#12
/* if shift not set in input data make it now */
if shift = ' ' then do ;
_date = datepart(datetime) ;
shift = substr("&cpshift",
((weekday(_date)-1)*24+
hour(datetime)+1),1) ;
#13
end ;
#14
if _odate ^= _date then do ;
_charval=put(_date,CPHDAY.) ;
if _charval ^= ' ' then do;
_hshift = put(0,CPHDAY.) ;
end;
else do;
_hshift = ' ' ;
end;
end ;
if _hshift ^= ' ' then do;
shift = _hshift ;
#15
end;
_odate = _date;
if datetime > _olt or _olt = . and not(_dellast) then
_olt = datetime;
if _last then do;
#16
call symput('cpldatm',put(_olt,best32.2));
if _dellast then delete;
end;
#17
output WORK.EJLDPCFV;
#18
run;
/************************************************************/
/* PROC SORT of the staged data by the BY variables. This */
/* prepares the data to be "merged" with the detail-level */
/* data set. Here the view is sorted out into a real data */
/* set in the WORK library; again the data set has a */
/* unique name. */
/************************************************************/
#19
proc sort
data=WORK.EJLDPCFV /* Input: VIEW DS */
out=WORK.EJLDPCFC /* Output: WORK DS */
#20
nodup ; /* eliminate duplicates from new data */
#21
by
MACHINE DCVSGTC DCVVOLS DCVDVNU DATETIME ;
run ;
/************************************************************/
/* If the BY-variable list has changed since the last */
/* run of the process macro, then you would see a PROC */
/* SORT of the detail-level data set onto itself, sorted */
/* by the current list of BY variables. */
/************************************************************/
#22
#23 /* only if there is no PROC SORT of detail level */
#24 /* only if there is a PROC SORT of detail level */
/************************************************************/
/* For illustration purposes, the sort of the DETAIL level */
/* is shown. This code would be generated and submitted */
/* only if the DETAIL-level data set required sorting. */
/************************************************************/
proc sort
data=DETAIL.XDCVOLSD /* Input/Output: DETAIL DS */
#25
;
by
MACHINE DCVSGTC DCVVOLS DCVDVNU DATETIME ;
run ;
#26 /* only if there was a PROC SORT of detail level */
/************************************************************/
/* DATA step that does a SET-BY ("merge") of the new data */
/* with the current detail-level data set, storing the */
/* output into the detail-level data set. SET statement */
/* age limit trimming is performed only on the detail- */
/* level data set, so that new data can be reduced before */
/* the data are aged out of detail level. Also, */
/* statistics are accumulated for the running of the */
/* process macro on the data in this table. */
/************************************************************/
#27
data DETAIL.XDCVOLSD /* Output: DETAIL */
(compress=yes
keep=
DATETIME
. . .
ZDATE
sortedby=
MACHINE DCVSGTC DCVVOLS DCVDVNU DATETIME
#28 ) #29 ;
/* Assign attributes to the BY-variables. This forces the */
/* variables used for merging to the first-most portion of */
/* each observation for efficiency in later reporting and */
/* subsequent runs of process. */
attrib MACHINE label='Machine' length = $8;
format MACHINE; informat MACHINE;
. . .
attrib DATETIME label='Datetime' length = 8
format=DATETIME21.2;
informat DATETIME;
retain _totobs 0 ;
retain _oldobs 0 ;
retain _addobs 0 ;
retain _dups 0 ;
retain _oet . _olt . _oest ._olst .;
if _n_ = 1 then do ;
call symput('cpsedatm','0') ;
call symput('cpsldatm','0') ;
call symput('cpedatm','0') ;
call symput('cpldatm','0') ;
call symput('cptotobs','0') ;
call symput('cpoldobs','0') ;
call symput('cpaddobs','0') ;
call symput('cpdupobs','0') ;
#30
end ;
#31
/* Concatenate DETAIL and NEW and select DETAIL */
/* data with dates newer than 12MAR1999:16:32:41.78 (Age= 10 days) */
%let CPCUTDT = '12MAR1999:16:32:41.78'dt ;
set DETAIL.XDCVOLSD (in=_detail
where=(datetime>'12MAR1999:16:32:41.78'dt
#32) #33)
WORK.EJLDPCFC (in=_new #34) #35
end=_last #36 ;
by
MACHINE DCVSGTC DCVVOLS DCVDVNU DATETIME ;
#37
/* count and keep duplicate obs. */
if not first.DATETIME then do;
#38
_dups = _dups + 1 ;
end;
if _oet= . or datetime < _oet then do;
#39
_oet = datetime ;
end ;
if _olt= . or datetime > _olt then do;
#40
_olt = datetime ;
end ;
if _detail then do;
#41
_oldobs = _oldobs + 1 ;
end;
else if _new then do;
#42
_addobs = _addobs + 1 ;
if _olst= . or datetime > _olst then do;
_olst = datetime ;
end;
if _oest= . or datetime < _oest then do;
_oest = datetime ;
end;
end;
#43
output DETAIL.XDCVOLSD;
_totobs = _totobs + 1;
#44
if _last then do;
/* notify number of duplicates */
if _dups > 0 then do;
put 'WARNING: Table XDCVOLS has ' _dups
' duplicate observations by key.' ;
#45
end;
call symput('cpldatm',put(_olt,best32.2)) ;
call symput('cpedatm',put(_oet,best32.2)) ;
call symput('cpsldatm',put(_olst,best32.2)) ;
call symput('cpsedatm',put(_oest,best32.2)) ;
call symput('cptotobs',put(_totobs,best32.)) ;
call symput('cpdupobs',put(_dups,best32.)) ;
call symput('cpaddobs',put(_addobs,best32.)) ;
call symput('cpoldobs',put(_oldobs,best32.)) ;
#46
end ;
run ;
#47 /* per-table basis */
data _null_; run; /* just to keep things clean */
#48 /* only once per-process run */
data _null_; run; /* just to keep things clean */