比方说,我有这些表:
USRMF(主要物理文件)
User ID User Name
A00001 SAMUEL
A00002 ADAM
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
我的子文件应该看起来像这样:
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
*此子文件显示每个用户的摘要数据&天: 第一次进入和最后一次出去。该名称应该从其他数据库表(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
此子文件应列出当天和所选人员的所有时间和超时时间。
我应该怎么做这个程序?????????特别是对于第一个子文件。?????
答案 0 :(得分:4)
首先,任何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';
请注意,这是使用实际数据和时间字段,而不是数字字段。这使得根据需要更容易操作。运行SQL时,可以指定日期和时间格式的首选项,例如* ISO,* DMY或* EUR。您可以将其视为以ISO 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;
检查SQLSTATE
的前两个字符,检查数据结束或其他问题。 '00'表示一切正常,'01'是警告(可能不行),其他一切都是错误。 (这比使用SQLCODE
更容易。)
您在DECLARE CURSOR语句中放置了一个SELECT语句(更具体地说是一个完整选择),它确定了当您从游标进行FETCH时系统将为您提供的内容。 SELECT可以做很多有力的事情。在这里,它将从两个表中获取信息并为您汇总行。如果您只是总结,可能如下所示:
SELECT userid, workday, min(starttime) as firsttime, max(endtime) as lasttime
FROM workperiod
GROUP BY userid, workday
如果您只是从两个表中加入数据,它可能如下所示:
SELECT u.userid, u.username, p.workday, p.starttime, p.endtime
FROM UserMast as u
JOIN WorkPeriod as p on u.userid = p.userid
把这些放在一起的首选方法是这样的:
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
有关使用SQL访问数据库的更多信息,请参阅IBM i Information Center。查看数据库/参考。有关显示文件的信息,请在编程/ 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你的子文件控制记录。处理任何适用的功能键。
答案 1 :(得分:0)
@WarrenT提供了一个很好的答案,即使您不喜欢SQL,也可以使用一般概念来加载和显示子文件。我们大多数人学到的方式是通过一本名为Application Display Programming指南的旧书。它在15年内没有改变。除此之外,我强烈建议你让一位同事告诉你小组其他人如何进行子文件编程。几乎可以肯定你想要符合风格问题。