SAS 9.1.3 Integration Technologies » Developer's Guide


WebSphere MQ Functional Interface
Writing WebSphere MQ Applications
WebSphere MQ Code Samples
WebSphere MQ CALL Routines
MQCONN
MQDISC
MQOPEN
MQCLOSE
MQPUT
MQPUT1
MQGET
MQCMIT
MQBACK
MQINQ
MQSET
MQPMO
MQGMO
MQOD
MQMD
MQMAP
MQSETPARMS
MQGETPARMS
MQRMH
MQFREE
Application Messaging

WebSphere MQ Coding Examples

This section contains examples of using the WebSphere MQ interface to send and receive messages to and from application messaging queues.

There are two examples of using DATA step code to send and receive text files. The first shows how to do it without using WebSphere MQ V5 features. The second example shows how to simplify the process using WebSphere MQ V5 features.

An example that shows how to send and receive binary files is here.

Examples of using the WebSphere MQ interface with the SAS Macro Language are here.

Please note the following points about freeing resources used in conjunction with the WebSphere MQ Interface:

  • When a SAS DATA step ends, all resources consumed by this DATA step are automatically freed. That is, all internal SAS handles are automatically freed, as well as being disconnected from all queue managers that were connected during this DATA step execution. However, it is good programming practice to free these resources using the functions provided.

  • When using the SAS Macro Language to interface with WebSphere MQ, care should be taken to ensure that all resources are freed programmatically. Unlike the DATA step, resources consumed by the SAS Macro Language are never implicitly freed during SAS execution.

DATA Step Coding Examples

This example puts a message on a queue.

   data _null_;
   length hconn hobj cc reason 8;
   length rc hod hpmo hmd hmap hdata 8;
   length parms $ 200 options $ 200 action $ 3 msg $ 200;

   hconn=0;
   hobj=0;
   hod=0;
   hpmo=0;
   hmd=0;
   hmap=0;
   hdata=0;

   put '---------------- Connect to QMgr --------------';
   qmgr="TEST";
   call mqconn(qmgr, hconn, cc, reason);
   if cc ^= 0 then do;
      if reason = 2002 then do;
         put 'Already connected to QMgr ' qmgr;
      end;
   else do;
      if reason = 2059 then
         put 'MQCONN: QMgr not available... 
		    needs to be started';
      else
         put 'MQCONN: failed with reason= ' reason;
      goto exit;
      end;
   end;
   else put 'MQCONN: successfully connected to QMgr ' qmgr;


   put '---------- Generate object descriptor ---------';
   action="GEN";
   parms="OBJECTNAME";
   objname="TEST";
   call mqod(hod, action, rc, parms, objname);
   if rc ^= 0 then do;
      put 'MQOD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;
   else put 'MQOD: successfully generated 
      object descriptor';


   put '-------- Open queue object for output ---------';
   options="OUTPUT";
   call mqopen(hconn, hod, options, hobj, cc, reason);
   if cc ^= 0 then do;
      put 'MQOPEN: failed with reason= ' reason;
      goto exit;
   end;
   else put 'MQOPEN: successfully opened queue for output';


   put '--------- Generate put message options --------';
   call mqpmo(hpmo, action, rc);
   if rc ^= 0 then do;
      put 'MQPMO: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;
   else put 'MQPMO: successfully generated put 
      message options';


   put '--------- Generate message descriptor ---------';
   parms="PERSISTENCE";
   persist="PERSISTENT"; /* persistent message */
   call mqmd(hmd, action, rc, parms, persist);
   if rc ^= 0 then do;
      put 'MQMD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;
   else put 'MQMD: successfully generated 
      message descriptor';


   put '----------- Generate map descriptor -----------';
   /* data will not be aligned */
   desc1="SHORT";
   desc2="LONG";
   desc3="DOUBLE";
   desc4="CHAR,,50"; /* blank pad to 50 bytes */
   call mqmap(hmap, rc, desc1, desc2, desc3, desc4);
   if rc ^= 0 then do;
      put 'MQMAP: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;
   else put 'MQMAP: successfully generated map descriptor';


   put '--- Generate data descriptor - actual data ----';
   parm1=100;
   parm2=9999;
   parm3=9999.9999;
   parm4="This is a test.";
   call mqsetparms(hdata, hmap, rc, parm1, 
      parm2, parm3, parm4);
   if rc ^= 0 then do;
      put 'MQSETPARMS: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;
   else put 'MQSETPARMS: successfully generated 
      data descriptor';


   put '------------- Put message on queue ------------';
   call mqput(hconn, hobj, hmd, hpmo, hdata, cc, reason);
   if cc ^= 0 then do;
      put 'MQPUT: failed with reason= ' reason;
      goto exit;
   end;
   else do;
      put 'MQPUT: successfully put message on queue';

      /* inquire about message descriptor 
         output parameters */
      action="INQ";
      parms="MSGID,PUTAPPLTYPE,PUTAPPLNAME,
         PUTDATE,PUTTIME";

      length msgid $ 48 applname $ 28 date $ 8 time $ 8;
      call mqmd(hmd, action, rc, parms, msgid, appltype, 
         applname, date, time);
      if rc ^= 0 then do;
         put 'MQMD: failed with rc= ' rc;
         msg = sysmsg();
         put msg;
      end;
      else do;
         put 'Message descriptor output parameters are:';
         put 'MSGID= ' msgid;
         put 'PUTAPPLTYPE= ' appltype;
         put 'PUTAPPLNAME= ' applname;
         put 'PUTDATE= ' date;
         put 'PUTTIME= ' time;
      end;
   end;


   exit:
   if hobj ^= 0 then do;
      put '----------------- Close queue ---------------';
      options="NONE";
      call mqclose(hconn, hobj, options, cc, reason);
      if cc ^= 0 then do;
         put 'MQCLOSE: failed with reason= ' reason;
      end;
      else put 'MQCLOSE: successfully closed queue';
   end;


   if hconn ^= 0 then do;
      put '------------ Disconnect from QMgr -----------';
      call mqdisc(hconn, cc, reason);
      if cc ^= 0 then do;
         put 'MQDISC: failed with reason= ' reason;
      end;
      else put 'MQDISC: successfully disconnected 
         from QMgr';
   end;


   if hod ^= 0 then do;
      call mqfree(hod);
      put 'Object descriptor handle freed';
   end;
   if hpmo ^= 0 then do;
      call mqfree(hpmo);
      put 'Put message options handle freed';
   end;
   if hmd ^= 0 then do;
      call mqfree(hmd);
      put 'Message descriptor handle freed';
   end;
   if hmap ^= 0 then do;
      call mqfree(hmap);
      put 'Map descriptor handle freed';
   end;
   if hdata ^= 0 then do;
      call mqfree(hdata);
      put 'Data descriptor handle freed';
   end;


   run;

