Отсылка файла в MQ очередь при помощи PL/I

Давайте создадим небольшую программу, в котором отправим содержимое текстового файла в MQ очередь.

Текст программы (немного откомментировал, если будут вопросы - пишите в комментариях):

/*********************************************************************/
/* MYMQSND: LOAD MQ QUEUE FROM FILE                                  */
/*********************************************************************/
MYMQSND: PROC OPTIONS(MAIN) REORDER;
/*********************************************************************/
/* BUILTIN функции                                                   */
/*********************************************************************/
DCL TRIM             BUILTIN;
DCL LENGTH           BUILTIN;
DCL ADDR             BUILTIN;
DCL ONCHAR           BUILTIN;
DCL ONCODE           BUILTIN;
DCL ONLOC            BUILTIN;
DCL ONSOURCE         BUILTIN;
/*********************************************************************/
/* Обработчик ошибок                                                 */
/*********************************************************************/
DCL ERRCHAR          CHAR (01)   INIT ('');
DCL ERRFLD           CHAR (20)   INIT ('');
DCL ERRPROC          CHAR (20)   INIT ('');
DCL ERRCD            FIXED BIN (5,0)   INIT(0);
ON ERROR BEGIN;
    ERRCD   = ONCODE;
    ERRCHAR = ONCHAR;
    ERRFLD  = ONSOURCE;
    ERRPROC = ONLOC;
    PUT SKIP DATA (ERRCD,ERRFLD,ERRCHAR,ERRPROC);
    CLOSE FILE (SYSPRINT);
    EXIT;
END;
/*********************************************************************/
/* Переменные                                                        */
/*********************************************************************/
DCL MQ_BUFFER        CHAR (32767);
DCL MSG_LENGTH       BIN FIXED(31);
DCL INSTR            CHAR(32760);
DCL INSTR_VAR        CHAR(32760) VAR;
DCL INSTR_BL         CHAR(79) INIT(' ');
/*********************************************************************/
/* MQSERIES переменные (стандартные обьявления)                      */
/*********************************************************************/
%INCLUDE CMQP;
%INCLUDE CMQEPP;
DCL L_MQMGR          CHAR(48);          /* Имя MQ manager            */
DCL L_MQNAME         CHAR(48);          /* Имя очереди               */
DCL 1 LMQOD          LIKE  MQOD;        /* OBJECT DESCRIPTOR         */
DCL 1 LMQMD          LIKE  MQMD;        /* MESSAGE DESCRIPTOR        */
DCL 1 LMQPMO         LIKE  MQPMO;       /* Структура опций           */
DCL OPTIONS          FIXED BIN(31);     /* Опции отсылки             */
DCL HQM              FIXED BIN(31);     /* CONNECTION HANDLE         */
DCL COMPCODE         FIXED BIN(31);     /* COMPLETION CODE           */
DCL REASONE          FIXED BIN(31);     /* REASON CODE               */
DCL HOBJ             FIXED BIN(31);     /* OBJECT HANDLE             */
DCL RECORD_LENGTH    FIXED BIN(31);     /* Длина записи              */
/*********************************************************************/
/* Файлы                                                             */
/*********************************************************************/
DCL SYSPRINT         FILE OUTPUT;
                                        /* Файл с именем очереди     */
DCL MQNAME           FILE RECORD INPUT SEQL;
                                        /* Файл со входными данными  */
DCL MQDATA           FILE RECORD INPUT SEQL ENVIRONMENT(SCALARVARYING);
DCL EOF_NAME         BIT(1) INIT('0'B); /* Индикатор конца файла     */
ON  ENDFILE(MQNAME)  EOF_NAME = '1'B;
DCL EOF_DATA         BIT(1) INIT('0'B); /* Индикатор конца файла     */
ON  ENDFILE(MQDATA)  EOF_DATA = '1'B;
/*********************************************************************/
/* Основной код                                                      */
/*********************************************************************/
CALL INIT_ALL;                          /* Инициализация             */
CALL READ_MQNAME;                       /* Вычитываем имя очереди    */
 
                                        /* Открываем MQ очередь      */
