简体   繁体   中英

Executing PROC SOAP in a loop in SAS

Purpose of the code

  1. Read a list of numbers from a SAS Dataset
  2. Make a web-service call by substituting each number as a variable in the XML envelope
  3. Store the XML Response to a temporary/intermediate file
  4. Parse the above file to retrieve essential information (ie, Employee Name and Number) and create/append the dataset that ultimately provides associated employee information for each of the numbers from #1.

Code and Other information

Below code creates three sample numbers that need to be used sequentially to make the webservice call.

data cenis;
 infile datalines; 
input CENI 8.;
datalines;
13413745
12174391
8905899
;

The below code makes the webservice call for number (CENI) 13413745 and produces the output as shown in the snapshot.

filename request temp;
filename response "/mktg/prc203/abhee/output.txt";

data _null_;
   file request;
   input;
   put _infile_;
   datalines4;

<soapenv:Envelope xmlns:sch="http://www.XXXX.com/XXXXservice/schema"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:ndf="http://slsexxxdevt1.ute.XXXX.com:10149/XXXX/XXXXservice.wsdl">

<soapenv:Header/>
     <soapenv:Body>
           <sch:OwnerOnlyInquiryRequest>
           <sch:RequestHeader>
           <sch:ClientSystem>ePRS</sch:ClientSystem>
           </sch:RequestHeader>
           <sch:RequestParameterList>
           <sch:RequestParam>13413745</sch:RequestParam>
           </sch:RequestParameterList>
           <sch:RequestType>CESEID</sch:RequestType>
           <sch:PeckingOrder>Pricing</sch:PeckingOrder>
           <sch:ViewType>Pricing</sch:ViewType>
           </sch:OwnerOnlyInquiryRequest>
     </soapenv:Body>
</soapenv:Envelope>
;;;; 


proc soap in=request
          out=response
          url="http://slsexxxdevt1.ute.XXXX.com:10149/XXXX/XXXXservice.wsdl"
          soapaction="";
run;  

data output_dataset;
infile response dsd dlm = ' /';
input @"firstName=" firstName :$32. @"lastName=" lastName :$32. @"emplnbr=" emplnbr :8.;
run;

proc print data=output_dataset;
run;

上面代码的输出

Problem Statement

I need all of this to work in a macro that can be put in a loop. The final output should be three observations each corresponding to the respective number from the 'cenis' dataset. My attempt to create the macro is as below

%macro parse_single(ID_VAR);
filename request temp;
filename response "/mktg/prc203/abhee/output.txt";

data _null_;
   file request;
   input;
   put _infile_;
   datalines4;

<soapenv:Envelope xmlns:sch="http://www.xxxx.com/xxxxservice/schema"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:ndf="http://slsxxxxdevt1.ute.xxxx.com:10149/xxx/xxxxservice.wsdl">

<soapenv:Header/>
     <soapenv:Body>
           <sch:OwnerOnlyInquiryRequest>
           <sch:RequestHeader>
           <sch:ClientSystem>ePRS</sch:ClientSystem>
           </sch:RequestHeader>
           <sch:RequestParameterList>
           <sch:RequestParam>&ID_VAR</sch:RequestParam>
           </sch:RequestParameterList>
           <sch:RequestType>CESEID</sch:RequestType>
           <sch:PeckingOrder>Pricing</sch:PeckingOrder>
           <sch:ViewType>Pricing</sch:ViewType>
           </sch:OwnerOnlyInquiryRequest>
     </soapenv:Body>
</soapenv:Envelope>
;;;; 


proc soap in=request
          out=response
          url="http://slsxxxxdevt1.ute.xxxx.com:10149/xxxx/xxxxservice.wsdl"
          soapaction="";
run;  

data want;
infile response dsd dlm = ' /';
input @"Employee" @"firstName=" firstName :$32. @"lastName=" lastName :$32. @"emplnbr=" emplnbr :8.;
run;

proc print data=want;
run;

%mend parse_single;

The above macro compiles correctly without any errors. Then when I try to execute the same for a specific number manually like below it creates errors.

%parse_single(13413745);
run;

The log is

1                                                          The SAS System                          12:47 Wednesday, February 7, 2018