This example retrieves a message from a queue.

   data _null_;
   length hconn hobj cc reason 8;
   length rc hod hgmo hmd hmap msglen 8;
   length parms $ 200 options $ 200 action $ 3 msg $ 200;

   hconn=0;
   hobj=0;
   hod=0;
   hgmo=0;
   hmd=0;
   hmap=0;

   put '---------------- Connect to QMgr --------------';
   qmgr="TEST";
   call mqconn(qmgr, hconn, cc, reason);
   if cc ^= 0 then do;
      if reason = 2002 then do;
         put 'Already connected to QMgr ' qmgr;
      end;
      else do;
         if reason = 2059 then
            put 'MQCONN: QMgr not available... 
               needs to be started';
         else
            put 'MQCONN: failed with reason= ' reason;
         goto exit;
      end;
   end;
   else put 'MQCONN: successfully connected to QMgr ' qmgr;


   put '---------- Generate object descriptor ---------';
   action="GEN";
   parms="OBJECTNAME";
   objname="TEST";
   call mqod(hod, action, rc, parms, objname);
   if rc ^= 0 then do;
      put 'MQOD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;
   else put 'MQOD: successfully generated 
      object descriptor';


   put '--------- Open queue object for input ---------';
   options="INPUT_SHARED";
   call mqopen(hconn, hod, options, hobj, cc, reason);
   if cc ^= 0 then do;
      put 'MQOPEN: failed with reason= ' reason;
      goto exit;
   end;
   else put 'MQOPEN: successfully opened queue for output';


   put '--------- Generate get message options --------';
   call mqgmo(hgmo, action, rc);
   if rc ^= 0 then do;
      put 'MQGMO: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;
   else put 'MQGMO: successfully generated get 
      message options';


   put '--------- Generate message descriptor ---------';
   call mqmd(hmd, action, rc);
   if rc ^= 0 then do;
      put 'MQMD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;
   else put 'MQMD: successfully generated 
      message descriptor';


   put '----------- Generate map descriptor -----------';
   desc1="SHORT";
   desc2="LONG";
   desc3="DOUBLE";
   desc4="CHAR,,50";
   call mqmap(hmap, rc, desc1, desc2, desc3, desc4);
   if rc ^= 0 then do;
      put 'MQMAP: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;
   else put 'MQMAP: successfully generated map descriptor';


   put '------------ Get message from queue -----------';
   call mqget(hconn, hobj, hmd, hgmo, msglen, cc, reason);
   if cc ^= 0 then do;
      if reason = 2033 then put 'No message available';
      else put 'MQGET: failed with reason= ' reason;
      goto exit;
   end;
   else do;
      put 'MQGET: successfully retrieved message 
         from queue';
      put 'message length= ' msglen;

      /* inquire about message descriptor 
         output parameters */
      action="INQ";
      parms="REPORT,MSGTYPE,FEEDBACK,MSGID,
         CORRELID,USERIDENTIFIER,PUTAPPLTYPE,
         PUTAPPLNAME,PUTDATE,PUTTIME";

      length report $ 30 msgtype 8 feedback 8 msgid $ 48 
         correlid $ 48 userid $ 12 appltype 8  
         applname $ 28 date $ 8 time $8;

      call mqmd(hmd, action, rc, parms, report, 
         msgtype, feedback, msgid, correlid, userid, 
         appltype, applname, date, time);
      if rc ^= 0 then do;
         put 'MQMD: failed with rc ' rc;
         msg = sysmsg();
         put msg;
      end;
      else do;
         put 'Message descriptor output parameters are:';
         put 'REPORT= ' report;
         put 'MSGTYPE= ' msgtype;
         put 'FEEDBACK= ' feedback;
         put 'MSGID= ' msgid;
         put 'CORRELID= ' correlid;
         put 'USERIDENTIFIER= ' userid;
         put 'PUTAPPLTYPE= ' appltype;
         put 'PUTAPPLNAME= ' applname;
         put 'PUTDATE= ' date;
         put 'PUTTIME= ' time;
      end;
   end;


   if msglen > 0 then do;
      /* retrieve SAS variables from GET buffer */
      length parm1 parm2 parm3 8 parm4 $ 50;

      call mqgetparms(hmap, rc, parm1, 
         parm2, parm3, parm4);
      put 'Display SAS variables:';
      put 'parm1= ' parm1;
      put 'parm2= ' parm2;
      put 'parm3= ' parm3;
      put 'parm4= ' parm4;
      if rc ^= 0 then do;
         put 'MQGETPARMS: failed with rc= ' rc;
         msg = sysmsg();
         put msg;
      end;
   end;
   else put 'No data associated with message';


   exit:
   if hobj ^= 0 then do;
      put '----------------- Close queue ---------------';
      options="NONE";
      call mqclose(hconn, hobj, options, cc, reason);
      if cc ^= 0 then do;
         put 'MQCLOSE: failed with reason= ' reason;
      end;
      else put 'MQCLOSE: successfully closed queue';
   end;


   if hconn ^= 0 then do;
      put '------------ Disconnect from QMgr -----------';
      call mqdisc(hconn, cc, reason);
      if cc ^= 0 then do;
         put 'MQDISC: failed with reason= ' reason;
      end;
      else put 'MQDISC: successfully disconnected 
         from QMgr';
   end;


   if hod ^= 0 then do;
      call mqfree(hod);
      put 'Object descriptor handle freed';
   end;
   if hgmo ^= 0 then do;
      call mqfree(hgmo);
      put 'Get message options handle freed';
   end;
   if hmd ^= 0 then do;
      call mqfree(hmd);
      put 'Message descriptor handle freed';
   end;
   if hmap ^= 0 then do;
      call mqfree(hmap);
      put 'Map descriptor handle freed';
   end;


   run;

Text File Processing Example

This example puts a text file on a queue.

   data _null_;
   length rc 8;
   length msg $ 200;
   length hconn hod hpmo hobj hmd hmap hdata 8;
   length cc reason 8;
   length corrid $ 48;
   length record $ 256;
   length seqno 8 seqstr $ 4;

   /* send this file to the queue */
   infile 'd:\test.txt' length=reclen end=eof;

   call mqconn("TESTQMGR", hconn, cc, reason);
   if cc ^= 0 then do;
      if reason = 2002 then do;
         put 'Already connected to QMgr';
      end;
      else do;
         if reason = 2059 then
            put 'MQCONN: QMgr not available... 
               needs to be started';
         else
            put 'MQCONN: failed with reason= ' reason;
         goto exit;
      end;
   end;

   put '---------- Generate object descriptor ---------';
   call mqod(hod, "GEN", rc, "OBJECTNAME", "TESTQ");
   if rc ^= 0 then do;
      put 'MQOD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   put '-------- Open queue object for output ---------';
   call mqopen(hconn, hod, "OUTPUT", hobj, cc, reason);
   if cc ^= 0 then do;
      put 'MQOPEN: failed with reason= ' reason;
      goto exit;
   end;

   put '--------- Generate put message options --------';
   call mqpmo(hpmo, "GEN", rc);
   if rc ^= 0 then do;
      put 'MQPMO: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   put '--------- Generate message descriptor ---------';
   call mqmd(hmd, "GEN", rc, "PERSISTENCE,MSGTYPE",
      "PERSISTENT", 100000);
   if rc ^= 0 then do;
      put 'MQMD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   put '----------- Generate map descriptor -----------';
   /* longest record in file is 255 bytes+1 length byte... */
   /* therefore all messages on the queue pertaining to    */
   /* this file will be blank-padded for 256 bytes...      */
   call mqmap(hmap, rc, "char,,256");
   if rc ^= 0 then do;
      put 'MQMAP: failed';
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   /* all of these messages will have the 
      same correlationid+seqno */
   corrid="46696c65212121"; /* File!!! */

   seqno = 0;


   do until(eof);
      input @;
      input record $varying256. reclen;
 
      call mqsetparms(hdata, hmap, rc, record);
      if( rc ) then do;
         put 'MQSETPARMS: failed';
         msg = sysmsg();
         put msg;
         goto exit;
      end;

      /* add sequence # to correlationid */
      seqstr = put(seqno, hex4.);
      substr(corrid,15,4) = seqstr;
      seqno+1;

      /* set correlation id and let MQ generate msgid 
         for this message */
      call mqmd(hmd, "SET", rc, "CORRELID,MSGID", 
         corrid, "");
      if rc ^= 0 then do;
         put 'MQMD: failed with rc= ' rc;
         msg = sysmsg();
         put msg;
         goto exit;
      end;

      put '--- Put msg on queue ----';
      call mqput(hconn, hobj, hmd, hpmo, hdata, cc, reason);
      if cc ^= 0 then do;
         put 'MQPUT: failed with reason= ' reason;
         msg = sysmsg();
         put msg;
         goto exit;
      end;

      /* free data */
      call mqfree(hdata);
   end;

   exit:
   if( hobj ) then do;
      call mqclose(hconn, hobj, "NONE", cc, reason);
      if( cc ) then do;
         put 'MQCLOSE: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if( hconn ) then do;
      call mqdisc(hconn, cc, reason);
      if( cc ) then do;
         put 'MQDISC: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if hod ^= 0 then do;
      call mqfree(hod);
      put 'Object descriptor handle freed';
   end;
   if hpmo ^= 0 then do;
      call mqfree(hpmo);
      put 'Put message options handle freed';
   end;
   if hmd ^= 0 then do;
      call mqfree(hmd);
      put 'Message descriptor handle freed';
   end;
   if hmap ^= 0 then do;
      call mqfree(hmap);
      put 'Map descriptor handle freed';
   end;

   stop;

   run;

