【问题标题】:PL/I - How do I read a file in a loop without opening/closing the file multiple timesPL/I - 如何在不多次打开/关闭文件的情况下循环读取文件
【发布时间】:2016-09-16 13:30:57
【问题描述】:

我有一个程序正在读取文件 (FILE1)。对于 FILE1 中的每条记录,它都会获取字段“A”,并在 FILE2 中搜索以查找具有字段“B”匹配值的记录。当 A = B 时,两个文件中的一些字段被读出。该程序目前正在使用如下代码。但是,问题是我在循环中多次打开和关闭 FILE2。我在没有打开循环内的文件的情况下尝试了这个,但是如果我这样做,我会得到重复的记录,因为 FILE2 是从上一次搜索停止的地方读入的。每次从 FILE1 读取新记录时,有什么方法可以指向 File2 的开头?代码如下:

READ FILE(FILE1) INTO (IN_LAYOUT);
    DO WHILE (MORE_RECS1);
       OPEN FILE(FILE2);
       READ FILE(FILE2) INTO (IN_LAYOUT2);
       MORE_RECS2 = '1'B;
              DO WHILE (MORE_RECS2);
                 IF (A = B) THEN
                  DO;
                     VAL = VAL2;
                     WRITE FILE (OUFILE) FROM (OUT_LAYOUT);
                     S_MORE_RECS2 = '0'B;
                     CLOSE FILE(FILE2);
                  END; /* ENDIF */
                  ELSE READ FILE(FILE2) INTO (IN_LAYOUT2);
              END; /* INNER DOWHILE */
       READ FILE(FILE1) INTO (IN_LAYOUT);
    END; 

【问题讨论】:

  • 你试过在循环外打开文件吗?
  • 是的,但是问题是当我在file2中找到我需要的记录并写入记录时,我需要跳出循环以从file1中读取下一条记录。然后,当我再次开始阅读 file2 时,我不是从文件的开头开始。我从上次阅读结束的地方开始。 File2 通常有 40,000 条记录。
  • 尽量避免再考虑这个问题。重复打开/关闭的开销是巨大的。请记住,客户为资源付费。如果你只是吸吮他们,他们不会高兴的。 JOINKEYS 是一种可能性,具体取决于程序中的其他内容。或两个文件匹配(排序数据)。或者尝试将一个文件完全存储在程序中。或者尝试通过密钥访问数据。除了多次打开/关闭/读取之外的任何内容。即使您可以避免打开/关闭,您仍然有读取开销。哎哟。

标签: loops logic mainframe pl-i


【解决方案1】:

这看起来像一个匹配合并。首先尝试按您匹配的键对文件进行排序。

至少一些大型机排序实用程序具有内置的匹配合并功能,例如 Syncsort 具有 JOIN 运算符。我敢肯定 DFSORT 也有这个能力。

【讨论】:

  • 是的,DFSORT 有 JOINKEYS。
  • 谢谢,我刚刚尝试使用笛卡尔连接,但我仍然遇到问题。例如。第一个文件大约有 20 条记录,第二个文件大约有 40,000 条记录。因此,如果我对文件进行排序以使它们的顺序相同,那么第二个文件中的记录仍然相隔数千个位置。此外,在第一个文件中,我可能有一个键出现 5 次,而在第二个文件中只出现一次,所以我需要在第二个文件中找到该记录 5 次。我不确定这是否可以通过 SORT 逻辑完成。
  • @JackDonovan 如果出于某种原因您想要编写代码来执行此操作,您需要根据您在逻辑中匹配的键对两个文件进行排序。那么第二个文件中的所有记录将是相邻的,而不是相隔数千个地方。但是您的 SORT 实用程序可以为您完成匹配合并。
【解决方案2】:

在这种情况下,@cschneid 答案是最好的解决方案。为了完整起见,还有其他可用的解决方案:

  1. 对键上的 2 个输入文件进行排序,然后在您的程序中进行合并
  2. 将 File2 加载到 VSAM 文件中并进行索引查找

排序合并处理

如果您对键上的 2 个输入文件进行排序,您可以这样做:

DO WHILE (MORE_RECS1 and MORE_RECS2);
   if (key_file1 < key_file2) then do;
      READ FILE(FILE1) INTO (IN_LAYOUT);
   end; else if (key_file1 > key_file2) then do;
      READ FILE(FILE2) INTO (IN_LAYOUT2);
   end; else do;
      VAL = VAL2;
      WRITE FILE (OUFILE) FROM (OUT_LAYOUT);
      READ FILE(FILE1) INTO (IN_LAYOUT);
   end;
end;

当 Sort 的逻辑很复杂时(例如,您 需要数据库查找

将 File2 加载到 VSAM 文件中

另一种方法是将 File2 加载到 VSAM 文件中并进行键控读取。 这对于避免多次进行昂贵的数据库查找很有用 (尤其是 IMS,它不如 DB2 灵活)。

在大多数情况下,上面的 Sort-Merge 处理将比 VSAM 查找更快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多