06-09-2016 04:52 AM
I'm looking for a procedure which provides to show who viewed the data set lastly. For example; I have a library such as sashelp and I have a data set such as class, I want to see who viewed this table last, which user.
Can somebody help me about this case, please?
06-09-2016 05:09 AM
There is nothing in standard SAS for what you want. I believe (though don't know first hand) that other packages - Metadata integration and such like may have this additional component. Generally speaking most users only want to find out who changed something, what and when, so use version control systems for this. Am not sure what methodology you would use to check viewing of data, maybe hold data away from normal user access and set it as a request pull system?
06-09-2016 05:15 AM
If you need to do this for security/privacy/legal issues, the only thing that really works is the auditing subsystem of the operating system. All other means can be circumvented.
06-09-2016 05:20 AM
Thank you very much for your information.
Actually, in our environment, we have a job which includes sas programs when we execute this job via Unix, we sometimes get a LOCK error, so it means that some of the employees viewed this data set while program was creating the data set, I try to figure out who viewed this data set.
That is my actual question, can we figure out by using beyond any SAS procedures?
06-09-2016 05:25 AM
Ah, this is a general problem with accessing datasets. Only one processes can access a dataset at a time.
Am afraid I don't have any simple suggestions for you, perhaps having a dual system, production and development - so users can view and work on development, but not on production - which would only be there to run things routinely. I have seen various implmentations of this and it works pretty good. Users work in their own area or on a development branch with their own copies, and commit finalised items back to the main production. The production branch operates totally independant of that.
06-09-2016 05:45 AM
So if I add a kill code before the the code creates the data set, I won't face a LOCK error. Is it possible build similar structure in SAS?
For example, is there way to build similar to following structure?
/*Kill Code should be here for Have and Want*/ PROC SQL; Create Table Want As Select * From Have; QUIT; /*Kill Code should be here for Have2 and Want2*/ PROC SQL; Create Table Want2 As Select * From Have2; QUIT;
06-09-2016 06:05 AM
Whilst there is a command line task kill, I don't think that would be a good idea as you generally wouldn't have access to or know which system has the process active. A process change is simpler, if someone wants to view a dataset, have them copy it to an area outside the run environment. E.g.:
Then look at want in their own work area.
06-09-2016 06:24 AM
Thank you, but it is hard to tell whole employees to do this;
They can forget, I need to do it in background without involve the end user.
06-09-2016 06:19 AM
This is the macro I have created to remove a dataset in UNIX before the step that rewrites it:
%macro del_phys(tabname,tabtype); %local dp_dsid dp_libref dp_filename dp_pathname dp_type dp_suffix dp_rmcmd; %if "&sysrc" = "0" and "&syscc" = "0" %then %do; %if (%substr(&sysscp,1,3)=WIN) %then %let dp_rmcmd=del; %else %let dp_rmcmd=rm -f; %if "&tabtype" = "" %then %let tabtype=data; %if %sysfunc(exist(&tabname,&tabtype)) %then %do; %let dp_dsid=%sysfunc(open(&tabname)); %if (&dp_dsid = 0) %then %do; %put %sysfunc(sysmsg()); %end; %else %do; %let dp_type=%sysfunc(attrc(&dp_dsid,MTYPE)); %if (&dp_type = VIEW) %then %let dp_suffix=sas7bvew; %else %let dp_suffix=sas7bdat; %let dp_libref=%sysfunc(attrc(&dp_dsid,LIB)); %let dp_filename=%sysfunc(attrc(&dp_dsid,MEM)); %let dp_filename=%lowcase(&dp_filename); %let dp_dsid=%sysfunc(close(&dp_dsid)); %let dp_pathname=%sysfunc(pathname(&dp_libref,L)); %let dp_pathname=&dp_pathname./&dp_filename..&dp_suffix; filename oscmd pipe "&dp_rmcmd &dp_pathname 2>&1"; data _null_; infile oscmd; input; put _infile_; run; %put &dp_rmcmd &dp_pathname; %end; %end; %end; %else %do; %put "No removal because of exitcode SYsrc=&sysrc SYSCC=&syscc"; %end; %mend del_phys;
If something in the batch job went bad before that, the physical remove is not executed, and the previous version of the dataset (if present) is preserved.
06-09-2016 07:21 AM
Do you have SAS/Share licensed? It is intended to meet this need.
I have had good luck by making sure the users always use libraries created with the ACCESS=READONLY option. Thus they should not be placing locks on files just by reading them. This might not be enough and you might need to change the operating system access rights such that normal users cannot write to the file or the folder that it lives in.
06-09-2016 07:35 AM
I have to respectfully disagree.
SAS/SHARE does not allow a complete rewrite of a dataset, only updates.
And ACCESS=READONLY does not change the behaviour. If a user who assigned the library with ACCESS=READONLY keeps a file open in EG for viewing, any try to update the file from another process fails with the usual message. Just tested with SAS 9.2 on AIX and EG 4.3/6.1.
READONLY only prevents write access, but the file handle from the viewer is still there and blocks.
06-09-2016 11:43 AM
As far as I understand, observing the latest user who viewed table is not possible for end user. Well, how can we observe the user by using the server. Can SAS Admin determine the user?