Getting a Text File From a Queue

This example retrieves the first text file on a queue. The message type msgtype is equal to 100000.

   filename output 'd:\testdup.txt';

   data _null_;
   length rc 8;
   length msg $ 200;
   length cc reason 8;
   length hconn hod hgmo hobj hobj2 hmap 8;
   length corrid filecorrid $ 48;
   length record $ 256;
   length seqno 8;


   fileid = fopen('output', 'o', 256, 'v');
   if( fileid = 0 ) then do;
      put 'Error opening output file...';
      goto exit;
   end;

   put '---------------- Connect to QMgr --------------';
   call mqconn("TESTQMGR", hconn, cc, reason);
   if cc ^= 0 then do;
      if reason = 2002 then do;
         put 'Already connected to QMgr';
      end;
      else do;
         if reason = 2059 then
            put 'MQCONN: QMgr not available... 
               needs to be started';
         else
            put 'MQCONN: failed with reason= ' reason;
         goto exit;
      end;
   end;


   put '---------- Generate object descriptor ---------';
   call mqod(hod, "GEN", rc, "OBJECTNAME", "TESTQ");
   if rc ^= 0 then do;
      put 'MQOD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;


   put '--------- Open queue object for input ---------';
   call mqopen(hconn, hod, "INPUT_SHARED,BROWSE", hobj, 
      cc, reason);
   if cc ^= 0 then do;
      put 'MQOPEN: failed with reason= ' reason;
      goto exit;
   end;


   put '--------- Generate get message options --------';
   call mqgmo(hgmo, "GEN", rc, "options", "browse_next");
   if rc ^= 0 then do;
      put 'MQGMO: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;


   put '--------- Generate message descriptor ---------';
   call mqmd(hmd, "GEN", rc);
   if rc ^= 0 then do;
      put 'MQMD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;


   seqno=0;

   recv:
   call mqget(hconn, hobj, hmd, hgmo, msglen, cc, reason);
   if( cc ) then do;
      if( reason = 2033 ) then do;
         put 'reached end of queue';
         goto exit;
      end;
      else do;
         put 'MQGET: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
         goto exit;
      end;
   end;

   /* inquire about msg properties */
   call mqmd(hmd, "INQ", rc, "CORRELID,MSGTYPE", 
      corrid, msgtype);
   if( rc ) then do;
      put 'MQMD failed';
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   /* default for getting next msg on queue */
   call mqgmo(hgmo, "SET", rc, "options", "browse_next");
   if rc ^= 0 then do;
      put 'MQGMO: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   if( msgtype = 100000 ) then do;
      /* file processing... */
      outofseq=0;

      if( filecorrid = "" ) then do;
      /* file begins at this message */

         /* write all correlating messages to this file */
         filecorrid = substr(corrid,1,14);

         put '--------- Generate map descriptor ---------';
         /* all file messages were sent to the queue as 
            256 bytes blank-padded */
         call mqmap(hmap, rc, "char,,256");
         if( rc ) then do;
            put 'MQMAP: failed';
            msg = sysmsg();
            put msg;
            goto exit;
         end;
      end;

      /* make sure message belongs to this file */
      if( substr(corrid,1,14) = filecorrid ) then do;
         if( seqno ^= input(substr(corrid,15,4), hex4.) ) 
            then do;
            /* this message is out of sequence 
               so search for it */
            outofseq=1;

         /* open another instance to search for 
            out-of-seq message */
         call mqopen(hconn, hod, "INPUT_SHARED,BROWSE", 
            hobj2, cc, reason);
         if cc ^= 0 then do;
            put 'MQOPEN: failed with reason= ' reason;
            goto exit;
         end;

         corrid = filecorrid;
         substr(corrid,15,4) = put(seqno, hex4.);
         call mqmd(hmd, "SET", rc, "MSGID,CORRELID", 
            "", corrid);
         if( rc ) then do;
            put 'MQMD: failed';
            msg = sysmsg();
            put msg;
         end;

         call mqgmo(hgmo, "SET", rc, "OPTIONS", 
            "BROWSE_FIRST");
         if( rc ) then do;
            put 'MQGMO: failed';
            msg = sysmsg();
            put msg;
            goto exit;
         end;

         call mqget(hconn, hobj2, hmd, hgmo, msglen, 
            cc, reason);
         if( cc ) then do;
            if( reason = 2033 ) then do;
               put 'Error: reached end of queue while 
                  searching for out-of-sequence msg';
               goto exit;
            end;
            else do;
               put 'MQGET: failed with reason = ' reason;
               msg = sysmsg();
               put msg;
               goto exit;
            end;
         end;
      end;

         /* increment sequence number for next 
            expected message */
         seqno+1;

         /* retrieve record from internal buffer */
         call mqgetparms(hmap, rc, record);
         if( rc ) then do;
            put 'MQGETPARMS: failed';
            msg = sysmsg();
            put msg;
            goto exit;
         end;

         put 'write record to file';
         rc = fput(fileid, record);
         if( rc ) then do;
            put 'Error writing to output file buffer...';
            goto exit;
         end;

         /* flush it to disk */
         rc = fwrite(fileid);
         if( rc ) then do;
            put 'Error writing to output file...';
            goto exit;
         end;
  

         /* now remove it from the queue... */
         call mqgmo(hgmo, "SET", rc, "OPTIONS", 
            "MSG_UNDER_CURSOR");
         if( rc ) then do;
            put 'MQGMO: failed';
            msg = sysmsg();
            put msg;
            goto exit;
         end;

         if( outofseq ) then do;
            call mqget(hconn, hobj2, hmd, hgmo, msglen, 
               cc, reason);
            if( cc ) then do;
               put 'problems removing message from queue';
               msg = sysmsg();
               put msg;
               goto exit;
            end;

            /* close queue */
            call mqclose(hconn, hobj2, "NONE", cc, reason);

            /* re-read previous message */
            call mqgmo(hgmo, "SET", rc, "OPTIONS", 
               "BROWSE_MSG_UNDER_CURSOR");
            if( rc ) then do;
               put 'MQGMO: failed';
               msg = sysmsg();
               put msg;
               goto exit;
            end;
         end;
         else do;
            call mqget(hconn, hobj, hmd, hgmo, msglen, 
               cc, reason);
            if( cc ) then do;
               put 'problems removing message from queue';
               msg = sysmsg();
               put msg;
               goto exit;
            end;

            /* browse next message */
            call mqgmo(hgmo, "SET", rc, "OPTIONS", 
               "BROWSE_NEXT");
            if( rc ) then do;
               put 'MQGMO: failed';
               msg = sysmsg();
               put msg;
               goto exit;
            end;
         end;
      end;
   end;

   /* finish retrieving all messages belonging 
      to this file */

   /* reset message descriptor */
   call mqmd(hmd, "SET", rc, "MSGID,CORRELID", "", "");
   if( rc ) then do;
      put 'MQMD: failed';
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   goto recv;

   exit:
   if( hobj ) then do;
      call mqclose(hconn, hobj, "NONE", cc, reason);
      if( cc ) then do;
         put 'MQCLOSE: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if( hconn ) then do;
      call mqdisc(hconn, cc, reason);
      if( cc ) then do;
         put 'MQDISC: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if( hod ) then
      call mqfree(hod);
   if( hgmo ) then
      call mqfree(hgmo);
   if( hmd ) then
      call mqfree(hmd);
   if( hmap ) then
      call mqfree(hmap);

   /* close file */
   rc = fclose(fileid);
   if( rc ) then put 'Error closing output file';

   run;

