WebSphere MQ Coding Examples

Introduction to the WebSphere MQ Examples

This section contains examples of using the WebSphere MQ interface to send and receive messages to and from application messaging queues.
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, 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 Example: Put a Message on a Queue

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;

DATA Step Coding Example: Retrieve a Message

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;

Processing a Text File

This example puts a text file to a queue.
   /** 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

This example gets a text file from a queue.
   /* Get
first text file on a queue... ie. msgtype=100000 */
   /* 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;

Processing a Binary File

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 gets 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;