[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

OpenVMS 用户手册


前页 目录 索引

9.4 以批量作业方式运行 Sort

批量作业是独立于当前对话期而运行的程序或 DCL 命令过程。如果要排序大文件,那么考虑把 Sort 操作提交为一个批量作业,因为排序将需要一些时间。有关批量作业和命令过程的详情,请参阅 第 16 章 第 13 章第 14 章

9.4.1 命令过程

在命令过程中指定 SORT 命令,就象在屏幕上写入它。如果默认目录不包含要排序的文件,就明确地在命令过程中设置默认目录,或者在命令文件说明中包括这个目录。

以下例子提交 DCL 命令过程 SORTJOB.COM 为一个批量作业。在命令行后,展示命令过程的文本:


$ SUBMIT SORTJOB


! SORTJOB.COM
!
$ SET DEFAULT [USER.PER]   ! Set default to location of input
$ SORT/KEY=(POSITION:10,SIZE:15) EMPLOYEE.LST BYNAME.LST
$ TYPE BYNAME.LST
$ EXIT

9.4.2 包括输入记录

在批量作业中可以包括输入记录,把它们放在 SORT 命令之后,每行一个记录。个别排序记录可以比一行长。

如同使用终端输入记录,指定输入文件参数为 SYS$INPUT。使用 /FORMAT 限定词指定以字节为单位的记录大小和以块为单位的近似文件大小。大约 6 个 80 个字符行等于一块。

以下例子示范在命令过程中包括输入记录:


$ SUBMIT SORTJOB


! SORTJOB.COM
!
$ SET DEFAULT [USER.PER]
$ SORT/KEY=(POSITION:10,SIZE:15) -
SYS$INPUT-
/FORMAT=(RECORD_SIZE:24,FILE_SIZE:10) -
BYNAME.LST
$ DECK
BST 7828 MCMAHON JANE
ADM 7933 ROSENBERG HARRY
COM 8102 KNIGHT MARTHA
ANS 8042 BENTLEY PETER
BIO 7951 LOWELL FRANK
$ EOD

9.5 合并文件

MERGE 命令把多达 10 个 (高性能 Sort/Merge 公用程序支持多达 12 个) 排序的文件组合成一个排序的输出文件。可以合并具有同样格式和通过同样键字段排序的输入文件。

按照默认,Merge 检查输入文件中记录的顺序,以确信它们是已排序的。如果不要 Merge 检查次序,就指定 /NOCHECK_SEQUENCE 限定词。如果指定 /CHECK_SEQUENCE 限定词而一个记录次序颠倒 (例如,如果没有排序一个输入文件),Merge 就报告以下出错:


%SORT-W-BAD_ORDER, merge input is out of order
 

使用 MERGE 命令时可以带与 SORT 命令同样的限定词,但有两个例外:

  • 不能为 Merge 操作指定一个进程 (/PROCESS)。
  • /CHECK_SEQUENCE 限定词只用于合并操作。

在以下例子中,文件 BYNAME1.LST 和 BYNAME2.LST 已经按雇员名升序排序。展示的命令将它们合并:


$ MERGE BYNAME1.LST,BYNAME2.LST BYNAME3.LST

输出文件 BYNAME3.LST 包含来自这两个文件 (即,BYNAME1.LST 和 BYNAME2.LST) 的所有记录,如下图所示:


9.5.1 排序的文件

要合并使用特定键排序的文件,必须在 MERGE 命令行上对 /KEY 限定词指定同样的键。

如果不指定一个键,Merge 使用 9.2 节描述的默认键。

在以下例子中,文件 BILLING1.LST 和 BILLING4.LST 按帐号排序 (/KEY=POSITION:5,SIZE:4,DECIMAL)。要把这些文件合并到输出文件 MAILING.LST,输入以下命令行:


$ MERGE/KEY=(POSITION:5,SIZE:4,DECIMAL) -
_$ BILLING1.LST,BILLING4.LST MAILING.LST

合并结果如下所示:


如果想要以排序的次序合并文件,那么指定 /NOCHECK_SEQUENCE 限定词可以阻止顺序检查。

9.5.2 同样的键字段

如同 Sort 操作,当输入文件包含同键的字段记录时,Merge 不必维持记录在输入文件中的同样次序。要维持同键记录的输入次序,在 MERGE 命令行上指定 /STABLE 限定词。只要保留同键记录的一个副本,指定 /NODUPLICATES 限定词。

9.6 从终端输入记录

想要排序或合并的记录不一定来自一个文件。当输入 SORT 或 MERGE 命令时,可以直接从终端输入记录。以下表格描述这个过程:

步骤 任务
1 在 SORT 或 MERGE 命令行上,指定 SYS$INPUT 为输入文件。

使用输入文件限定词 /FORMAT 指定以字节为单位的最长记录大小,和输入文件以块为单位的近似大小。

2 在连续行上输入记录。

每按下 Return 就结束一个记录。

3 按下 Ctrl/Z 结束文件。

以下例子示范一个 Sort 操作,它排序的输入记录直接从终端输入:


$ SORT/KEY=(POSITION:8,SIZE:15) -
_$ SYS$INPUT/FORMAT=(RECORD_SIZE:24,FILE_SIZE:10) BYNAME.LST
BST 7828 MCMAHON JANE
ADM 7933 ROSENBERG HARRY
COM 8102 KNIGHT MARTHA
ANS 8042 BENTLEY PETER
BIO 7951 LOWELL FRANK

这串命令建立包含排序记录的输出文件 BYNAME.LST。

9.7 使用 Sort/Merge 说明文件

Sort/Merge 允许您在说明文件中维护排序定义,并指定更复杂的排序准则。(高性能 Sort/Merge 公用程序不支持说明文件。对这个特性的实现留待将来的 OpenVMS Alpha 发行版本。) 可以使用任何标准编辑程序,或 DCL CREATE 命令建立一个说明文件。

Sort/Merge 说明文件允许您:

  • 选择 Sort/Merge 操作包括的记录
  • 重新格式化输出文件的记录
  • 使用条件键或数据
  • 指定多个记录格式
  • 建立或修改一个比较顺序
  • 重新指派工作文件
  • 存储频繁使用的 Sort/Merge 操作

在完成说明文件后,使用 /SPECIFICATION 限定词指定文件名。说明文件的默认文件类型是 .SRT。

说明文件的每个命令应该以一个斜杠 (/) 开始。如果一个命令跨越一行以上,不需要连续字符。

注意

在说明文件使用的许多限定词类似于在 Sort/Merge 命令行使用的 DCL 限定词。然而,要注意这些限定词的语法可以不同。例如,在 DCL 级的 /KEY 限定词与在说明文件中的 /KEY 限定词有不同的语法。有关说明文件限定词的概要,请参阅 9.9.3 节

在命令行中指定的任何 DCL 命令限定词取代在说明文件中的相应条目。例如,如果在 DCL 命令行中指定 /KEY 限定词,Sort/Merge 就忽略在说明文件中的 /KEY 子句。

一般,在说明文件中指定限定词时,对次序没有特殊的要求。然而,在以下情况下次序是重要的:

  • 按一个以上键字段排序,如果没有指定 NUMBER:n 键元素
  • 描述输出格式
  • 定义多个记录类型

对 /COLLATING_SEQUENCE 限定词指定 FOLD、MODIFICATION 和 IGNORE 关键字时,应该在任何 FOLD 子句之前指定所有 MODIFICATION 和 IGNORE 子句。有关 /COLLATING_SEQUENCE 限定词的详情,请参阅 9.9.3 节

在说明文件中可以包括注释,每个注释行由一个感叹号 (!) 开始。与 DCL 命令行不同,说明文件不需要连字号 (-) 续行。

例子

  1. 这是一个说明文件的例子,可以用来按升序排序负数和正数数据:


    ! 按升序排序负数和正数数据
    ! 的说明文件
    !
    /FIELD=(NAME=SIGN,POS:1,SIZ:1)  (1)
    /FIELD=(NAME=AMT,POS:2,SIZ:4)   (2)
    /CONDITION=(NAME=CHECK1,        (3)
              TEST=(SIGN EQ "-"))
    /CONDITION=(NAME=CHECK2,        (4)
              TEST=(SIGN EQ " "))
    /INCLUDE=(CONDITION=CHECK1,     (5)
              KEY=(AMT,DESCENDING),
              DATA=SIGN,
              DATA=AMT)
    /INCLUDE=(CONDITION=CHECK2,     (6)
              KEY=(AMT,ASCENDING),
              DATA=SIGN,
              DATA=AMT)
    

    检查说明文件时,注意以下几点:
    1. 这个命令行定义一个开始于记录的第 1 字节并且是 1 字节长的字段。它为这个字段指派名称 SIGN。
    2. 这个命令行定义一个开始于记录的第 2 字节并且是 4 字节长的字段。它为这个字段指派名称 AMT。
    3. 这是一个条件语句。如果在 SIGN 字节中有一个负号 ( - ),满足 CHECK1 条件。
    4. 这是 一个条件语句。如果 SIGN 字节是空白,满足 CHECK2 条件。
    5. 如果满足条件 CHECK1,记录按降序排序。
    6. 如果满足条件 CHECK2,则记录按升序排序。

    图 9-8 展示在输入文件 BALANCES.LIS 上使用说明文件的结果。

    图 9-8 使用说明文件的输出


  2.  


    /FIELD=(NAME=RECORD_TYPE,POS:1,SIZ:1)   ! 记录类型,1 字节
    /FIELD=(NAME=PRICE,POS:2,SIZ:8)         ! 价格,两个文件
    /FIELD=(NAME=TAXES,POS:10,SIZ:5)        ! 税,两个文件
    /FIELD=(NAME=STYLE_A,POS:15,SIZ:10)     ! 样式,格式化 A 文件
    /FIELD=(NAME=STYLE_B,POS:20,SIZ:10)     ! 样式,格式化 B 文件
    /FIELD=(NAME=ZIP_A,POS:25,SIZ:5)        ! 邮政编码,格式化 A 文件
    /FIELD=(NAME=ZIP_B,POS:15,SIZ:5)        ! 邮政编码,格式化 B 文件
    /CONDITION=(NAME=FORMAT_A,              ! 条件测试,格式化 A
                TEST=(RECORD_TYPE EQ "A"))
    /CONDITION=(NAME=FORMAT_B,              ! 条件测试,格式化 B
                TEST=(RECORD_TYPE EQ "B"))
    /INCLUDE=(CONDITION=FORMAT_A,           ! 输出格式,类型 A
                KEY=ZIP_A,
                DATA=PRICE,
                DATA=TAXES,
                DATA=STYLE_A,
                DATA=ZIP_A)
    /INCLUDE=(CONDITION=FORMAT_B,           ! 输出格式,类型 B
                KEY=ZIP_B,
                DATA=PRICE,
                DATA=TAXES,
                DATA=STYLE_B,
                DATA=ZIP_B)
    

    在这个例子中,根据说明文件指定的指令,排序来自一个地产代理的两个分公司的两个输入文件。在第一个文件中第一个位置开始于 A 的记录有这个格式:


           |A|PRICE|TAXES|STYLE|ZIP|
            1 2     10    15    25
    

    在第二个文件中第一个位置开始于 B 的记录有位置调转的样式和邮政编码字段,如下所示:


           |B|PRICE|TAXES|ZIP|STYLE|
            1 2     10    15  20
    

    要按记录 A 的格式以邮政编码字段排序这两个文件,首先用 /FIELD 限定词定义这两个记录的字段。然后,用 /CONDITION 限定词指定一个测试区别这两类记录。最后,/INCLUDE 限定词在输出时把类型 B 的记录格式更改为类型 A 的记录格式。
    注意,如果在 /INCLUDE 限定词中指定键或数据字段,必须在 /INCLUDE 限定词中为 Sort 操作明确地指定所有键和数据字段。
    也要注意,排序时会省略不是类型 A 也不是类型 B 的记录。
  3.  


    /COLLATING_SEQUENCE=(SEQUENCE=
    ("AN","EB","AR","PR","AY","UN","UL",
    "UG","EP","CT","OV","EC","0"-"9"),
    MODIFICATION=("'"="19"),
    FOLD)
    

    这个 /COLLATING_SEQUENCE 限定词指定一个用户自定义顺序,按年代顺序为每个月给出一个唯一值。例如,如果想要根据日期排序文件 SEMINAR.DAT,那么文件 SEMINAR.DAT 将被设置如下:


           16 NOV 1983   Communication Skills
           05 APR 1984   Coping with Alcoholism
           11 Jan '84    How to Be Assertive
           12 OCT 1983   Improving Productivity
           15 MAR 1984   Living with Your Teenager
           08 FEB 1984   Single Parenting
           07 Dec '83    Stress --- Causes and Cures
           14 SEP 1983   Time Management
    

    主键是年字段;辅助键是月字段。因为月字段不是数字,而想要按年代顺序排序月份,因此必须定义自己的比较顺序。可以这样做,即按年代顺序排序每个月份的后两个字母,即为每个月份给出唯一键值。
    MODIFICATION 任选项指定省略号 (') 等同于 19,从而允许比较 '83 和 1984。FOLD 任选项指定大写字母和小写字母视为相同。
    这个 Sort 操作的输出如下所示:


           14 SEP 1983   Time Management
           12 OCT 1983   Improving Productivity
           16 NOV 1983   Communication Skills
           07 Dec '83    Stress --- Causes and Cures
           11 Jan '84    How to Be Assertive
           08 FEB 1984   Single Parenting
           15 MAR 1984   Living with Your Teenager
           05 APR 1984   Coping with Alcoholism
    

    有关建立用户自定义比较顺序的其他例子,请参阅 9.3 节
  4.  


    /FIELD=(NAME=AGENT,POSITION:20,SIZE:15)
    /CONDITION=(NAME=AGENCY,
                TEST=(AGENT EQ "Real-T Trust"
                OR
                AGENT EQ "Realty Trust"))
    /DATA=(IF AGENCY THEN "Realty Trust" ELSE AGENT)
    

    在这个例子中,两个地产文件被排序。一个文件称一个代理为 Real-T Trust;另一个文件称同一代理为 Realty Trust。/CONDITION 和 /DATA 限定词指示 Sort 把在排序的输出文件中的 AGENT 字段列为 Realty Trust。
  5.  


    /FIELD=(NAME=ZIP,POSITION:60,SIZE:6)
    /CONDITION=(NAME=LOCATION,
                TEST=(ZIP EQ "01863"))
    /KEY=(IF LOCATION THEN 1
          ELSE 2)
    

    在这个例子中,所有带邮政编码 01863 的记录将出现在排序的输出文件的开始。条件测试是在用 /FIELD 限定词定义的 ZIP 字段;条件被命名为 LOCATION。在这个 /KEY 限定词的值 1 和 2 表示那些满足和不满足条件记录的相对次序。
  6.  


    /FIELD=(NAME=ZIP,POSITION:60,SIZE:6)
    /CONDITION=(NAME=LOCATION,
                TEST=(ZIP EQ "01863"))
    /DATA=(IF LOCATION THEN "NORTH CHELMSFORD"
           ELSE "Outside district")
    

    在这个例子中,/CONDITION 限定词测试 01863 邮政编码。/DATA 限定词指定城镇字段名称将添加到输出记录,视测试结果而定。
  7.  


    /FIELD=(NAME=FFLOAT,POS:1,SIZ:0,F_FLOATING)
    /CONDITION=(NAME=CFFLOAT,TEST=(FFLOAT GE 100))
    /OMIT=(CONDITION=CFFLOAT)
    

    在这个例子中,这个数 100 被认为是一个 F_FLOATING 数据类型,因为在 /FIELD 限定词中字段 FFLOAT 被定义为 F_FLOATING,。
  8.  


    /FIELD=(NAME=AGENT,POSITION:1,SIZE:5)
    /FIELD=(NAME=ZIP,POSITION:6,SIZE:3)
    /FIELD=(NAME=STYLE,POSITION:10,SIZE:5)
    /FIELD=(NAME=CONDITION,POSITION:16,SIZE:9)
    /FIELD=(NAME=PRICE,POSITION:26,SIZE:5)
    /FIELD=(NAME=TAXES,POSITION:32,SIZE:5)
    /DATA=PRICE
    /DATA="  "
    /DATA=TAXES
    /DATA="  "
    /DATA=STYLE
    /DATA="  "
    /DATA=ZIP
    /DATA="  "
    /DATA=AGENT
    

    /FIELD 限定词定义输入文件记录的字段有以下格式:


    AGENT ZIP STYLE CONDITION PRICE TAXES
    

    /DATA 限定词,使用 /FIELD 限定词定义的 field-names,重新格式化记录来建立具有以下格式的输出记录:


    PRICE TAXES STYLE ZIP AGENT
    

9.8 优化 Sort 或 Merge 操作

根据排序环境,有几种方法可以提高 Sort 或 Merge 操作的效率。在 SORT 或 MERGE 命令中使用 /STATISTICS 限定词可获得有关排序环境中变量的信息。

在检查统计显示后,考虑以下几节提出的任何优化任选项。

当输入 SORT 或 MERGE 命令使用 /STATISTICS 限定词时,可看到类似以下的输出:


$ SORT/STATISTICS PAGEANT.LIS DOCUMENT.LIS
                  OpenVMS Sort/Merge Statistics

Records read:           3 (1)     Input record length:       26
Records sorted:         3        Internal length:           28
Records output:         3        Output record length:      26
Working set extent: 16384 (2)     Sort tree size:            42
Virtual memory:       392        Number of initial runs:     0
Direct I/O:            10        Maximum merge order:        0
Buffered I/O:          11        Number of merge passes:     0
Page faults:          158 (3)     Work file allocation:       0 (4)
Elapsed time: 00:00:00.54        Elapsed CPU:      00:00:00.03 (5)

当检查这些字段时,注意以下几点:

  1. 读取记录
    列出在 Sort 操作期间读取的记录数。有关选择性地从 Sort 操作省略记录的详情,请参阅 9.8.2 节
  2. 工作区范围
    展示保留多少块存储器执行排序操作。有关扩大工作区的详情,请参阅 9.8.4 节
  3. 页故障
    展示操作系统多少次把部分进程从物理内存传输到分页设备。有关阻止分页的详情,请参阅 9.8.4 节
  4. 工作文件分配
    展示为工作文件保留多少磁盘空间。有关工作文件的详情,请参阅 9.8.3 节
  5. CPU 使用时间
    展示操作系统使用多少 CPU 时间处理排序操作。有关通过挑选不同排序方法节省时间的详情,请参阅 9.8.1 节

9.8.1 排序进程

内部排序数据时 Sort 定义以下四个进程: 记录、标签、地址或索引。(高性能 Sort/Merge 公用程序只支持记录进程。对标签、地址和索引进程的实现留待将来的 OpenVMS Alpha 发行版本。) RECORD 是默认进程。挑选进程的类型影响 Sort 操作性能和存储需求。有关不同排序进程的详情,请参阅 9.2.6 节

在选择排序进程之前,考虑以下几点:

  • 如何使用输出文件
    • 因为记录和标签排序产生包含整个排序记录的文件,因此这些重新排序的文件就绪待用。
    • 地址和索引排序的输出文件可以被用一种程序设计语言例如 Pascal、Fortran、MACRO 或 C 编写的程序处理。
    • 地址排序建立一个包含指针的输出文件,每个指针指向输入文件的记录。当排序多个输入文件时,这个列表包括二进制的 RFA 和一个文件号。程序使用指针存取记录。
    • 当排序多个文件时,索引排序建立一个包含 RFA、键字段和一个文件号的输出文件。这些键字段的格式与输入文件一样。如果程序将来处理时需要键字段的内容,那么选择索引排序,而不使用地址排序。

    如果针对不同用途需要用几种方法从一个文件重新排序文件记录,那么存储来自地址或索引排序的几个输出文件。按想要的排序次序,使用输出文件存取主文件的记录。
  • 可用于排序的临时存储空间
    标签排序比记录排序使用较少的临时存储空间。因为 记录排序在排序时保持记录原样,因此当文件比较大时,它使用很多工作空间。地址和索引排序使用很少的临时存储空间。
  • 使用的输入和输出设备类型
    记录排序进程只可以接受读卡机、磁带和磁盘的输入。标签和记录排序的输出可以写入任何输出设备。地址和索引排序的输出必须写入能够接受二进制数据的设备。
  • 速度差别
    如果在操作中计划检索排序的记录,那么记录排序通常是最快的进程。否则,地址和索引排序是最快的进程。


前页 后页 目录 索引