CALL MQ_CONNECT;
CALL MQ_OPEN;
                                        /* Читаем в цикле файл       */
                                        /* Каждая вычитанная строка  */
                                        /* отсылается в MQ очередь   */
OPEN FILE(MQDATA);
READ FILE(MQDATA) INTO(INSTR);
DO WHILE(¬EOF_DATA);
  CALL MQ_PUT;
  READ FILE(MQDATA) INTO(INSTR);
END;
CLOSE FILE(MQDATA);
CALL MQ_CLOSE;
CALL MQ_DISCONNECT;
/*********************************************************************/
/* Инициализация                                                     */
/*********************************************************************/
INIT_ALL: PROC;
  RECORD_LENGTH = 0;
  OPTIONS       = 0;
  HQM           = 0;
  COMPCODE      = 0;
  REASONE       = 0;
  HOBJ          = 0;
  L_MQNAME      = '';
  MSG_LENGTH    = 0;
  INSTR         = '';
                                        /* Будет использован MQ      */
  L_MQMGR       = '';                   /* manager по-умолчанию      */
END INIT_ALL;
/*********************************************************************/
/* Читаем имя очереди из файла                                       */
/*********************************************************************/
READ_MQNAME: PROC;
  DCL MQN_BUFFER     CHAR(80);
  OPEN FILE(MQNAME);
  READ FILE(MQNAME) INTO(MQN_BUFFER);
  IF EOF_NAME THEN
    CALL GENEND('MQLM010', 'MQ QUEUE NAME MISSING');
  CLOSE FILE(MQNAME);
  L_MQNAME = SUBSTR(MQN_BUFFER,1,48);
END READ_MQNAME;
/*********************************************************************/
/* Подключаемся к QUEUE MANAGER                                      */
/*********************************************************************/
MQ_CONNECT: PROC;
  CALL MQCONN (L_MQMGR,                
               HQM,                    
               COMPCODE,               
               REASONE);               
  IF COMPCODE ¬= MQCC_OK & REASONE ¬= MQRC_NONE THEN
    CALL GENEND('MQLM020', 'MQ CONNECT FAILED');
END MQ_CONNECT;
/********************************************************************/
/* Отключаемся от QUEUE MANAGER                                     */
/********************************************************************/
MQ_DISCONNECT: PROC;
  CALL MQDISC (HQM,                    
               COMPCODE,               
               REASONE);               
  IF COMPCODE ¬= MQCC_OK & REASONE ¬= MQRC_NONE THEN
    CALL GENEND('MQLM030', 'MQ DISCONNECT FAILED');
END MQ_DISCONNECT;
/*********************************************************************/
/* Открываем очередь                                                 */
/*********************************************************************/
MQ_OPEN: PROC;
  LMQOD.OBJECTTYPE = MQOT_Q;            
  LMQOD.OBJECTNAME = L_MQNAME;          
  OPTIONS = MQOO_OUTPUT;                /* Режим-  отсылка данных    */
  CALL MQOPEN (HQM,                
               LMQOD,              
               OPTIONS,            
               HOBJ,               
               COMPCODE,           
               REASONE);           
  IF COMPCODE ¬= MQCC_OK & REASONE ¬= MQRC_NONE THEN
    CALL GENEND('MQLM030', 'MQ OPEN FAILED');