Text File Processing Example Using WebSphere MQ V5 Features

This example puts a text file to a queue using V5 features.

   /** bits within md.msgflags **/
   %let segment_allow=1;
   %let segment=2;
   %let last_segment=4;
   %let group=8;
   %let last_group=16;

   data _null_;
   length rc 8;
   length msg $ 200;
   length hconn hod hpmo hobj hmd hmap hdata 8;
   length cc reason 8;
   length record $ 256;
   length msgflags 8;

   /* send this file to the queue */
   infile 'd:\test.txt' length=reclen end=eof;

   call mqconn("TESTQMGR", hconn, cc, reason);
   if cc ^= 0 then do;
      if reason = 2002 then do;
         put 'Already connected to QMgr';
      end;
      else do;
         if reason = 2059 then
            put 'MQCONN: QMgr not available... 
               needs to be started';
         else
         put 'MQCONN: failed with reason= ' reason;
         goto exit;
      end;
   end;

   put '---------- Generate object descriptor ---------';
   call mqod(hod, "GEN", rc, "OBJECTNAME", "TESTQ");
   if rc ^= 0 then do;
      put 'MQOD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   put '-------- Open queue object for output ---------';
   call mqopen(hconn, hod, "OUTPUT", hobj, cc, reason);
   if cc ^= 0 then do;
      put 'MQOPEN: failed with reason= ' reason;
      goto exit;
   end;

   put '--------- Generate put message options --------';
   /** QMgr will generate a unique msgid on every put as **/
   /** well as generate a groupid for all of the msgs    **/
   /** and incrementally keep up with the sequencing...  **/
   call mqpmo(hpmo, "GEN", rc, "OPTIONS", 
      "NEW_MSGID,LOGICAL_ORDER");
   if rc ^= 0 then do;
      put 'MQPMO: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   put '--------- Generate message descriptor ---------';
   /** specify the message belongs to a group **/
   msgflags=&group;
   call mqmd(hmd, "GEN", rc, "PERSISTENCE,MSGTYPE,MSGFLAGS",
      "PERSISTENT", 100000, msgflags);
   if rc ^= 0 then do;
      put 'MQMD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   put '----------- Generate map descriptor -----------';
   /* longest record in file is 255 bytes+1 length byte... */
   /* therefore all messages on the queue pertaining to    */
   /* this file will be blank-padded for 256 bytes...      */
   call mqmap(hmap, rc, "char,,256");
   if rc ^= 0 then do;
      put 'MQMAP: failed';
      msg = sysmsg();
      put msg;
      goto exit;
   end;


   do until(eof);
      input @;
      input record $varying256. reclen;

      call mqsetparms(hdata, hmap, rc, record);
      if( rc ) then do;
         put 'MQSETPARMS: failed';
         msg = sysmsg();
         put msg;
         goto exit;
      end;

      /** set last in group if eof **/
      if( eof ) then do;
         msgflags + &last_group;
         call mqmd(hmd, "SET", rc, "MSGFLAGS", msgflags);
         if rc ^= 0 then do;
            put 'MQMD: failed with rc= ' rc;
            msg = sysmsg();
            put msg;
            goto exit;
         end;
      end;

      put '--- Put msg on queue ----';
      call mqput(hconn, hobj, hmd, hpmo, hdata, 
         cc, reason);
      if cc ^= 0 then do;
         put 'MQPUT: failed with reason= ' reason;
         msg = sysmsg();
         put msg;
         goto exit;
      end;

      /* free data */
      call mqfree(hdata);
   end;

   exit:
   if( hobj ) then do;
      call mqclose(hconn, hobj, "NONE", cc, reason);
      if( cc ) then do;
         put 'MQCLOSE: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if( hconn ) then do;
      call mqdisc(hconn, cc, reason);
      if( cc ) then do;
         put 'MQDISC: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if hod ^= 0 then do;
      call mqfree(hod);
      put 'Object descriptor handle freed';
   end;
   if hpmo ^= 0 then do;
      call mqfree(hpmo);
      put 'Put message options handle freed';
   end;
   if hmd ^= 0 then do;
      call mqfree(hmd);
      put 'Message descriptor handle freed';
   end;
   if hmap ^= 0 then do;
      call mqfree(hmap);
      put 'Map descriptor handle freed';
   end;

   stop;

   run;

