adding a meta user to a meta group in sas - sas

I've around 600 meta users in SAS EGRC 6.1 in the platform in SAS 9.4.
I want to add those users to a meta-group. for this, I'm using code below
libname current '/tmp/temp1'; /* for the current metadata */
libname addgrps '/tmp/temp2'; /* current augmented with the changes */
libname updates '/tmp/temp3'; /* for the updates created by the mducmp macro */
options metaserver=abc
metaport=8561
metauser='sasadm#saspw'
metapass='xyz123'
metaprotocol=bridge
metarepository=foundation;
%mduextr(libref=current);
proc copy in = current out = addgrps;
/*copy the current data to the directory for the target */
run;
data investigators_1;
set current.person;
where name in ('5806036');
rename objid = memkeyid;
keep objid;
run;
data investigator_group_1;
set current.group_info;
where name='Enterprise GRC: Incident Investigation';
rename id = grpkeyid;
keep id;
run;
proc sql;
create table grpmems as
select * from investigators_1, investigator_group_1;
quit;
proc append base = addgrps.grpmems data = grpmems;
run;
/* use the mducmp macro to create the updates data */
%mducmp(master=addgrps, target=current, change=updates)
/* validate the change data sets */
%mduchgv(change=updates, target=current, temp=work, errorsds=work.mduchgverrors)
/* apply the updates */
%mduchgl(change=updates);
for the final updated I tried both %mduchgl and %mduchglb but with both, I'm not able to get the desired results. I test it with one user.
with %mduchgl I get the below error
The symbolic reference for A52PDIUF.$A52PDIUF.AP0000NI did not resolve.
with %mduchglb I get the below error
The object reference to Person was requested without an identifier.
Errors returned from Proc Metadata prevented objects from being Added, Updated, or Deleted. Table: work.mduchglb_failedobjs
identifies 1 such objects. Consult the SAS Log for the specific Metadata Server errors returned.
Any suggestions that how can I resolve the error or another approach that I should try to achieve this.
Thanks.

I don't think you should ever modify those datasets! Everything you need to achieve should be possible using proc metadata (or data step functions as last resort).
Here is a relevant SAS Communities thread. To summarise - the following snippet will add a group to a user, so long as you have the group / user URI:
<Person Id="A5NUQPXO.AP00002V">
<IdentityGroups>
<IdentityGroup ObjRef="A5NUQPXO.A500001C" />
</IdentityGroups>
</Person>
UPDATE - for completeness, I turned this into a macro, described here
https://core.sasjs.io/mm__adduser2group_8sas.html

Related

Append data or Replace based on column values in SAS

I'm trying to save the results from a forecast(dataset) into a historical dataset in SAS servers.
I already have the path of the historical dataset but what I'm trying to do here is to append the results if they don't exist or replace them if they already exist on the historical dataset.
Below is how the table that I want to append/replace looks:
:Agency
:Forecast_Week
:Date Fc
:SubAgency
:Value
New
12/26/22
12/27/22
One
3243262
New
12/26/22
12/28/22
One
3242355
New
12/26/22
12/29/22
Two
3225142
New
12/26/22
12/30/22
Two
3234235
So, if the records for the Agency, Forecast Week, Date, SubAgency already exists I want to replace them with the new values but if they don't exist in the historical dataset I want to append them.
Do you know how I can do this?
I did something very similar not that long ago:
proc sql;
create table temp as
select *
from table_old
where forecast_week NOT IN(select forecast_week from table_new)
;
quit;
/* Append the updated and new values */
data table_old;
set temp
table_new
;
run;
I hope this helps
I asked a similar question in this post maybe you can get some inspiration there:
SAS EG append new data and overwrite already existing rows

Referencing a macro variable created by a prompt SAS EG

I created a prompt in SAS EG that takes a text input and creates the macro variable called 'variableName'.
I am trying to reference this macro variable like so:
proc sql;
create table MyTable as
select * from Source_Table as a
where a.field = &variableName ;
This gives me an error that says: "Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant, a missing value, BTRIM, INPUT, PUT, SUBSTRING, USER."
I have also tried enclosing &variableName in single and double quotes but when I do that I just don't get any results.
I am able to reference the prompt when I use query builder and filter data based on the prompt, but I am trying to use the prompt's value in calculated expressions, etc. and in queries I write without query builder. How can i reference the variable I created in the prompt??
Edit: code with a value that the macro variable would have
proc sql;
create table MyTable as
select * from Source_Table as a
where a.field = 'NAME OF PERSON';
When I run that, I get the results I want.
It needs to resolve to valid SAS code. Assuming &variableName is a string, then it would be something like:
proc sql;
create table MyTable as
select * from Source_Table as a
where a.field = "&variableName." ;
If this isn't working, please show a query that does work with the same value as the macro variable would have. And then we can suggest how to change your code.
Edit: based on your comment you do not have the prompt connected to your query. Right click the query and link the prompt to your query and it will run before the query to provide the value.

SAS set statement using colon and creating a filename variable

