Processing VSAM Data Sets in SAS Programs |
Generating PROC PRINT Listings from a KSDS |
This example generates the following PRINT procedure listings:
The following example is based on the data set described in Sample STUDENT Data Set. The example can generate PROC PRINT listings:/* This DATA step reads all of the records from a KSDS */ /* using sequential access. */ data test; infile myksds vsam; input id $9. lastname $10. frstname $10. address $25. city $15. state $2. zip $5. balance $5. gpa $4. class $2. hrs $2. finaid $1.; run; /* Generate a listing of all the records of a KSDS. */ proc print data=test; run; /* This DATA step subsets the keys to every third key. */ data keys; infile myksds vsam keypos=kpos keylen=klen; input @kpos key $varying200. klen; if mod(_n_,3)=0 then output; /* This DATA step reads every third record from a */ /* KSDS using keyed access. */ data test; set keys; infile myksds vsam key=key; input id $9. lastname $10. frstname $10. address $25. city $15. state $2. zip $5. balance $5. gpa $4. class $2. hrs $2. finaid $1.; run; /* Generate a listing of the subset of keys. */ proc print data=keys; /* Generate a listing of the subset of KSDS records. */ proc print data=test; run;
Generating Reports Using PROC MEANS |
The following example reads all of the records from the KSDS, creates a numeric variable containing the students' GPA, and generates the following reports by using the MEANS procedure:
The data must be sorted by the variable that is used in the BY statement of PROC MEANS before you run PROC MEANS. The following example is based on the data set described in Sample STUDENT Data Set.
/* This DATA step reads all of the records from the KSDS and */ /* generates a numeric variable GPANUM from the character */ /* variable GPA using the input function. */ data test; infile myksds vsam; input id $9. lastname $10. frstname $10. address $25. city $15. state $2. zip $5. balance $5. gpa $4. class $2. hrs $2. finaid $1.; gpanum=input(gpa,4.2); run; proc means data=test; var gpanum; run; proc sort data=test; by class; run; proc means data=test; var gpanum; by class; run; proc sort data=test; by state; run; proc means data=test; var gpanum; by state; run;
Using a Windowing Program to Update VSAM Records |
The following program is an example of using SAS Component Language (SCL) to create a simple windowing application for updating VSAM records.
This application uses SCL to provide an interface to a VSAM KSDS. The data set consists of student records, keyed by the student's Social Security number (SSN). The application enables users to scroll through records using the NEXT and PREV buttons (or the forward and backward commands). You can also retrieve a record with a specific key by entering a Social Security number and selecting the RETRIEVE button. After a record is displayed, any desired changes can be made to the values in the window, and the record is updated by selecting the CHANGE button. A new record can be added by entering new values for all fields in the window and selecting the ADD button.
The application uses the following algorithm:
Create a SAS data set by reading records from the VSAM KSDS.
Perform the appropriate action when the user selects a button.
The purpose of this application is to illustrate how SCL can be used to create an interactive interface to the records in a VSAM data set. In the interest of clarity of the code, this application does little error checking:
INIT: /* Set the VSAMLOAD and VSAMUPDATE SAS options. */ /* Assign a fileref to the VSAM data set. */ /* Read records into a SAS data set from a VSAM KSDS. */ /* Deallocate the fileref. */ /* Open the SAS data set for processing. */ control asis; error=0; submit continue STATUS; option vsamload vsamupdate; filename myksds 'dsname.ksds.student' disp=shr; data stdrecs; infile myksds vsam; input id $9. lastname $10. frstname $10. address $25. city $15. state $2. zip $5. balance $5. gpa $4. class $2. hrs $2. finaid $1.; run; filename myksds clear; endsubmit; dsid=open('work.stdrecs','u'); prevrec=0; nextrec=2; rc=fetchobs(dsid,1); link readval; return; MAIN: /* Determine what the user wants to do, and perform */ /* the appropriate action. */ /* length cmd $ 10 idnum $ 9; */ length cmd $ 10; cmd=''; put 'in MAIN - cmd = ' cmd; call notify('RETRIEVE','_getText',cmd); if (cmd = 'RETRIEVE') then do; put cmd=; link retrieve; return; end; call notify('CHANGE','_getText',cmd); if (cmd = 'CHANGE') then do; put cmd=; link change; return; end; call notify('ADD','_getText',cmd); if (cmd = 'ADD') then do; put cmd=; link add; return; end; /* call notify('NEXT','_getText',cmd); */ if (cmd = 'NEXT') then do; put cmd=; /* link next; */ return; end; call notify('PREV','_getText',cmd); if (cmd = 'PREV') then do; put cmd=; link prev; return; end; call notify('QUIT','_getText',cmd); if (cmd = 'QUIT') then do; put cmd=; goto term; return; end; cmd=''; return; TERM: /* Close the SAS data set. Sort the SAS data set by the */ /* variable holding the VSAM key value. Delete the old */ /* VSAM data set. Create a new VSAM data set to hold */ /* the updated records. (Note: The method used here */ /* (building a SAS macro to be submitted to the operating */ /* system command processor) only works on the z/OS operating */ /* system.) Assign a fileref to the newly created VSAM data */ /* set. Write the records from the SAS data set to the VSAM */ /* data set. Deallocate the fileref. */ call close(dsid); submit terminate; proc sort data=work.stdrecs; by id; run; x "delete ('dsname.ksds.student') purge cluster"; %let mac=%str(define cluster %(name('dsname.ksds.student') ) ; %let mac=%mac %str(records(10 5) ); %let mac=&mac %str(recsz(90 90) ); %let mac=&mac %str(shareoptions(2,3) ); %let mac=&mac %str(reuse ); %let mac=&mac %str(volumes(APP004) ); %let mac=&mac %str(cisz(2048) ); %let mac=%mac %str(keys(9 0)%) ); %let mac=&mac %str(data ); %let mac=&mac %str(%(name('dsname.ksds.student.data') ); %let mac=&mac %str(cisz(2048)%) ); %let mac=&mac %str(index ); %let mac=&mac %str(%(name('dsname.ksds.student.index') ); %let mac=&mac %str(cisz(512)%) ); /* Submit the macro variable for execution. */ %sysexec &mac; filename myksds 'dsname.ksds.student' disp=shr; data _null_; set work.stdrecs; file myksds vsam reset; /* Write the data from the variables in the SAS data set to */ /* the appropriate column in the current record of the KSDS. */ if id ^= ' ' then do; put @1 id $9. /* Student's Social Security number */ @10 lastname $10. /* Student's surname */ @20 frstname $10. /* Student's given name */ @30 address $25. /* Permanent mailing address */ @55 city $15. /* City of residence */ @70 state $2. /* State of residence */ @72 zip $5. /* Five-digit ZIP code */ @77 balance $5. /* Balance from previous semester */ @82 gpa $4. /* Grade point average on a4.00 scale */ @86 class $2. /* FR, SO, JU, SE, or GR */ @88 hrs $2. /* Hours registered for in next semester */ @90 finaid $1.; /* Financial aid eligibility, Y or N */ end; run; filename myksds clear; endsubmit; return; RETRIEVE: /* Use a WHERE clause to subset the data set to contain only */ /* the record associated with the requested ID number. If */ /* there is an observation left in the data set, display its */ /* values. If there are no observations left in the data set, */ /* blank out any values in fields other than idnum and notify */ /* the user that there was no match found. */ clause="id='"||idnum||"'"; rc=where(dsid,clause); rc=fetchobs(dsid,1); if rc=0 then link readval; else do; link blanks; _msg_='No matching record found.'; end; return; CHANGE: /* Update the values in the current observation. */ link writeval; if error then error=0; else rc=update(dsid); return; ADD: /* Check to see if a record with that SSN already exists. If */ /* so, notify the user. Else add a new observation to the */ /* data set and update its variables. */ clause="id='"||idnum||"'"; put clause=; rc=where(dsid,clause); put rc=; rc=fetchobs(dsid,1); put rc=; if rc=0 then do; _msg_='A record with that key already exists.'; _msg_='No duplicates allowed'; end ; else do; rc=append(dsid); link writeval; end; if error then error=0; else rc=update(dsid); return; NEXT: put 'next - nextrec = ' nextrec; put 'next - prevrec = ' prevrec; rc=fetchobs(dsid,nextrec); put rc=; if rc=0 then do; prevrec=prevrec+1; nextrec=nextrec+1; link readval; end; else _msg_='NOTE: At bottom.'; return; PREV: put 'prev - nextrec = ' nextrec; put 'prev - prevrec = ' prevrec; if prevrec>0 then do; rc=fetchobs(dsid,prevrec); put rc=; if rc=0 then do; prevrec=prevrec-1; nextrec=nextrec-1; link readval; end; else _msg_='NOTE: At top.'; end; else _msg_='NOTE: At top.'; return; BLANKS: /* Blank out all values on the screen. */ idnum =''; lname =''; fname =''; address= ''; city =''; s =''; zip =''; bal =''; gpa =''; c =''; h =''; fa =''; return; READVAL: /* Assign the screen variables the values contained in the */ /* current observation. */ idnum =getvarc(dsid,1); lname =getvarc(dsid,2); fname =getvarc(dsid,3); address= getvarc(dsid,4); city =getvarc(dsid,5); s =getvarc(dsid,6); zip =getvarc(dsid,7); bal =put(input(getvarc(dsid,8),5.),dollar10.2); gpa =getvarc(dsid,9); c =getvarc(dsid,10); h =getvarc(dsid,11); if getvarc(dsid,12)='Y' then fa='Yes'; else fa='No'; return; WRITEVAL: /* Write the values contained in the screen variables to the */ /* variables in the current observation. */ length tempbal $ 10; call putvarc(dsid,1,idnum); call putvarc(dsid,2,lname); call putvarc(dsid,3,fname); call putvarc(dsid,4,address); call putvarc(dsid,5,city); call putvarc(dsid,6,s); call putvarc(dsid,7,zip); tempbal=substr(bal,2); pos=index(tempbal,','); if pos>0 then tempbal=substr(tempbal,1,pos-1)||substr(tempbal,pos+1); tempbal=substr(tempbal,1,index(tempbal,'.')-1); call putvarc(dsid,8,tempbal); call putvarc(dsid,9,gpa); call putvarc(dsid,10,c); call putvarc(dsid,11,h); temp=upcase(substr(fa,1,1)); if (temp='Y') | (temp='N') then call putvarc(dsid,12,temp); else do; _msg_='Invalid value for Financial Aid Eligibility,(Yes or No)'; error=1; end; return;
The output for the example creates the following window:
Result of SCL Windowing Program
Copyright © 2008 by SAS Institute Inc., Cary, NC, USA. All rights reserved.