Getting a Text File From a Queue

   /* Get first text file on a queue... ie. msgtype=100000 */
   /* use V5 features to perform the sequencing...         */

   /* This example opens queue with a browse cursor and    */
   /* browses the first msg in every group looking for     */
   /* a msg with msgtype=100000... once it is found,       */
   /* open a fetch instance to remove all msgs in that     */
   /* particular group...                                  */

   /* if you knew upfront the groupid that you wanted, you */
   /* could just open a single instance of the queue and   */
   /* remove the group in logical order without having to  */
   /* do any initial browsing...                           */

   /* bit test macros */
   %let segment_allow_mask='.......1'b;
   %let segment_mask='......1.'b;
   %let last_segment_mask='.....1..'b;
   %let group_mask='....1...'b;
   %let last_group_mask='...1....'b;

   filename output 'd:\testdup.txt';

   data _null_;
   length rc 8;
   length msg $ 200;
   length cc reason 8;
   length hconn hod hgmo hobj hmap 8;
   length record $ 256;
   length msgtype seqno msgflags 8;
   length groupid $ 48;


   fileid = fopen('output', 'o', 256, 'v');
   if( fileid = 0 ) then do;
      put 'Error opening output file...';
      goto exit;
   end;

   put '---------------- Connect to QMgr --------------';
   call mqconn("TESTQMGR", hconn, cc, reason);
   if cc ^= 0 then do;
      if reason = 2002 then do;
         put 'Already connected to QMgr';
      end;
      else do;
         if reason = 2059 then
            put 'MQCONN: QMgr not available... needs to 
               be started';
         else
            put 'MQCONN: failed with reason= ' reason;
         goto exit;
      end;
   end;


   put '---------- Generate object descriptor ---------';
   call mqod(hod, "GEN", rc, "OBJECTNAME", "TESTQ");
   if rc ^= 0 then do;
      put 'MQOD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;


   put '--------- Open queue object for input ---------';
   call mqopen(hconn, hod, "INPUT_SHARED,BROWSE", hobj, 
      cc, reason);
   if cc ^= 0 then do;
      put 'MQOPEN: failed with reason= ' reason;
      goto exit;
   end;

   put '--------- Generate get message options --------';
   call mqgmo(hgmo, "GEN", rc, "options, matchoptions", 
      "browse_next", "seqnumber");
   if rc ^= 0 then do;
      put 'MQGMO: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;


   put '--------- Generate message descriptor ---------';
   /** browse first msg in group only **/
   call mqmd(hmd, "GEN", rc, "msgseqnumber", 1);
   if rc ^= 0 then do;
      put 'MQMD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;


   recv:
   call mqget(hconn, hobj, hmd, hgmo, msglen, cc, reason);
   if( cc ) then do;
      if( reason = 2033 ) then do;
         put 'reached end of queue';
         goto exit;
      end;
      else do;
         put 'MQGET: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
         goto exit;
      end;
   end;

   /* inquire about msg properties */
   call mqmd(hmd, "INQ", rc, 
      "MSGTYPE,GROUPID,MSGSEQNUMBER,MSGFLAGS",
      msgtype, groupid, seqno, msgflags);
   if( rc ) then do;
      put 'MQMD failed';
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   put msgtype=;
   put groupid=;
   put seqno=;
   put msgflags=;


   if( msgtype = 100000 ) then do;
      /* file processing... */

      put '---------- Generate map descriptor ----------';
      /* all file messages were sent to the queue as 
         256 bytes blank-padded */
      call mqmap(hmap, rc, "char,,256");
      if( rc ) then do;
         put 'MQMAP: failed';
         msg = sysmsg();
         put msg;
         goto exit;
      end;

      /* close browse instance */
      call mqclose(hconn, hobj, "NONE", cc, reason);
      if( cc ) then do;
         put 'MQCLOSE: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;

      /* open queue in fetch mode */
      hobj=0;
      call mqopen(hconn, hod, "INPUT_SHARED", hobj, 
         cc, reason);
      if cc ^= 0 then do;
         put 'MQOPEN: failed with reason= ' reason;
         goto exit;
      end;

      call mqgmo(hgmo, "SET", rc, "options, matchoptions",
         "logical_order,complete_msg,all_msgs_available",
         "groupid");
      if rc ^= 0 then do;
         put 'MQGMO: failed with rc= ' rc;
         msg = sysmsg();
         put msg;
         goto exit;
      end;

      call mqmd(hmd, "SET", rc, "groupid", groupid);
      if rc ^= 0 then do;
         put 'MQMD: failed with rc= ' rc;
         msg = sysmsg();
         put msg;
         goto exit;
      end;

   next:
      call mqget(hconn, hobj, hmd, hgmo, msglen, 
         cc, reason);
      if( cc ) then do;
         put 'MQGET: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
         goto exit;
      end;

      /* inquire about msg properties */
      call mqmd(hmd, "INQ", rc, 
         "MSGTYPE,GROUPID,MSGSEQNUMBER,MSGFLAGS",
         msgtype, groupid, seqno, msgflags);
      if( rc ) then do;
         put 'MQMD failed';
         msg = sysmsg();
         put msg;
         goto exit;
      end;

      put msgtype=;
      put groupid=;
      put seqno=;
      put msgflags=;

      /* retrieve record from internal buffer */
      call mqgetparms(hmap, rc, record);
      if( rc ) then do;
         put 'MQGETPARMS: failed';
         msg = sysmsg();
         put msg;
         goto exit;
      end;

      put 'write record to file';
      rc = fput(fileid, record);
      if( rc ) then do;
         put 'Error writing to output file buffer...';
         goto exit;
      end;

      /* flush it to disk */
      rc = fwrite(fileid);
      if( rc ) then do;
         put 'Error writing to output file...';
         goto exit;
      end;


      /** receive until last in group **/
      if( (msgflags=&group_mask) AND 
         (NOT(msgflags=&last_group_mask)) ) 
         then goto next;
      else goto exit;

   end;
   else goto recv;

   exit:
   if( hobj ) then do;
      call mqclose(hconn, hobj, "NONE", cc, reason);
      if( cc ) then do;
         put 'MQCLOSE: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if( hconn ) then do;
      call mqdisc(hconn, cc, reason);
      if( cc ) then do;
         put 'MQDISC: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if( hod ) then
      call mqfree(hod);
   if( hgmo ) then
      call mqfree(hgmo);
   if( hmd ) then
      call mqfree(hmd);
   if( hmap ) then
      call mqfree(hmap);

   /* close file */
   rc = fclose(fileid);
   if( rc ) then put 'Error closing output file';

   run;

Binary File Processing Example

This example puts a binary file on a queue.

   data _null_;
   length rc 8;
   length msg $ 200;
   length hconn hod hpmo hobj hmd hmap hdata 8;
   length cc reason 8;
   length corrid $ 48;
   length msgbuf $ 256;
   length seqno 8 seqstr $ 4;

   /* send this file to the queue */
   infile 'd:\test.exe' recfm=f lrecl=1 end=eof;

   call mqconn("TESTQMGR", hconn, cc, reason);
   if cc ^= 0 then do;
      if reason = 2002 then do;
         put 'Already connected to QMgr';
      end;
      else do;
         if reason = 2059 then
            put 'MQCONN: QMgr not available... needs to 
               be started';
         else
            put 'MQCONN: failed with reason= ' reason;
         goto exit;
      end;
   end;

   put '---------- Generate object descriptor ---------';
   call mqod(hod, "GEN", rc, "OBJECTNAME", "TESTQ");
   if rc ^= 0 then do;
      put 'MQOD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   put '-------- Open queue object for output ---------';
   call mqopen(hconn, hod, "OUTPUT", hobj, cc, reason);
   if cc ^= 0 then do;
      put 'MQOPEN: failed with reason= ' reason;
      goto exit;
   end;

   put '--------- Generate put message options --------';
   call mqpmo(hpmo, "GEN", rc);
   if rc ^= 0 then do;
      put 'MQPMO: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   put '--------- Generate message descriptor ---------';
   call mqmd(hmd, "GEN", rc, "PERSISTENCE,MSGTYPE", 
      "PERSISTENT", 100001);
   if rc ^= 0 then do;
      put 'MQMD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   put '----------- Generate map descriptor -----------';
   /* send 256 byte messages to the queue */
   call mqmap(hmap, rc, "char,,256");
   if rc ^= 0 then do;
      put 'MQMAP: failed';
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   /* all of these messages will have the same 
      correlationid+seqno */
   corrid="42696e46696c65212121"; /* BinFile!!! */

   seqno = 0;

   i=1;
   do until(eof);
      /* read a byte at a time */
      input x $char1.;
      i+1;
      substr(msgbuf,i,1) = x;
      if( i = 256 or eof ) then do;
         /* set length of this record embedded 
            as first byte of message */
         substr(msgbuf,1,1) = put(i-1,pib1.);

         call mqsetparms(hdata, hmap, rc, msgbuf);
         if( rc ) then do;
            put 'MQSETPARMS: failed';
            msg = sysmsg();
            put msg;
            goto exit;
         end;


         /* add sequence # to correlationid */
         seqstr = put(seqno, hex4.);
         substr(corrid,21,4) = seqstr;
         seqno+1;

         /* set correlation id and let MQ generate 
            msgid for this message */
         call mqmd(hmd, "SET", rc, "CORRELID,MSGID", 
            corrid, "");
         if rc ^= 0 then do;
            put 'MQMD: failed with rc= ' rc;
            msg = sysmsg();
            put msg;
            goto exit;
         end;

         put '--- Put msg on queue ----';
         call mqput(hconn, hobj, hmd, hpmo, hdata, 
            cc, reason);
         if cc ^= 0 then do;
            put 'MQPUT: failed with reason= ' reason;
            msg = sysmsg();
            put msg;
            goto exit;
         end;

         /* free data */
         call mqfree(hdata);

         /* reset message buffer entities */
         i=1;
         msgbuf="";
      end;
   end;

   exit:
   if( hobj ) then do;
      call mqclose(hconn, hobj, "NONE", cc, reason);
      if( cc ) then do;
         put 'MQCLOSE: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if( hconn ) then do;
      call mqdisc(hconn, cc, reason);
      if( cc ) then do;
         put 'MQDISC: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if hod ^= 0 then do;
      call mqfree(hod);
      put 'Object descriptor handle freed';
   end;
   if hpmo ^= 0 then do;
      call mqfree(hpmo);
      put 'Put message options handle freed';
   end;
   if hmd ^= 0 then do;
      call mqfree(hmd);
      put 'Message descriptor handle freed';
   end;
   if hmap ^= 0 then do;
      call mqfree(hmap);
      put 'Map descriptor handle freed';
   end;

   stop;

   run;

Getting a Binary File From a Queue

This example get the first binary file on a queue.

   filename output 'd:\testdup.exe';

   data _null_;
   length rc 8;
   length msg $ 200;
   length cc reason 8;
   length hconn hod hgmo hobj hobj2 hmap 8;
   length corrid filecorrid $ 48;
   length msgbuf stream $ 256;
   length len 8;
   length seqno 8;


   fileid = fopen('output', 'o', 0, 'b');
   if( fileid = 0 ) then do;
      put 'Error opening output file...';
      goto exit;
   end;

   put '---------------- Connect to QMgr --------------';
   call mqconn("TESTQMGR", hconn, cc, reason);
   if cc ^= 0 then do;
      if reason = 2002 then do;
         put 'Already connected to QMgr';
      end;
      else do;
         if reason = 2059 then
            put 'MQCONN: QMgr not available... needs to be 
               started';
         else
            put 'MQCONN: failed with reason= ' reason;
         goto exit;
      end;
   end;


   put '---------- Generate object descriptor ---------';
   call mqod(hod, "GEN", rc, "OBJECTNAME", "TESTQ");
   if rc ^= 0 then do;
      put 'MQOD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;


   put '--------- Open queue object for input ---------';
   call mqopen(hconn, hod, "INPUT_SHARED,BROWSE", hobj, cc,
      reason);
   if cc ^= 0 then do;
      put 'MQOPEN: failed with reason= ' reason;
      goto exit;
   end;


   put '--------- Generate get message options --------';
   call mqgmo(hgmo, "GEN", rc, "options", "browse_next");
   if rc ^= 0 then do;
      put 'MQGMO: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;


   put '--------- Generate message descriptor ---------';
   call mqmd(hmd, "GEN", rc);
   if rc ^= 0 then do;
      put 'MQMD: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;


   seqno=0;

   recv:
   call mqget(hconn, hobj, hmd, hgmo, msglen, cc, reason);
   if( cc ) then do;
      if( reason = 2033 ) then do;
         put 'reached end of queue';
      goto exit;
      end;
      else do;
         put 'MQGET: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
         goto exit;
      end;
   end;

   /* inquire about msg properties */
   call mqmd(hmd, "INQ", rc, "CORRELID,MSGTYPE", 
      corrid, msgtype);
   if( rc ) then do;
      put 'MQMD failed';
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   /* default for getting next msg on queue */
   call mqgmo(hgmo, "SET", rc, "options", "browse_next");
   if rc ^= 0 then do;
      put 'MQGMO: failed with rc= ' rc;
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   if( msgtype = 100001 ) then do;
      /* file processing... */
      outofseq=0;

      if( filecorrid = "" ) then do;
         /* file begins at this message */

         /* write all correlating messages to this file */
         filecorrid = substr(corrid,1,20);

         put '--------- Generate map descriptor ---------';
         /* all file messages were sent to the queue as 256
            bytes blank-padded */
         call mqmap(hmap, rc, "char,,256");
         if( rc ) then do;
            put 'MQMAP: failed';
            msg = sysmsg();
            put msg;
            goto exit;
         end;
      end;

      /* make sure message belongs to this file */
      if( substr(corrid,1,20) = filecorrid ) then do;
         if( seqno ^= input(substr(corrid,21,4), hex4.) ) 
            then do;
            /* this message is out of sequence so 
               search for it */
            outofseq=1;

            /* open another instance to search for 
               out-of-seq message */
            call mqopen(hconn, hod, "INPUT_SHARED,BROWSE", 
               hobj2, cc, reason);
            if cc ^= 0 then do;
               put 'MQOPEN: failed with reason= ' reason;
               goto exit;
            end;

            corrid = filecorrid;
            substr(corrid,21,4) = put(seqno, hex4.);
            call mqmd(hmd, "SET", rc, "MSGID,CORRELID", 
               "", corrid);
            if( rc ) then do;
               put 'MQMD: failed';
               msg = sysmsg();
               put msg;
            end;

            call mqgmo(hgmo, "SET", rc, "OPTIONS", 
               "BROWSE_FIRST");
            if( rc ) then do;
               put 'MQGMO: failed';
               msg = sysmsg();
               put msg;
               goto exit;
            end;

            call mqget(hconn, hobj2, hmd, hgmo, msglen, 
               cc, reason);
            if( cc ) then do;
               if( reason = 2033 ) then do;
                  put 'Error: reached end of queue while 
                     searching for out-of-sequence msg';
                  goto exit;
               end;
               else do;
                  put 'MQGET: failed with reason = ' reason;
                  msg = sysmsg();
                  put msg;
                  goto exit;
               end;
            end;
         end;

         /* increment sequence number for 
            next expected message */
         seqno+1;

         /* retrieve record from internal buffer */
         call mqgetparms(hmap, rc, msgbuf);
         if( rc ) then do;
            put 'MQGETPARMS: failed';
            msg = sysmsg();
            put msg;
            goto exit;
         end;

         /* length of this stream is embedded 
		    as 1st byte in msg */
         len = input(substr(msgbuf,1,1), pib1.);
         stream = substr(msgbuf,2);

         put 'write stream to file';
         rc = fput(fileid, substr(stream,1,len));
         if( rc ) then do;
            put 'Error writing to output file buffer...';
            goto exit;
         end;

         /* flush it to disk */
         rc = fwrite(fileid);
         if( rc ) then do;
            put 'Error writing to output file...';
            goto exit;
         end;


         /* now remove it from the queue... */
         call mqgmo(hgmo, "SET", rc, "OPTIONS", 
		    "MSG_UNDER_CURSOR");
         if( rc ) then do;
            put 'MQGMO: failed';
            msg = sysmsg();
            put msg;
            goto exit;
         end;

         if( outofseq ) then do;
            call mqget(hconn, hobj2, hmd, hgmo, msglen, 
               cc, reason);
            if( cc ) then do;
               put 'problems removing message from queue';
               msg = sysmsg();
               put msg;
               goto exit;
            end;

            /* close queue */
            call mqclose(hconn, hobj2, "NONE", cc, reason);

            /* re-read previous message */
            call mqgmo(hgmo, "SET", rc, "OPTIONS", 
               "BROWSE_MSG_UNDER_CURSOR");
            if( rc ) then do;
               put 'MQGMO: failed';
               msg = sysmsg();
               put msg;
               goto exit;
            end;
         end;
         else do;
            call mqget(hconn, hobj, hmd, hgmo, msglen, 
               cc, reason);
            if( cc ) then do;
               put 'problems removing message from queue';
               msg = sysmsg();
               put msg;
               goto exit;
            end;

            /* browse next message */
            call mqgmo(hgmo, "SET", rc, "OPTIONS", 
               "BROWSE_NEXT");
            if( rc ) then do;
               put 'MQGMO: failed';
               msg = sysmsg();
               put msg;
               goto exit;
            end;
         end;
      end;
   end;

   /* finish retrieving all messages belonging 
      to this file */

   /* reset message descriptor */
   call mqmd(hmd, "SET", rc, "MSGID,CORRELID", "", "");
   if( rc ) then do;
      put 'MQMD: failed';
      msg = sysmsg();
      put msg;
      goto exit;
   end;

   goto recv;

   exit:
   if( hobj ) then do;
      call mqclose(hconn, hobj, "NONE", cc, reason);
      if( cc ) then do;
         put 'MQCLOSE: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
      end;
   end;

   if( hconn ) then do;
      call mqdisc(hconn, cc, reason);
      if( cc ) then do;
         put 'MQDISC: failed with reason = ' reason;
         msg = sysmsg();
         put msg;
       end;
   end;

   if( hod ) then
      call mqfree(hod);
   if( hgmo ) then
      call mqfree(hgmo);
   if( hmd ) then
      call mqfree(hmd);
   if( hmap ) then
      call mqfree(hmap);

   /* close file */
   rc = fclose(fileid);
   if( rc ) then put 'Error closing output file';

   run;

