Оператор DD
Оператор описания данных DD (data definition) - это оператор определения данных и устройств, используемых в задании и его отдельных шагах. Операторы DD, относящиеся к определенному шагу задания, следуют за оператором EXEC этого шага задания. В одном шаге задания может быть описано не более 3273 операторов DD. Оператор DD может располагаться также за оператором JOB, если требуется описать наборы данных, общие для всего задания (например, библиотеки загрузочных модулей и др.).
Оператор DD может содержать один позиционный и около 60 ключевых параметров. Познакомимся с некоторыми наиболее важными из них, исключив из рассмотрения параметры, используемые для описания SMS и VSAM наборов данных.
Формат оператора DD:
//имя DD [позиционный параметр][,ключевые параметры] Позиционный параметр: * | DATA | DUMMY Ключевые параметры: [,DSN[AME] = имя_набора_данных] [,DCB = (список подпараметров)] [,UNIT = устройство] [,VOL[UME] =(список подпараметров)] [,SPACE = (список подпараметров)] [,DISP = (список подпараметров)] [,SYSOUT = (список подпараметров)] [,LABEL = (список подпараметров)] ...
Важнейшим атрибутом оператора DD является имя, связывающее описываемый набор данных с кодом вызываемой программы. Как отмечалось в п.5.1.3, в программе для каждого используемого набора данных с помощью макровызова DCB устанавливается так называемое dd-имя (ddname). Если в шаге задания указать оператор DD с таким же именем, то появляется возможность определить или изменить ряд параметров указанного набора данных через оператор DD задания, то есть в момент запуска программы. Таким образом, при выполнении любой программы пользователь должен в первую очередь выяснить, какие dd-имена следует применять для описания данных и устройств, необходимых для ее работы. Это можно сделать с помощью соответствующей документации и руководств. Например, для программы-компилятора языка ассемблера установлены следующие dd-имена:
SYSIN - для описания исходного модуля;
SYSPRINT - для вывода сообщений компилятора;
SYSLIN - для описания объектного модуля;
SYSUT1 - промежуточный набор данных.
Некоторые имена операторов DD зарезервированы системой для специальных целей. К ним относятся, например, следующие имена:
JOBLIB - для описания личной библиотеки загрузочных модулей, доступной заданию;
STEPLIB - для описания личной библиотеки загрузочных модулей, доступной для шага задания;
SYSABEND - для выходного набора данных, в который может быть записан дамп системного ядра и области памяти обрабатывающей программы, если шаг задания завершился аварийно;
SYSUDUMP - для выходного набора данных, в который может быть записан дамп области памяти обрабатывающей программы, если шаг задания завершился аварийно;
SYSCHK - для выходного набора данных контрольной точки;
SYSIN - для входного набора данных ввода заданий;
SYSPRINT - для набора данных, выводимого на печатающее устройство;
При использовании процедур могут применяться составные имена операторов DD, о чем речь пойдет немного ниже.
Только в одном случае у оператора DD может отсутствовать имя: при описании сцепленных наборов данных, рассматриваемых системой как единый набор данных:
//SCHETA DD ... // DD ... // DD ...
Система требует, чтобы у таких наборов данных были согласованы основные характеристики логических записей, такие как формат, длина и размер блока.
В языке управления заданиями имеется возможность определять значения некоторых параметров одного оператора DD посредством ссылки на значение этого же параметра другого оператора DD. В общем виде ссылку можно представить в следующих форматах:
*.имя_DD
или
*.имя_шага_задания.имя_DD
Первый формат используется при ссылке внутри шага задания, а второй формат применяется при ссылке на один из предшествующих шагов задания. Например:
//PR JOB SECT //ST1 EXEC PGM=SUN1 //UT1 DD DSNAME=LIB1,DCB=(RECFM=FB,LRECL=80,BLKSIZE=400) //UT2 DD DSNAME=LIB2,DCB=*.UT1 //ST2 EXEC PGM=SUN2 //GO DD DSNAME=LIB3,DCB=*.ST1.UT1
Теперь рассмотрим позиционный параметр оператора DD, который может принимать одно из трех взаимоисключающих значений:
* | DATA | DUMMY
Первое значение (*) служит для описания данных, размещаемых во входном потоке, то есть непосредственно в тексте задания вслед за оператором DD. Данные могут занимать одну или несколько строк задания и завершаться ограничительным оператором /*. В некоторых случаях ограничительный оператор может быть опущен. Признаком конца набора данных является в этом случае первый встретившийся управляющий оператор JCL с символами // в первых двух позициях строки.
Пример:
//SYSIN DD * 1 ИВАНОВ 12345 7.9 2 ПЕТРОВ 67890 3.8 3 СИДОРОВ 73452 9.0 /*
Если же входные данные включают управляющие операторы JCL, то есть строки, содержащие в первых двух позициях //, то необходимо вместо * использовать параметр DATA. В приведенном ниже примере в качестве входных данных определены две строки, содержащие предложения JOB и EXEC:
//MYJCL DD DATA //USER1A JOB ,BOB,MSGLEVEL=1 //ST1 EXEC IEFBR14 /*
Если во вводимых во входном потоке данных должны содержаться строки, начинающиеся с символов /*, то в этом случае можно определить другой ограничитель с помощью параметра DLM. В частности, при компиляции C/C++ приложений можно использовать этот прием следующим образом:
//PR JOB SECT //ST1 EXEC PGM=CCNDRVR //COMPILE DD *,DLM=<> # incude <stdio.h> /*комментарий*/ main(); ... <>
Здесь двухсимвольное значение <> в первых двух позициях строки служит для ограничения входного набора данных подобно /*.
Следует обратить внимание, что по умолчанию JES принимает для вводимого таким образом набора данных значения LRECL=BLKSIZE=80.
Значение позиционного параметра DUMMY применяется, чтобы объявить некоторый набор данных как фиктивный. В этом случае система не производит никаких действий над набором данных. Например, предложение
//SYSPRINT DD DUMMY
обеспечивает подавление вывода сообщений, направляемых программой в набор данных с dd-именем SYSPRINT.
//BIBL DD DSNAME=LIB1 //SYSIN DD DSN=D.USER1.DATA
Для указания раздела библиотеки в скобках записывают имя раздела:
//LOAD DD DSN=USERLIB(PROG1) //XXX DD DSN=MY.JCL(JOBTEST)
Перед именем временного набора данных записывают два знака амперсанда &&:
//SYSLIN DD DSN=&&LOADSET(GO) //SYSUT1 DD DSN=&&SYSUT1
Временные наборы данных автоматически уничтожаются системой после завершения шага задания. Отсутствие в операторе DD параметра DSNAME также означает, что набор данных временный. В этом случае имя набора данных будет сгенерировано автоматически, например, так:
SYSxxxxx.Txxxxxx.RA000.jobname.Rxxxxxx
где x - определенным образом сформированные цифры и символы.
В качестве значения параметра DSNAME можно указывать ссылки на другие операторы DD в формате *.имя_DD или *.имя_шага.имя_DD.
//STFG EXEC PGM=PROG1 //SYSUT1 DD DSN=DATA.IN ... //SYSLIN DD DSN=*.STFG.SYSUT1
Параметр DISP (диспозиция) определяет исходное состояние набора данных, а также действия, которые необходимо произвести с набором данных после завершения шага задания или всего задания: сохранить, уничтожить, каталогизировать и др. Формат записи параметра DISP включает три позиционных подпараметра:
DISP=([статус][,дисп_НЗ][,дисп_АЗ])
где статус - исходное (текущее) состояние набора данных, дисп_НЗ - действие при нормальном завершении шага задания, дисп_АЗ - действие, которое надлежит выполнить при аварийном завершении шага задания.
Подпараметр статус может принимать следующие значения:
NEW - в указанном шаге задания создается новый набор данных;
OLD - набор данных существует (создан ранее);
SHR - набор данных существует и может быть использован одновременно другим заданием, т.е. разделяется различными заданиями в режиме чтения;
MOD - набор данных существует и будет модифицироваться в указанном шаге задания (используется только для последовательных наборов данных).
Подпараметры диспозиции дисп_НЗ и дисп_АЗ могут принимать следующие значения:
DELETE - набор данных следует уничтожить;
KEEP - набор данных следует сохранить;
CATLG - набор данных следует сохранить и каталогизировать;
UNCATLG - набор данных нужно сохранить, но при этом исключить из системного каталога.
PASS - набор данных следует передать для использования в последующем шаге того же задания.
Последнее значение (PASS) может быть использовано только для подпараметра дисп_НЗ.
Примеры задания диспозиции:
- DISP=(NEW,KEEP,DELETE) - набор данных создается и будет сохранен при нормальном завершении и удален при аварийном завершении шага задания;
- DISP=(SHR,KEEP,UNCATLG) - набор данных существует и будет сохранен при нормальном завершении и исключен из каталога при аварийном завершении шага задания.
Допускается не указывать некоторые или даже все подпараметры, учитывая следующие правила формирования их значений по умолчанию:
- если не указан первый подпараметр (статус), то принимается значение NEW;
- если не указан второй подпараметр (дисп_НЗ), то принимается значение DELETE для нового и KEEP для существующего набора данных;
- если не указан третий подпараметр (дисп_АЗ), то принимается значение, заданное для второго подпараметра (дисп_НЗ);
- если не указан параметр DISP, то принимаются значения (NEW,DELETE,DELETE), то есть набор данных создается и уничтожается во время выполнения шага задания (временный).
Примеры:
DISP=(NEW,KEEP) и DISP=(,KEEP) соответствует DISP=(NEW,KEEP,KEEP) DISP=NEW и DISP=(NEW,,DELETE) соответствует DISP=(NEW,DELETE,DELETE) DISP=OLD соответствует DISP=(OLD,KEEP,KEEP) DISP=(OLD,,DELETE) соответствует DISP=(OLD,KEEP,DELETE) DISP=(SHR,,KEEP) соответствует DISP=(SHR,KEEP,KEEP)
Параметр UNIT назначает набору данных устройство ввода-вывода и определяется в большинстве случаев одним из трех значений (см. п. 5.1.3):
UNIT=адрес | типовое_имя | групповое_имя
Подпараметр адрес задает трех- или четырехразрядный физический адрес устройства (в шестнадцатеричном представлении). Подпараметр типовое_имя задает устройство по установленному производителем оборудования номеру модели, однозначно указывающему на тип устройства.
Подпараметр групповое_имя определяет устройство через логическое имя устройства или группы устройств, задаваемое системным программистом на этапе конфигурирования оборудования с помощью компонента HCD в таблице EDT. Ниже приведены примеры задания параметра UNIT различными способами:
//AD DD UNIT=220 - адрес устройства //TD DD UNIT=3390 - типовое имя //GD DD UNIT=SYSDA - групповое имя //GD DD UNIT=VIO - набор данных в виртуальной памяти
Параметр VOLUME (сокращенно VOL) указывает том или тома, на которых размещается набор данных. Рассмотрим наиболее употребительные варианты использования данного параметра.
В первом варианте том определяется посредством задания серийного имени тома в виде:
VOL=SER=имя[,имя]...
Например:
//DSETl DD DSN=YS,UNIT=SYSDA,VOL=SER=PTOM01
Здесь описан набор данных YS, находящийся на устройстве, принадлежащем к группе SYSDA с серийным номером тома PTOM01. Для многотомных наборов данных следует указывать список имен.
Во втором варианте том задается через ссылку, определяемую одним из трех способов:
VOL=REF=имя_набора_данных | *.имя_DD |.имя шага.имя_DD
В первом способе будет выбран том, на котором размещен ранее описанный в задании каталогизированный набор данных. Второй и третий способы используют стандартный формат ссылок. Рассмотрим пример:
//STEP1 EXEC PGM=.... //DD1 DD DSN=OLD.DATASET,DISP=SHR //DD2 DD DSN=DSET1,DISP=(,CATLG,DELETE),VOL=REF=*.DD1 //STEP2 EXEC PGM=... //DD3 DD DSN=DSET2,DISP=(,CATLG),VOL=REF=*.STEP1.DD1
Здесь создаваемые наборы данных DSET1 и DSET2 будут размещены на том же томе, что и существующий набор данных с именем OLD.DATASET.
Параметр DCB устанавливает характеристики логической организации набора данных, фиксируемые в блоке управления данными (Data Control Block), который создается системой для каждого набора данных. Блок управления данными представляет собой таблицу, которая после открытия заполняется информацией из описания набора данных в программе и дополняется данными из соответствующего оператора DD. Параметр DCB обычно имеет формат:
DCB=(список подпараметров)
Все подпараметры DCB являются ключевыми. Перечислим основные из них:
- DSORG - тип организации набора данных;
- RECFM - формат записей;
- LRECL - длина логической записи;
- BLKSIZE - длина блока;
- BUFNO - число буферов ввода-вывода, выделяемых набору данных;
- BUFL - размер каждого буфера в байтах.
Подпараметр RECFM может принимать следующие значения: F - записи фиксированной длины; V - записи переменной длины; U - записи неопределенной длины. Выбор типа записи определяет пользователь. Если он группирует записи в блоки, то указывает это, добавляя к символу формата букву В. Например, указание RECFM=FB означает, что сблокированные записи имеют фиксированную длину.
Примеры:
- Набор данных состоит из записей фиксированной длины по 128 байт, которые объединяются в блоки по четыре записи в каждом:
DCB=(RECFM=FB,LRECL=128,BLKSIZE=512) - Набор данных содержит неблокированные записи фиксированной длины по 80 байт:
DCB=(BLKSIZE=80,RECFM=F)
Вместо ключевых подпараметров DCB можно записать ссылку на другой оператор DD, причем некоторые подпараметры можно переопределить заново:
//ST1 DD DSN=VAX,DCB=(RECFM=VB,LRECL=64,BLKSIZE=640) //PRINT DD DCB=(*.ST1,BLKSIZE=128)
Здесь подпараметры набора данных для параметра DCB копируются из оператора DD с именем ST1, кроме размера блока, который задается непосредственно.
Параметр SPACE задает требуемый объем памяти для размещения создаваемого набора данных на жестком диске, то есть набора данных с диспозицией NEW. Обычно этот параметр записывают в виде:
SPACE=(размер[,(количество[,приращение][,оглавление])][,RLSE])
Подпараметр количество указывает, сколько блоков памяти будет выделено набору данных первоначально, а подпараметр размер задает размер или тип одного блока и может принимать одно из следующих значений:
TRK - блок соответствует физической дорожке диска;
CYL - блок соответствует цилиндру диска;
число - определяет значение размера блока в байтах.
Так, параметр SPACE=(CYL,10) определяет область дисковой памяти размером 10 цилиндров, а параметр SPACE=(800,30) объявляет, что требуется память объемом в 30 блоков по 800 байт каждый.
Если указанный объем не может быть выделен (диск переполнен), система завершает шаг задания аварийно.
В том случае когда первоначального объема памяти недостаточно для размещения данных, система может выделить дополнительные блоки памяти, количество которых определяется подпараметром приращение. Установлено, что система может выделять дополнительные блоки не более 15 раз. Так, параметр SPACE=(CYL,(40,5)) запрашивает первоначально 40 цилиндров, а если этого объема памяти будет недостаточно, то система будет выделять по пять цилиндров до 15 раз, т. е. при необходимости всего будет выделено 40+5*15=115 цилиндров. Если приращение не указано, то дополнительные блоки не выделяются.
Параметр оглавление задается только для наборов данных с библиотечной организацией. Он определяет необходимое количество блоков, отводимых под оглавление библиотечного набора данных. Один блок оглавления содержит 256 байт. Так, например, параметр SPACE=(TRK,(100,10,5)) запрашивает память в 100 дорожек и по 10 дополнительных дорожек (до 15 раз), а также пять блоков по 256 байт оглавления библиотечного набора данных. Отсутствие подпараметра оглавление обычно косвенно указывает на набор данных с последовательной организацией.
Очевидно, что не всегда удается точно предсказать требуемый для набора данных объем внешней памяти. Подпараметр RLSE служит для освобождения памяти, выделенной, но не использованной под размещение данных. Освобождение свободной памяти производится при закрытии набора данных. Так, параметр SPACE=(TRK,(40,,8),RLSE) указывает, что запрашивается 40 дорожек без приращения. Для оглавления выделяется восемь блоков. Незанятая память после закрытия набора данных освобождается.
Параметр LABEL чаще всего используется для описания набора данных на магнитной ленте. В нем могут быть указаны порядковый номер набора данных на МЛ, тип метки, срок хранения набора данных, пароль. Наиболее употребительный формат параметра:
LABEL=([номер][,формат][PASSWORD][,IN|,OUT])
Подпараметр номер задает последовательный номер набора данных на ленточном томе.
Значения 0 или 1 указывают на первый по порядку набор данных. Для каталогизированных наборов данных, а также наборов данных, передаваемых из предыдущего шага задания (DISP=,PASS) , номер можно не указывать.
Подпараметр формат указывает используемый стандарт форматирования ленточного тома (тип меток наборов данных). Возможны следующие значения формата:
SL - стандартный формат IBM (используется по умолчанию, можно не указывать);
SUL - указывает, где набор данных имеет стандартные метки и метки пользователя;
AL - используется формат ISO/ANSI;
NSL - набор данных имеет нестандартные метки;
NL - набор данных не имеет меток;
BLP - необходимо обойти обработку метки набора данных.
Подпараметр, задаваемый ключевым словом PASSWORD, требует при изменении набора данных, чтобы пользователь ввел правильный пароль, используя консоль или терминал TSO.
Ключевые слова IN и OUT указывают, что набор данных обрабатывается для ввода или вывода соответственно.
В приводимом ниже примере открывается для чтения 5-й набор данных, имеющий нестандартные метки, на ленточном томе TAPE01:
//DD1 DD DSNAME=NAB1,UNIT=TAPE01, // VOL=SER=MT1,LABEL=(5,NSL,,IN)
Параметр SYSOUT идентифицирует набор данных как системный выходной набор данных. Наиболее употребительная форма для записи параметра:
SYSOUT=(выходной_класс[,имя_прог])
Чаще всего подпараметр выходной_класс определяет имя выходного класса для описываемого набора данных в виде символа А-Z или 0-9. Атрибуты выходных классов определяются при настройке JES. Если в качестве значения выходного класса указана звездочка (*), это означает, что следует использовать то же значение, что у параметра MSGCLASS, определенное в операторе JOB. Символ "запятая" (,) в позиции данного подпараметра задает так называемый "пустой" класс, означающий, что основные атрибуты вывода будут определены в операторе задания OUTPUT, ссылка на который должна быть указана далее с помощью параметра OUTPUT.
Подпараметр имя_прог позволяет указать имя программы (загрузочного модуля), обрабатывающей выходной набор данных.
Если подпараметр не указан, JES будет обрабатывать выходной набор данных стандартным способом, определенным для соответствующего класса.
Кроме указанных подпараметров, параметр SYSOUT может использовать подпараметры, управляющие форматированием выходного набора данных при выводе на печать (выбор шрифта, межстрочный интервал, размеры полей, количество копий и т.п.)
Примеры использования параметра SYSOUT:
- определение выходного класса B:
//SYSPRINT DD SYSOUT=B - определение выходного класса по значению MSGCLASS:
//YSl JOB ,,MSGCLASS=A //ST1 EXEC PGM=ZARPLATA //DD1 DD SYSOUT=* - определение пустого выходного класса и ссылки на оператор OUTPUT:
//OUT1 OUTPUT BURST=Y,CHARS=(GT12),COPIES=3 ... //DS DD SYSOUT=(,),OUTPUT=*.OUT1 - обработка выходного набора данных программой ввода заданий INTRDR:
//SYSUT2 DD SYSOUT=(X,INTRDR)
Итак, мы рассмотрели небольшую часть из общего числа параметров оператора DD, однако наиболее важную с точки зрения практического использования. Рассмотрим ряд примеров описания наборов данных при решении некоторых типовых задач [15].
- Описание каталогизированных наборов данных на DASD. В этом случае достаточно указать только параметры DSN и DISP, поскольку остальную необходимую информацию о размещении набора данных система получит из каталога, например:
//CATDS1 DD DSN=AS30.MY.DSET,DISP=OLD //CATDS2 DD DSN=LIB.DATA(CHAR),DISP=SHR - Описание некаталогизированных наборов данных на DASD. Здесь требуется указывать дополнительно значения параметров UNIT и VOLUME, например:
//NOCATDS DD DSNAME=AS30.MY.DSET,DISP=OLD, // VOL=SER=D01457,UNIT=3390 - Описание нового non-SMS набора данных на жестких магнитных дисках. Требуется задавать параметры DCB и SPACE. В приводимом ниже примере создается библиотечный набор данных со 120-байтными записями фиксированной длины на выделенном пространстве внешней памяти размером 10 цилиндров с приращением в три цилиндра. На оглавление отводится два блока по 256 байт, при завершении шага задания неиспользуемая память будет освобождена, а набор данных сохранен.
//NEWDS DD DSNAME=D.AS32.DATA,DISP=(NEW,KEEP), // VOL=SER=BIBLIO,UNIT=3380, // DCB=(RECFM=F,LRECL=120), // SPACE=(CYL,(10,3,2),RLSE)