1          %_eg_hidenotesandsource;
5          %_eg_hidenotesandsource;
28         
29         %parse_single(13413745);

NOTE: The file REQUEST is:
      Filename=/var/xxxx/SAS/WORK/tmp/9.4/SAS_work75F400002FE8_mktpricing/#LN00038,
      Owner Name=e0836441,Group Name=pricing,
      Access Permission=-rw-r--r--,
      Last Modified=07Feb2018:14:56:06

ERROR: The macro PARSE_SINGLE generated CARDS (data lines) for the DATA step, which could cause incorrect results.  The DATA step 
       and the macro will stop executing.
NOTE: 0 records were written to the file REQUEST.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.00 seconds

180: LINE and COLUMN cannot be determined.
NOTE: NOSPOOL is on. Rerunning with OPTION SPOOL might allow recovery of the LINE and COLUMN where the error has occurred.
ERROR 180-322: Statement is not valid or it is used out of proper order.

ERROR: The macro PARSE_SINGLE will stop executing.
30         run;

31         
32         
33         %_eg_hidenotesandsource;
45         
46         
47         %_eg_hidenotesandsource;
50       

My first roadblock is to get the macro working correctly and the second roadblock is to make the %do loop work correctly. When attempted the loop I am getting the same CARDS error.

You cannot use CARDS/DATALINES in macro code. So do it some other way.

I would store the template in a file and use PROC STREAM to read the file and replace any macro expressions.

Or just pass the values to your data _null_ as string literals.

data _null_;
   file request;
   put 
 '<soapenv:Envelope xmlns:sch="http://www.xxxx.com/xxxxservice/schema"'
/'                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"'
/'             xmlns:ndf="http://slsxxxxdevt1.ute.xxxx.com:10149/xxx/xxxxservice.wsdl">'
/'<soapenv:Header/>'
/'     <soapenv:Body>'
/'           <sch:OwnerOnlyInquiryRequest>'
/'           <sch:RequestHeader>'
....
   ;
run;

Here is what worked. All credits to my lovely wife!

filename response "/mktg/prc203/abhee/output.txt";
data cenis;
infile datalines; 
input CENI $;
datalines;
13413745
12174391
8905899
;

%macro abc;
proc sql noprint;
 select count(*) into :cnt
 from CENIS;
quit;

%do x=1 %to &cnt;

filename outfile "/mktg/prc203/abhee/input.txt";

data _null_;
set cenis(firstobs=&x obs=&x);
file outfile;
string1='<soapenv:Envelope xmlns:sch="http://www.xxxxx.com/xxxxxservice/schema"';
string2='xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"';
string3='xmlns:ndf="http://slsxxxxxdevt1.ute.xxxxx.com:10149/xxxxx/xxxxxservice.wsdl">';
string4=compress('<sch:RequestParam>'||CENI||'</sch:RequestParam>');
put string1;
put @25 string2;
put @25 string3;
put '<soapenv:Header/>' /
@10 '<soapenv:Body>' /
@15 '<sch:OwnerOnlyInquiryRequest>' /
@15 '<sch:RequestHeader>' /
@15 '<sch:ClientSystem>ePRS</sch:ClientSystem>' /
@15 '</sch:RequestHeader>' /
@15 '<sch:RequestParameterList>' /
@15 string4 /
@15 '</sch:RequestParameterList>' /
@15 '<sch:RequestType>CESEID</sch:RequestType>' /
@15 '<sch:PeckingOrder>Pricing</sch:PeckingOrder>' /
@15 '<sch:ViewType>Pricing</sch:ViewType>' /
@15 '</sch:OwnerOnlyInquiryRequest>' /
@10 '</soapenv:Body>' /
'</soapenv:Envelope>'
;

run;

proc soap in=outfile
          out=response
          url="http://slsxxxxxdevt1.ute.xxxxx.com:10149/xxxxx/xxxxxservice.wsdl"
          soapaction="";
run;  
data want;
infile response dsd dlm = ' /';
input @"Employee" @"firstName=" firstName :$32. @"lastName=" lastName :$32. @"emplnbr=" emplnbr :8.;
run;

proc append base=FINAL data=want;
run;

%end;
%mend;

%abc;

proc print data=final;
run;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM