使用 OPNQRYF 按字段的子字符串排序
Ordering by sub string of a field with OPNQRYF
我有一个要求,我需要更改记录在报告中的打印顺序。我需要按记录字段的子字符串对记录进行排序。
在调用报告RPG之前有如下OPNQRYF:
OVRDBF FILE(MOHDL35) SHARE(*YES)
BLDQRYSLT QRYSLT(&QRYSLT) +
SELECT((CHARDT *GE &FRDATE F2) +
(CHARDT *LE &TODATE F2) +
(HDPLVL *EQ 'FS' F2) +
(HDMPLT *EQ &PLANT F2))
OPNQRYF FILE((*LIBL/MOHDL35)) +
QRYSLT(&QRYSLT) +
KEYFLD(*FILE) +
MAPFLD((ZONEDT HDAEDT *ZONED 8 0) +
(CHARDT ZONEDT *CHAR 8))
我看到如何执行此操作的一种方法是执行 运行SQL 以按要求的顺序在 qtemp 中使用 MOHDL35 记录创建一个临时文件 table。 substr SQL 函数将有助于更轻松地实现这一目标。这应该具有与 MOHDL35 相同的结构(字段名称,记录格式)
然后用新创建的table名称替换RPG程序中对这个文件的使用。我还没有尝试过,但这行得通吗?这听起来是个好主意吗?有没有更好的建议?
我会尝试创建一个包含所有 table 字段和子字符串列的视图,然后使用 OPNQRYF 而不是 table,将子字符串列指定为键盘。这可能比每次都将整个批次复制到 QTEMP 更简单(并且可能更快)。
您可以通过使用 MAPFLD
参数对 OPNQRYF
执行此操作,如下所示:
OPNQRYF FILE((JCVCMP))
KEYFLD((*MAPFLD/PART))
MAPFLD((PART '%SST(VCOMN 2 5)'))
JCVCOMN
中的字段现在排序如下:
VENNO VCMTP VCMSQ VCOMN
----- ----- ----- -------------------------
1,351 ICL 3 Let's see what wow
1,351 ICL 1 This is a test
1,351 NDA 2 another comment
1,351 NDA 1 more records
请注意,记录按 VCOMN 的子字符串从第二个字符开始排序。
这是你的 OPNQRYF
指定了多个关键字段
OPNQRYF FILE((*LIBL/MOHDL35))
QRYSLT(&QRYSLT)
KEYFLD((*MAPFLD/CHARDT) (*MAPFLD/HDPROD))
MAPFLD((ZONEDT HDAEDT *ZONED 8 0) (CHARDT ZONEDT *CHAR 8)
(HDPROD '%SST(HDPROD 1 2) *CAT %SST(HDPROD 10 12)
*CAT %SST(HDPROD 13 16)'))
一些注意事项:我猜 HDAEDT 是一个 PACKED
数字。如果是这样,您无需将其映射到 ZONED
数字即可将其转换为字符值。如果您需要 ZONED
值,那没问题(但 PACKED
应该也能正常工作)。否则,您可以使用:
MAPFLD((CHARDT HDAEDT *CHAR 8))
同样在您的 OVRDBF
中,您需要确保选择了正确的覆盖范围 OVRSCOPE
。 IBM 默认值为 OVRSCOPE(*ACTGRPDFN)
。 OPNQRYF 也有一个作用域 OPNSCOPE
。您需要确保 OVRSCOPE
、OPNSCOPE
和使用 table 的程序都使用相同的激活组。有很多不同的组合。如果你不能让它工作,你总是可以将它们全部更改为 *JOB
,这样就可以了。但是 OPNQRYF
并没有任何内在因素阻止它从 CLP 工作。
我有一个要求,我需要更改记录在报告中的打印顺序。我需要按记录字段的子字符串对记录进行排序。
在调用报告RPG之前有如下OPNQRYF:
OVRDBF FILE(MOHDL35) SHARE(*YES)
BLDQRYSLT QRYSLT(&QRYSLT) +
SELECT((CHARDT *GE &FRDATE F2) +
(CHARDT *LE &TODATE F2) +
(HDPLVL *EQ 'FS' F2) +
(HDMPLT *EQ &PLANT F2))
OPNQRYF FILE((*LIBL/MOHDL35)) +
QRYSLT(&QRYSLT) +
KEYFLD(*FILE) +
MAPFLD((ZONEDT HDAEDT *ZONED 8 0) +
(CHARDT ZONEDT *CHAR 8))
我看到如何执行此操作的一种方法是执行 运行SQL 以按要求的顺序在 qtemp 中使用 MOHDL35 记录创建一个临时文件 table。 substr SQL 函数将有助于更轻松地实现这一目标。这应该具有与 MOHDL35 相同的结构(字段名称,记录格式)
然后用新创建的table名称替换RPG程序中对这个文件的使用。我还没有尝试过,但这行得通吗?这听起来是个好主意吗?有没有更好的建议?
我会尝试创建一个包含所有 table 字段和子字符串列的视图,然后使用 OPNQRYF 而不是 table,将子字符串列指定为键盘。这可能比每次都将整个批次复制到 QTEMP 更简单(并且可能更快)。
您可以通过使用 MAPFLD
参数对 OPNQRYF
执行此操作,如下所示:
OPNQRYF FILE((JCVCMP))
KEYFLD((*MAPFLD/PART))
MAPFLD((PART '%SST(VCOMN 2 5)'))
JCVCOMN
中的字段现在排序如下:
VENNO VCMTP VCMSQ VCOMN
----- ----- ----- -------------------------
1,351 ICL 3 Let's see what wow
1,351 ICL 1 This is a test
1,351 NDA 2 another comment
1,351 NDA 1 more records
请注意,记录按 VCOMN 的子字符串从第二个字符开始排序。
这是你的 OPNQRYF
指定了多个关键字段
OPNQRYF FILE((*LIBL/MOHDL35))
QRYSLT(&QRYSLT)
KEYFLD((*MAPFLD/CHARDT) (*MAPFLD/HDPROD))
MAPFLD((ZONEDT HDAEDT *ZONED 8 0) (CHARDT ZONEDT *CHAR 8)
(HDPROD '%SST(HDPROD 1 2) *CAT %SST(HDPROD 10 12)
*CAT %SST(HDPROD 13 16)'))
一些注意事项:我猜 HDAEDT 是一个 PACKED
数字。如果是这样,您无需将其映射到 ZONED
数字即可将其转换为字符值。如果您需要 ZONED
值,那没问题(但 PACKED
应该也能正常工作)。否则,您可以使用:
MAPFLD((CHARDT HDAEDT *CHAR 8))
同样在您的 OVRDBF
中,您需要确保选择了正确的覆盖范围 OVRSCOPE
。 IBM 默认值为 OVRSCOPE(*ACTGRPDFN)
。 OPNQRYF 也有一个作用域 OPNSCOPE
。您需要确保 OVRSCOPE
、OPNSCOPE
和使用 table 的程序都使用相同的激活组。有很多不同的组合。如果你不能让它工作,你总是可以将它们全部更改为 *JOB
,这样就可以了。但是 OPNQRYF
并没有任何内在因素阻止它从 CLP 工作。