Macro Language Coding Examples

This section shows examples of using the SAS Macro Language to make calls to the MQSeries Interface.

   %macro putmsg;
   %let hconn=0;
   %let hobj=0;
   %let hod=0;
   %let hpmo=0;
   %let hmd=0;
   %let hmap=0;
   %let hdata=0;
   %put ---------------- Connect to QMgr --------------;
   %let qmgr=TEST;
   %let cc=0;
   %let reason=0;
   %syscall mqconn(qmgr, hconn, cc, reason);
   %if &cc ^= 0 %then %do;
      %if &reason = 2002 %then %do;
         %put Already connected to QMgr &qmgr;
      %end;
      %else %do;
         %if &reason = 2059 %then
            %put MQCONN: QMgr not available... 
               needs to be started;
         %else
            %put MQCONN: failed with reason= &reason;
            %goto exit;
         %end;
      %end;


   %put ---------- Generate object descriptor ---------;
   %let action=GEN;
   %let rc=0;
   %let parms=OBJECTNAME;
   %let objname=TEST;
   %syscall mqod(hod, action, rc, parms, objname);
   %if &rc ^= 0 %then %do;
      %put MQOD: failed with rc= &rc;
      %put %sysfunc(sysmsg());
      %goto exit;
   %end;
   %else %put MQOD: successfully generated 
      object descriptor;


   %put -------- Open queue object for output ---------;
   %let options=OUTPUT;
   %syscall mqopen(hconn, hod, options, hobj, cc, reason);
   %if &cc ^= 0 %then %do;
      %put MQOPEN: failed with Reason= &reason;
      %goto exit;
   %end;
   %else %put MQOPEN: successfully opened queue for output;


   %put --------- Generate put message options --------;
   %syscall mqpmo(hpmo, action, rc);
   %if &rc ^= 0 %then %do;
      %put MQPMO: failed with rc= &rc;
      %put %sysfunc(sysmsg());
      %goto exit;
   %end;
   %else %put MQPMO: successfully generated put 
      message options;


   %put --------- Generate message descriptor ---------;
   %let parms=PERSISTENCE;
   %let persist=PERSISTENT;
   %syscall mqmd(hmd, action, rc, parms, persist);
   %if &rc ^= 0 %then %do;
      %put MQMD: failed with rc= &rc;
      %put %sysfunc(sysmsg());
      %goto exit;
   %end;
   %else %put MQMD: successfully generated 
      message descriptor;


   %put ----------- Generate map descriptor -----------;
   /* data will not be aligned */
   %let desc1=SHORT;
   %let desc2=LONG;
   %let desc3=DOUBLE;
   %let desc4=CHAR,,50;
   %syscall mqmap(hmap, rc, desc1, desc2, desc3, desc4);
   %if &rc ^= 0 %then %do;
      %put MQMAP: failed with rc= &rc;
      %put %sysfunc(sysmsg());
      %goto exit;
   %end;
   %else %put MQMAP: successfully generated map descriptor;


   %put --- Generate data descriptor - actual data ----;
   %let parm1=100;
   %let parm2=9999;
   %let parm3=9999.999;
   %let parm4=This is a test.;
   %syscall mqsetparms(hdata, hmap, rc, parm1, 
      parm2, parm3, parm4);
   %if &rc ^= 0 %then %do;
      %put MQSETPARMS: failed with rc= &rc;
      %put %sysfunc(sysmsg());
      %goto exit;
   %end;
   %else %put MQSETPARMS: successfully generated 
      data descriptor;


   %put ------------- Put message on queue ------------;
   %syscall mqput(hconn, hobj, hmd, hpmo, 
      hdata, cc, reason);
   %if &cc ^= 0 %then %do;
      %put MQPUT: failed with reason= &reason;
      %goto exit;
   %end;
   %else %do;
      %put MQPUT: successfully put message on queue;

      /* inquire about message descriptor 
         output parameters */
      %let action=INQ;
      %let parms=MSGID,PUTAPPLTYPE,PUTAPPLNAME,
         PUTDATE,PUTTIME;
      /* initialize msgid for return length of 48 */
      %let msgid="                                       ";
      %let appltype=0;
      /* initialize applname for return length of 28 */
      %let applname="                          ";
      /* initialize data, time for return length of 8 */
      %let date="      ";
      %let time="      ";

      %syscall mqmd(hmd, action, rc, parms, msgid, 
         appltype, applname, date, time);
      %if &rc ^= 0 %then %do;
         %put MQMD: failed with rc=  &rc;
         %put %sysfunc(sysmsg());
      %end;
      %else %do;
         %put Message descriptor output parameters are:;
         %put MSGID=  &msgid;
         %put PUTAPPLTYPE=  &appltype;
         %put PUTAPPLNAME=  &applname;
         %put PUTDATE=  &date;
         %put PUTTIME=  &time;
      %end;
   %end;


   %exit:
   %if &hobj ^= 0 %then %do;
      %put ------------------ Close queue ----------------;
      %let options=NONE;
      %syscall mqclose(hconn, hobj, options, cc, reason);
      %if &cc ^= 0 %then %do;
         %put MQCLOSE: failed with reason= &reason;
      %end;
      %else %put MQCLOSE: successfully closed queue;
   %end;


   %if &hconn ^= 0 %then %do;
      %put ------------- Disconnect from QMgr ------------;
      %syscall mqdisc(hconn, cc, reason);
      %if &cc ^= 0 %then %do;
         %put MQDISC: failed with reason= &reason;
      %end;
      %else %put MQDISC: successfully disconnected 
         from QMgr;
   %end;


   %if &hod ^= 0 %then %do;
      %syscall mqfree(hod);
      %put Object descriptor handle freed;
   %end;
   %if &hpmo ^= 0 %then %do;
      %syscall mqfree(hpmo);
      %put Put message options handle freed;
   %end;
   %if &hmd ^= 0 %then %do;
      %syscall mqfree(hmd);
      %put Message descriptor handle freed;
   %end;
   %if &hmap ^= 0 %then %do;
      %syscall mqfree(hmap);
      %put Map descriptor handle freed;
   %end;
   %if &hdata ^= 0 %then %do;
      %syscall mqfree(hdata);
      %put Data descriptor handle freed;
   %end;


   %mend putmsg;

   /** invoke macro to Put a message on a queue **/
   %putmsg;


   %macro getmsg;
   %let hconn=0;
   %let hobj=0;
   %let hod=0;
   %let hgmo=0;
   %let hmd=0;
   %let hmap=0;
   %put ---------------- Connect to QMgr --------------;
   %let qmgr=TEST;
   %let cc=0;
   %let reason=0;
   %syscall mqconn(qmgr, hconn, cc, reason);
   %if &cc ^= 0 %then %do;
      %if &reason = 2002 %then %do;
         %put Already connected to QMgr &qmgr;
      %end;
      %else %do;
         %if &reason = 2059 %then
            %put MQCONN: QMgr not available... 
               needs to be started;
         %else
            %put MQCONN: failed with reason= &reason;
         %goto exit;
      %end;
   %end;
   %else %put MQCONN: successfully connected 
      to QMgr &qmgr;


   %put ---------- Generate object descriptor ---------;
   %let rc=0;
   %let action=GEN;
   %let parms=OBJECTNAME;
   %let objname=TEST;
   %syscall mqod(hod, action, rc, parms, objname);
   %if &rc ^= 0 %then %do;
      %put MQOD: failed with rc= &rc;
      %put %sysfunc(sysmsg());
      %goto exit;
   %end;
   %else %put MQOD: successfully generated 
      object descriptor;


   %put --------- Open queue object for input ---------;
   %let options=INPUT_SHARED;
   %syscall mqopen(hconn, hod, options, hobj, cc, reason);
   %if &cc ^= 0 %then %do;
      %put MQOPEN: failed with reason= &reason;
      %goto exit;
   %end;
   %else %put MQOPEN: successfully opened queue for output;


   %put --------- Generate get message options --------;
   %syscall mqgmo(hgmo, action, rc);
   %if &rc ^= 0 %then %do;
      %put MQGMO: failed with rc= &rc;
      %put %sysfunc(sysmsg());
      %goto exit;
   %end; 
   %else %put MQGMO: successfully generated get 
      message options;


   %put --------- Generate message descriptor ---------;
   %syscall mqmd(hmd, action, rc);
   %if &rc ^= 0 %then %do;
      %put MQMD: failed with rc= &rc;
      %put %sysfunc(sysmsg());
      %goto exit;
   %end;
   %else %put MQMD: successfully generated 
      message descriptor;


   %put ----------- Generate map descriptor -----------;
   %let desc1=SHORT;
   %let desc2=LONG;
   %let desc3=DOUBLE;
   %let desc4=CHAR,,50;
   %syscall mqmap(hmap, rc, desc1, desc2, desc3, desc4);
   %if &rc ^= 0 %then %do;
      %put MQMAP: failed with rc= &rc;
      %put %sysfunc(sysmsg());
      %goto exit;
   %end;
   %else %put MQMAP: successfully generated map descriptor;


   %put ------------ Get message from queue -----------;
   %let msglen=0;
   %syscall mqget(hconn, hobj, hmd, hgmo, msglen, cc, 
      reason);
   %if &cc ^= 0 %then %do;
      %if &reason = 2033 %then %put No message 
         available;
      %else %put MQGET: failed with reason= &reason;
      %goto exit;
   %end;
   %else %do;
      %put MQGET: successfully retrieved message from queue;
      %put message length= &msglen;

      /* inquire about message descriptor 
         output parameters */
      %let action=INQ;
      %let parms=REPORT,MSGTYPE,FEEDBACK,MSGID,CORRELID,
         USERIDENTIFIER,PUTAPPLTYPE,PUTAPPLNAME,PUTDATE,
         PUTTIME;
      /* initialize report for return length of 30 */
      %let report="                            ";
      %let msgtype=0;
      %let feedback=0;
      /* initialize msgid, correlid for 
         return length of 48 */
      %let msgid="                                       ";
      %let correlid="                                    ";
      /* initialize userid for return length of 12 */
      %let userid="          ";
      %let appltype=0;
      /* initialize applname for return length of 28 */
      %let applname="                          ";
      /* initiailze data, time for return length of 8 */
      %let date="      ";
      %let time="      ";

      %syscall mqmd(hmd, action, rc, parms, report, 
         msgtype, feedback, msgid, correlid, userid, 
         appltype, applname, date, time);
      %if &rc ^= 0 %then %do;
         %put MQMD: failed with rc &rc;
         %put %sysfunc(sysmsg());
      %end;
      %else %do;
         %put Message descriptor output parameters are:;
         %put REPORT= &report;
         %put MSGTYPE= &msgtype;
         %put FEEDBACK= &feedback;
         %put MSGID= &msgid;
         %put CORRELID= &correlid;
         %put USERIDENTIFIER= &userid;
         %put PUTAPPLTYPE= &appltype;
         %put PUTAPPLNAME= &applname;
         %put PUTDATE= &date;
         %put PUTTIME= &time;
      %end;
   %end;


   %if &msglen > 0 %then %do;
      /* retrieve SAS variables from GET buffer */
      %let parm1=0;
      %let parm2=0;
      %let parm3=0;
      /* initialize character return value length of 50 */
      %let parm4="                                       ";

      %syscall mqgetparms(hmap, rc, parm1, 
         parm2, parm3, parm4);
      %put Display SAS macro variables:;
      %put parm1= &parm1;
      %put parm2= &parm2;
      %put parm3= &parm3;
      %put parm4= &parm4;
      %if &rc ^= 0 %then %do;
         %put MQGETPARMS: failed with rc= &rc;
         %put %sysfunc(sysmsg());
      %end;
   %end;
   %else %put No data associated with message;


   %exit:   
   %if &hobj ^= 0 %then %do;
      %put ------------------ Close queue ----------------;
      %let options=NONE;
      %syscall mqclose(hconn, hobj, options, cc, reason);
      %if &cc ^= 0 %then %do;
         %put MQCLOSE: failed with reason= &reason;
      %end;
      %else %put MQCLOSE: successfully closed queue;
   %end;


   %if &hconn ^= 0 %then %do;
      %put ------------- Disconnect from QMgr ------------;
      %syscall mqdisc(hconn, cc, reason);
      %if &cc ^= 0 %then %do;
         %put MQDISC: failed with reason= &reason;
      %end;
      %else %put MQDISC: successfully 
         disconnected from QMgr;
   %end;


   %if &hod ^= 0 %then %do;
      %syscall mqfree(hod);
      %put Object descriptor handle freed;
   %end;
   %if &hgmo ^= 0 %then %do;
      %syscall mqfree(hgmo);
      %put Get message options handle freed;
   %end;
   %if &hmd ^= 0 %then %do;
      %syscall mqfree(hmd);
      %put Message descriptor handle freed;
   %end;
   %if &hmap ^= 0 %then %do;
      %syscall mqfree(hmap);
      %put Map descriptor handle freed;
   %end;


   %mend getmsg;


   /** invoke macro to Get a message from a queue **/
   %getmsg;