So using SAS, I have a number of SAS monthend datasets named as follows:
mydata_201501
mydata_201602
mydata_201603
mydata_201604
mydata_201605
...
mydata_201612
Each has account information at particular monthend. I want to stack the datasets all into one dataset using colon rather than writing out the full set statement as follows:
data mynewdata;
set mydata_:;
run;
However there is no datestamp variable within the datasets so when I stack them I will lose the monthend information for each account. I want to know which line refers to which monthend for each account. Is there a way I can automatically create a variable that names the table the row come from. for example the long winded way would be this:
data mynewdata;
set mydata_201501 (in=a) mydata_201502 (in=b) mydata_201503 (in=c)...;
if a then tablename = 'mydata_201501';
if b then tablename = 'mydata_201502';
if c...
run;
but is there a quicker way using colon along these lines?
data mynewdata;
set mydata_:;
tablename = _tablelabel_;
run;
thanks
I always find clicking on comment links annoying, so hopefully here's the answer in your context. Use the INDSNAME= SET statement option to assign the dataset name to a variable:
data mynewdata;
set mydata_: indsname=_tablelabel_;
tablename = _tablelabel_;
run;
N.B. you can call _tablelabel_ whatever you want, and you may wish to change it so it doesn't look like a SAS generated variable name.
INDSNAME= only became a SAS SET statement option in version 9.2
Just to be clear, with my particular code, where the datasets were named mydata_yyyymm and I wanted a monthend variable with datestamp, I was able to produce this using the solution provided by mjsqu as follows (obs and keep statement provided if required):
data mynewdata;
set mydata_: (obs=100 keep=xxx xxx) indsname=_tablelabel_;
format monthend yymmdd10.;
monthend = input(scan(_tablelabel_,-1,'_'),yymmn6.);
run;

Use a macro variable to when saving to a permanent SAS data set

Trying to save data set Keepmerge as a permanent SAS data set called Oct15Tot using the code below. If I sub "&OutTabTot" for just Oct15Tot, it works. Trying to save myself from having to chang another bit of code further down (the %let is referenced at the beginning, and is used throughout my program. Thanks!
%let OutTabTot = Oct15Tot;
libname WorkItem "\\WRKGRP\CVOWB\SAS Data Sets";
data WorkItem."&OutTabTot";
set work.Keepmerge;
run;
Here's the error I'm getting:
22
201
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, /, ;,
_DATA_, _LAST_, _NULL_.
ERROR 201-322: The option is not recognized and will be ignored.
If you remove the quotes in your Data statement it should work, like so:
%let OutTabTot = Oct15Tot;
libname WorkItem "\\WRKGRP\CVOWB\SAS Data Sets";
Data WorkItem.&OutTabTot;
Set Work.Keepmerge;
Run;
In general, as cherry notes, you should just skip the quotations.
However, if you have reason to use quotations, you need to use an n afterwards to tell SAS to make this a name literal.
%let OutTabTot = Oct15 Tot;
options validmemname=extend;
libname WorkItem "\\WRKGRP\CVOWB\SAS Data Sets";
Data WorkItem."&OutTabTot"n;
Set Work.Keepmerge;
Run;
I don't recommend using things like dataset names with spaces if you can avoid it, as it's a pain... but it's legal, with options validmemname=extend set.

How can I write a DATA step that will drop all variables from the input dataset except the ones that I explicitly define within the dataset?

I want to generate a new SAS dataset using table foo as the input and one-to-one correspondence with records in the output dataset bar. I wand to drop variables from foo by default but I also require all of the fields of foo be available (to derive new variables) and also that some variables from foo to be kept (if explicitly indicated).
I'm currently managing an explicit list of variables to drop= but it results in long and unwieldy syntax in the data-set-option declaration.*
DATA bar (drop=id data_value2);
set foo;
new_id = id;
data_value1 = data_value1; /* Explicitly included for clarity */
new_derived_data_value = data_value2 * 2; /* etc. */
format new_id $fmt_id.
data_value1 $fmt_dat.
new_derived_data_value $fmt_ddat.
;
RUN;
The output table I want should have only fields data_value1, new_data and new_derived_data_value.
I'm looking for the most syntactically succinct way of reproducing the same effect as :
SELECT
id AS new_id
,data_value1
,data_value2 * 2 AS new_derived_data_value
FROM foo
How can I write a DATA step that will drop all variables from the input dataset except the ones that I explicitly define within the dataset?
* Update: I could use aaa--hhh type notatation but even this can be unwieldy if the ordering of the variables changes over time or I later decide I'd like to keep variable ddd.
I would store the variable names in a macro list, obtained from the DICTIONARY tables. You can then drop them all easily in a data step. e.g.
proc sql noprint;
select name into :vars separated by ' '
from dictionary.columns
where libname = 'SASHELP' and memname='CLASS';
quit;
data want (drop=&vars.);
set sashelp.class;
name1=name;
age1=age;
run;
Keith's solution is the best production solution, but a quick alternative assuming you know the first and last variables in the dataset:
data want;
set class;
drop name--weight;
name1=name;
age1=age;
run;