END MQ_OPEN;
/********************************************************************/
/* Записываем сообщение в очередь                                   */
/********************************************************************/
MQ_PUT: PROC;
                                        /* Посылаем только данные   */
                                        /* без пробелов в конце     */
  INSTR_VAR = TRIM(INSTR);
  MQ_BUFFER = INSTR_VAR;
  MSG_LENGTH = LENGTH(INSTR_VAR);
                                        /* Стандартные значения     */
  LMQMD.STRUCID     = MQMD_STRUC_ID;   
  LMQMD.VERSION     = MQMD_VERSION_1;  
  LMQMD.MSGTYPE     = MQMT_DATAGRAM;   
  LMQMD.EXPIRY      = MQEI_UNLIMITED;  
  LMQMD.FORMAT      = MQFMT_STRING;    
  LMQMD.PRIORITY    = MQPRI_PRIORITY_AS_Q_DEF;
  LMQMD.PERSISTENCE = MQPER_PERSISTENCE_AS_Q_DEF;
  LMQMD.MSGID       = MQCI_NONE;       
  LMQMD.CORRELID    = MQCI_NONE;
  LMQPMO.STRUCID    = MQPMO_STRUC_ID;  
  LMQPMO.VERSION    = MQPMO_VERSION_1; 
  CALL MQPUT (HQM,               
              HOBJ,              
              LMQMD,             
              LMQPMO,            
              MSG_LENGTH,        
              MQ_BUFFER,         
              COMPCODE,          
              REASONE);          
  IF COMPCODE ¬= MQCC_OK & REASONE ¬= MQRC_NONE THEN
   CALL GENEND('MQLM050', ' MQ PUT FAILED');
END MQ_PUT;
/********************************************************************/
/* Закрываем очередь                                                */
/********************************************************************/
MQ_CLOSE: PROC;
  OPTIONS = MQCO_NONE;
  CALL MQCLOSE (HQM,             
                HOBJ,            
                OPTIONS,         
                COMPCODE,        
                REASONE);        
  IF COMPCODE ¬= MQCC_OK & REASONE ¬= MQRC_NONE THEN
   CALL GENEND('MQLM080', ' MQ CLOSE FAILED');
END MQ_CLOSE;
/********************************************************************/
/* Обработчик ошибок                                                */
/********************************************************************/
GENEND: PROC(ID,TEXT);
  DCL ID             CHAR(7);
  DCL TEXT           CHAR(60);
  PUT SKIP DATA(ID);
  PUT SKIP DATA(TEXT);
  PUT SKIP DATA(COMPCODE);
  PUT SKIP DATA(REASONE);
  SIGNAL ERROR;
END GENEND;
/********************************************************************/
/* Конец программы                                                  */
/********************************************************************/
END MYMQSND;

Собираем программу и создаем небольшое задание, для ее запуска:

//MYMQSNDJ JOB (USERID,GROUPID),'TEST JOB',NOTIFY=&SYSUID,
//             MSGLEVEL=(1,1),MSGCLASS=H,CLASS=2,REGION=6M
//********************************************************************/
//STEP010 EXEC PGM=MYMQSND,REGION=4M
//STEPLIB   DD DSN=USERID.LOAD,DISP=SHR
//          DD DSN=SYS1.MQMXXX.SCSQAUTH,DISP=SHR
//          DD DSN=SYS1.MQMXXX.SCSQANLE,DISP=SHR
//SYSIN     DD DUMMY
//SYSTSPRT  DD SYSOUT=*
//SYSOUT    DD SYSOUT=*
//SYSPRINT  DD SYSOUT=*
//PLIDUMP   DD SYSOUT=*
//********************************************************************/
//* Файл с именем очереди
//********************************************************************/
//MQNAME    DD DSN=USERID.MQNAME,DISP=SHR
//********************************************************************/
//* Файл с данными для отсылки
//********************************************************************/
//MQDATA    DD DSN=USERID.MQDATA,DISP=SHR

Параметры задания устанавливаем в зависимости от настроек среды.

Пути к библиотекам SYS1.MQMXXX.SCSQAUTH и SYS1.MQMXXX.SCSQANLE нужно заменить на аналогичные существующие (MQMXXX - имя MQSeries environment).

PS: надеюсь, лишних переменных не оставил и не удалил нужных =)