use*_*536 0 rpg rpgle ibm-midrange
比方说,例如,我有这些表:
USRMF(主物理文件)
User ID User Name
A00001 SAMUEL
A00002 ADAM
Run Code Online (Sandbox Code Playgroud)
USRTS
user id date time in time out
A000001 080812 084555 104545
A000001 080812 120800 150000
A000001 080812 170000 180000
A000001 090812 084555 104545
A000001 090812 170000 180000
A000002 080812 084555 104545
A000002 080812 120800 150000
A000002 080812 170000 190000
A000002 090812 084555 104545
A000002 090812 170000 190000
Run Code Online (Sandbox Code Playgroud)
我的子文件应该看起来像这样:
Option: 5-display
OPT User ID User Name Date TimeIn TimeOut
_ A000001 SAMUEL 090812 084555 180000
_ A000002 ADAM 090812 084555 190000
_ A000001 SAMUEL 080812 084555 180000
_ A000002 ADAM 080812 084555 190000
Run Code Online (Sandbox Code Playgroud)
*此子文件显示每个用户和每天的汇总数据:第一次进入和最后一次退出。该名称应从其他数据库表 (USRMF) 中读取,并应按时间卡日期排序。
如果用户将选项 5 放在第三个子文件行,其中用户 ID:A000001 用户名:samuel 和日期 090812,那么将显示下一个子文件屏幕。
OPT User ID User Name Date TimeIn TimeOut
_ A000001 SAMUEL 080812 084555 104545
_ A000001 SAMUEL 080812 120800 150000
_ A000001 SAMUEL 080812 170000 180000
Run Code Online (Sandbox Code Playgroud)
此子文件应列出所选日期和人员的所有进出时间。
我该怎么做这个程序??????????特别是对于第一个子文件。????
首先,任何 DBA 都会告诉您,如果您是从头开始创建的,请不要使用 DDS 来定义您的文件。从长远来看,如果用 SQL 定义它们会更好,如下所示:
CREATE TABLE USERMAST
(UserID char(7),
UserName char(25)
);
LABEL ON TABLE USERMAST is 'User Master Table';
CREATE TABLE WORKPERIOD
(UserID char(7),
WorkDay date,
StartTime time,
EndTime time
);
LABEL ON TABLE WORKPERIOD is 'User Work Periods';
Run Code Online (Sandbox Code Playgroud)
请注意,这是使用实际数据和时间字段,而不是数字字段。这使得根据需要更容易操作。运行 SQL 时,您可以指定日期和时间格式的首选项,例如 *ISO、*DMY 或 *EUR。您可以将其视为以 *ISO 格式存储,但以您希望的任何格式提供给您。
无论您的文件(表)是在 DDS 还是 SQL 中定义的,您仍然应该使用嵌入式 SQL 来读取程序中的数据。乍一看,它似乎比原生 I/O 更复杂。但是当您了解它时,您会发现它更强大、更容易、更快和更灵活。
嵌入 SQL 的基本概念实际上并不那么复杂。您的程序在自由格式的 ILE RPG 中可能是这样的(假设您正在使用):
EXEC SQL DECLARE CURSOR c1 FOR your-select-statement;
EXEC SQL OPEN c1;
do while SQLSTATUS is ok;
EXEC SQL FETCH FROM c1 INTO :var1, :var2, ... ;
if SQLSTATUS is ok;
// process data
endif;
enddo;
EXEC SQL CLOSE c1;
Run Code Online (Sandbox Code Playgroud)
通过检查 的前两个字符来检查数据的结尾或其他问题SQLSTATE。'00' 表示一切正常,'01' 是警告(可能不正常),其他一切都是错误。(这比使用更容易SQLCODE。)
你在你的 DECLARE CURSOR 语句中放置了一个 SELECT 语句(更具体地说是一个全选),它决定了当你从游标中提取时系统会给你什么。SELECT 可以做很多强大的事情。在这里,它将从两个表中获取信息并为您汇总行。如果你只是总结,它可能看起来像这样:
SELECT userid, workday, min(starttime) as firsttime, max(endtime) as lasttime
FROM workperiod
GROUP BY userid, workday
Run Code Online (Sandbox Code Playgroud)
如果您只是连接两个表中的数据,它可能如下所示:
SELECT u.userid, u.username, p.workday, p.starttime, p.endtime
FROM UserMast as u
JOIN WorkPeriod as p on u.userid = p.userid
Run Code Online (Sandbox Code Playgroud)
将这些放在一起的首选方法是这样的:
WITH s as
( SELECT userid, workday, min(starttime) as firsttime, max(endtime) as lasttime
FROM workperiod
GROUP BY userid, workday
)
SELECT u.userid, u.username, s.workday, s.firsttime, p.lasttime
FROM UserMast as u
JOIN WorkPeriod as p on u.userid = s.userid
ORDER BY workday descending, username
FOR INPUT ONLY
Run Code Online (Sandbox Code Playgroud)
有关使用 SQL 访问数据库的更多信息,请查看IBM i 信息中心。在数据库/参考下查看。有关显示文件的信息,请查看信息中心下的编程/DDS/DDS 显示文件,
就您的显示文件而言,您需要为每个子文件屏幕定义至少两种记录格式——子文件记录格式和子文件控制记录格式。
子文件记录用于列表中的一行。它应该有SFL关键字。
子文件控制记录管理屏幕。它通常包含子文件的屏幕标题和列标题。它应该有SFLCTL(yoursubfilename), SFLSIZ(subfile-rows), SFLPAG(rows-per-page), nn SFLDSP, nn SFLDSPCTL, nn SFLCLR, nn SFLEND(*MORE),其中 nn 表示条件指示符。您通常希望指定子文件行数比每页行数多 1。还包括此处的任何功能键规格。
您可能还需要屏幕底部的记录格式,以告诉用户可以使用哪些功能键。如果是,请OVERLAY在子文件控制记录上使用关键字。
1.) 关闭SFLDSP并SFLDSPCTL暂时防止它们显示在屏幕上。打开SFLCLR以启用创建空子文件。现在写入子文件控制记录。
2.) 在循环处理来自数据库的行中,增加子文件记录号,并写入子文件记录。
3.) 完成子文件记录的填写后:打开SFLDSP并SFLDSPCTL显示两者。关闭SFLCLR以便您的子文件记录不会被清除。打开SFLEND以便它会在每页底部显示“更多...”,最后一页除外。写下你的基础记录。EXFMT 你的子文件控制记录。根据需要处理任何功能键。
| 归档时间: |
|
| 查看次数: |
2258 次 |
| 最近记录: |