<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Using data step functions to query identities in metadata in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194755#M36619</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I asked the following question on SAS Professionals so if you've seen it there please disregard.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I'm trying to write some code, using the metadata data step functions, which will query specified identities metadata. Where an identity is a group, I then want it to get the members of that group, and then do that recursively until it is down to persons only. I can't think of a way of writing recursive code in a data step so I thought I'd try using macro code. However, the metadata functions don't seem to work with %sysfunc. This is demonstrated by this log extract:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;&lt;SPAN style="font-family: courier new,courier;"&gt;15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %let rc=%sysfunc(metadata_getattr(&amp;amp;identuri,Name,ident_name));&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new,courier;"&gt;16&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put identuri=&amp;amp;identuri rc=&amp;amp;rc ident_name=&amp;amp;ident_name;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new,courier;"&gt;WARNING: Apparent symbolic reference IDENT_NAME not resolved.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new,courier;"&gt;identuri=OMSOBJ:IdentityGroup\A54UQ8A9.A300005Q rc=0 ident_name=&amp;amp;ident_name&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The ident_name macro variable never gets defined because it's not the function's return code, but one of the function's arguments.&lt;/P&gt;&lt;P&gt;Can anyone suggest a way around this, or an alternative method? I don't know if it would be possible with PROC METADATA. I've never really got to grips with the XML for querying the metadata.&lt;/P&gt;&lt;P&gt;Thanks&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Thu, 28 May 2015 09:34:10 GMT</pubDate>
    <dc:creator>Nigel_Pain</dc:creator>
    <dc:date>2015-05-28T09:34:10Z</dc:date>
    <item>
      <title>Using data step functions to query identities in metadata</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194755#M36619</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I asked the following question on SAS Professionals so if you've seen it there please disregard.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I'm trying to write some code, using the metadata data step functions, which will query specified identities metadata. Where an identity is a group, I then want it to get the members of that group, and then do that recursively until it is down to persons only. I can't think of a way of writing recursive code in a data step so I thought I'd try using macro code. However, the metadata functions don't seem to work with %sysfunc. This is demonstrated by this log extract:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;&lt;SPAN style="font-family: courier new,courier;"&gt;15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %let rc=%sysfunc(metadata_getattr(&amp;amp;identuri,Name,ident_name));&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new,courier;"&gt;16&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put identuri=&amp;amp;identuri rc=&amp;amp;rc ident_name=&amp;amp;ident_name;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new,courier;"&gt;WARNING: Apparent symbolic reference IDENT_NAME not resolved.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: courier new,courier;"&gt;identuri=OMSOBJ:IdentityGroup\A54UQ8A9.A300005Q rc=0 ident_name=&amp;amp;ident_name&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The ident_name macro variable never gets defined because it's not the function's return code, but one of the function's arguments.&lt;/P&gt;&lt;P&gt;Can anyone suggest a way around this, or an alternative method? I don't know if it would be possible with PROC METADATA. I've never really got to grips with the XML for querying the metadata.&lt;/P&gt;&lt;P&gt;Thanks&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 28 May 2015 09:34:10 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194755#M36619</guid>
      <dc:creator>Nigel_Pain</dc:creator>
      <dc:date>2015-05-28T09:34:10Z</dc:date>
    </item>
    <item>
      <title>Re: Using data step functions to query identities in metadata</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194756#M36620</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;How about this:&lt;/P&gt;&lt;P&gt;Write a data step that works through a dataset containing metadata objects and expands all objects of type "group" into their members. At the end, the data step should use call symput to create a macro variable that signals if any "group" type records were found.&lt;/P&gt;&lt;P&gt;Then use a macro that repeats that datastep with a %do %while loop until the dataset has been stripped of all "group" records.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%macro do_it;&lt;/P&gt;&lt;P&gt;%let signal = 1;&lt;/P&gt;&lt;P&gt;%do %while &amp;amp;signal = 1;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data dataset (drop=signal);&lt;/P&gt;&lt;P&gt;set dataset end=done;&lt;/P&gt;&lt;P&gt;retain signal 0;&lt;/P&gt;&lt;P&gt;if type = "group"&lt;/P&gt;&lt;P&gt;then do;&lt;/P&gt;&lt;P&gt;&amp;nbsp; /* get members and write a record for each */&lt;/P&gt;&lt;P&gt;&amp;nbsp; signal = 1;&lt;/P&gt;&lt;P&gt;end;&lt;/P&gt;&lt;P&gt;else output;&lt;/P&gt;&lt;P&gt;if done then call symput('signal',put(signal,1.));&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;%end;&lt;/P&gt;&lt;P&gt;%mend;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 28 May 2015 10:40:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194756#M36620</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2015-05-28T10:40:44Z</dc:date>
    </item>
    <item>
      <title>Re: Using data step functions to query identities in metadata</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194757#M36621</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thanks Kurt, that looks like a method I can work with. Trust me to try and get too complicated.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 28 May 2015 12:34:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194757#M36621</guid>
      <dc:creator>Nigel_Pain</dc:creator>
      <dc:date>2015-05-28T12:34:56Z</dc:date>
    </item>
    <item>
      <title>Re: Using data step functions to query identities in metadata</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194758#M36622</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Nigel&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;You could package the METADATA_... functions using&lt;A href="http://support.sas.com/documentation/cdl/en/proc/67327/HTML/default/viewer.htm#p0urpv7yyzylqsn1g2fycva2bs3n.htm"&gt; Proc FCMP&lt;/A&gt;. This way it is possible to call your function from %SYSFUNC.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Find below a code sample that shows this.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;DIV style="font-family: Courier New; font-size: 11pt;"&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;STRONG style="color: #000080; background-color: #ffffff;"&gt;proc&lt;/STRONG&gt; &lt;STRONG style="color: #000080; background-color: #ffffff;"&gt;fcmp&lt;/STRONG&gt; &lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;outlib&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;=work.myfunctions.md;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;function&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; md_getMembers(uri $)&amp;nbsp; $ &lt;/SPAN&gt;&lt;STRONG style="color: #008080; background-color: #ffffff;"&gt;32767&lt;/STRONG&gt;; &lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;length&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; returnList $ &lt;/SPAN&gt;&lt;STRONG style="color: #008080; background-color: #ffffff;"&gt;32767&lt;/STRONG&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tempUri $ &lt;/SPAN&gt;&lt;STRONG style="color: #008080; background-color: #ffffff;"&gt;256&lt;/STRONG&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; memberName $ &lt;/SPAN&gt;&lt;STRONG style="color: #008080; background-color: #ffffff;"&gt;256&lt;/STRONG&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; memberType $ &lt;/SPAN&gt;&lt;STRONG style="color: #008080; background-color: #ffffff;"&gt;256&lt;/STRONG&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; n=&lt;/SPAN&gt;&lt;STRONG style="color: #008080; background-color: #ffffff;"&gt;1&lt;/STRONG&gt;; &lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nMem = metadata_getnasn(uri, &lt;/SPAN&gt;&lt;SPAN style="color: #800080; background-color: #ffffff;"&gt;"MemberIdentities"&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;, n, tempURI);&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;do&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; i_mem = &lt;/SPAN&gt;&lt;STRONG style="color: #008080; background-color: #ffffff;"&gt;1&lt;/STRONG&gt; &lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;to&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; nMem;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rc = metadata_getnasn(uri, &lt;/SPAN&gt;&lt;SPAN style="color: #800080; background-color: #ffffff;"&gt;"MemberIdentities"&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;, i_mem, tempURI);&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rc = metadata_getattr(tempURI, &lt;/SPAN&gt;&lt;SPAN style="color: #800080; background-color: #ffffff;"&gt;"Name"&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;, memberName);&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rc = metadata_getattr(tempURI, &lt;/SPAN&gt;&lt;SPAN style="color: #800080; background-color: #ffffff;"&gt;"PublicType"&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;, memberType);&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; returnList = catx(&lt;/SPAN&gt;&lt;SPAN style="color: #800080; background-color: #ffffff;"&gt;"!"&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;, returnList, memberName);&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #008000; background-color: #ffffff;"&gt;* put i_mem= tempURI= memberName= memberType=;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;end&lt;/SPAN&gt;; &lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;return&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; (returnList);&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;endsub&lt;/SPAN&gt;; &lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;STRONG style="color: #000080; background-color: #ffffff;"&gt;run&lt;/STRONG&gt;; &lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;options&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;cmplib&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;=work.myfunctions&lt;BR /&gt;;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;%let&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; memberList = &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;%sysfunc&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;( md_getMembers(OMSOBJ:IdentityGroup\A5GOWNJA.A50000S0) );&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;%put&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; NOTE: &amp;amp;=memberList;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 28 May 2015 13:26:13 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194758#M36622</guid>
      <dc:creator>BrunoMueller</dc:creator>
      <dc:date>2015-05-28T13:26:13Z</dc:date>
    </item>
    <item>
      <title>Re: Using data step functions to query identities in metadata</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194759#M36623</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thanks Bruno. I've never used PROC FCMP before. I'll have to have a read up on it.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 28 May 2015 14:49:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-data-step-functions-to-query-identities-in-metadata/m-p/194759#M36623</guid>
      <dc:creator>Nigel_Pain</dc:creator>
      <dc:date>2015-05-28T14:49:43Z</dc:date>
    </item>
  </channel>
</rss>

