0

我正在做考勤系统,其中我的物理文件(PF)具有以下字段:

User ID(key field),Date,Time In,Time Out
......

问题是,我尝试选择特定的用户 ID 和日期以及当天的最高超时值。并将超时值移动到我程序中的变量中。

RPGLE 源代码会是什么样子?

4

3 回答 3

3

传统的方法是构建一个以用户 ID、日期和超时为键的逻辑文件,日期和超时降序。然后我认为只是使用用户 ID 和今天的日期作为部分键链接到逻辑将为您提供最新记录。

于 2012-07-11T12:03:18.890 回答
2

嵌入式 SQL 也可以:

SELECT MAX(timeout) 
INTO :outTime  
FROM PF 
WHERE userid = :selected_user_id
AND date = :selected_date`
于 2012-07-11T13:44:09.133 回答
2

假设您有一个员工档案和一个工作时间档案,如您所描述的。并且您想要报告给定日期每位员工的最早上班时间和最晚时间超时时间。

因此,您可能有一个读取员工文件的循环,并且在该循环中,您可以链接到@Martin 描述的逻辑以获得最后一次超时,以及另一个以递增时间为键的逻辑以获得那里的最小值.

使用 SQL,您可以在一次读取(SQL 中获取)中获取员工文件信息,以及最早的时间和最晚的时间。它大大简化了循环内的代码,不是吗?

所以这是伪代码的基本流程:

Declare a cursor with your SQL statement
Open the cursor
Fetch a row from the cursor
DoWhile status is ok
    Process your data
    Fetch the next record
EndDo
Close the cursor

看起来不会太吓人吧?所以让我们看看代码可能是什么样子。当然,在 SQL 中可以做的方法不止一种,但让我们从一个简单的 SQL Select 语句开始。当您在 SQL 中使用 RPG 变量时,您需要在它们前面加上一个冒号 (':')。

    WITH h as
    ( SELECT empID, min(timein) as firstin, max(timeout) as lastout
        FROM workhours
        WHERE workdate = :myvariable
        GROUP BY empID
    )
    SELECT e.lastname, e.firstname, e.empnbr, h.firstin, h.lastout
      FROM h
      JOIN employees as e   on h.empID = e.empnbr
      ORDER BY e.lastname, e.firstname, e.empnbr;

嗯,这是一个相当不错的 SELECT 语句,是吗?发生了很多事情。

但它分为两部分。第一部分是一个名为 h 的表表达式,我们在其中获取每个员工在该日期的时间。第二部分列出了我们想要的所有结果字段,这些字段取自表表达式 h 和员工文件,我们可以匹配两个文件中的员工编号。这些行将按姓氏、名字和员工编号排序给我们。

所以让我们把它放在RPG中。

EXEC-SQL  DECLARE CURSOR C1 AS
              WITH h as
              ( SELECT empID, min(timein) as firstin, max(timeout) as lastout
                  FROM workhours
                  WHERE workdate = :myvariable
                  GROUP BY empID
              )
              SELECT e.lastname, e.firstname, e.empnbr, h.firstin, h.lastout
                FROM h
                JOIN employees as e   on h.empID = e.empnbr
                ORDER BY e.lastname, e.firstname, e.empnbr
                FOR READ ONLY;
EXEC-SQL  OPEN C1;
EXEC-SQL  FETCH FROM C1
            INTO :lname, :fname, :emp, :firsttime, :lasttime;
DoW &subst(SQLState,1,2) = '00';
    //
    // perform processing here
    //
    EXEC-SQL  FETCH FROM C1
                INTO :lname, :fname, :emp, :firsttime, :lasttime;
enddo;
EXEC-SQL  CLOSE C1;

现在您可能首先犹豫游标中的 SELECT 语句正在完成多少工作。但是通过在那里完成所有这些操作,您已经简化了 I/O,并让 SQL 优化器发挥其魔力,以找到将数据提供给您的最快方法。

于 2012-07-14T00:36:47.113 回答