Question

I'm doing time attendance system where my physical file(PF) have these fields:

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

the problem is,I try to select for particular User ID and Date and highest value of Time Out for that day. and move the Time Out value to a variable in my program.

how to the RPGLE source would look like?

Was it helpful?

Solution

The traditional way would be to build a logical file with User ID, Date and Time Out as keys, with Date and Time Out descending. Then I think just chaining to the logical using the User ID and today's date as a partial key will give you the latest record.

OTHER TIPS

Embedded SQL will also work:

SELECT MAX(timeout) 
INTO :outTime  
FROM PF 
WHERE userid = :selected_user_id
AND date = :selected_date`

Let's say you've got an employee file, and an time worked file, such as you described. And you want to report what was the earliest time-in, and the latest time-out, for each employee on a given day.

So you might have a loop reading the employee file, and in that loop, you could chain out to the logical that @Martin described to get the last time-out, and another logical keyed with ascending time-in to get the least value there.

With SQL you could get the employee file information, as well as the earliest time-in and the latest time-out, all in a single read (fetch in SQL). It simplifies your code inside the loop quite a bit, doesn't it?

So here's the basic flow in pseudo-code:

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

Not too scary looking, is it? So let's see what the code might look like. Of course there is more than one way to do in SQL, but let's start simple with just an SQL Select statement. When you use RPG variables in SQL, you prefix them with a colon (':').

    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;

Well, that's quite a SELECT statement, eh? A lot going on.

But it's organized into two parts. The first part is a table expression called h, where we get our times for each employee on that date. The second part lists all the result fields we want, which are taken from the table expression h and the employees file, wherever we can match the employee numbers in both files. The rows will be given to us sorted by last name, first name, and employee number.

So let's put this in 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;

Now you may at first hesitate at how much work is being done by the SELECT statement in the cursor. But by doing it all there you've simplified your I/O, and let the SQL optimizer work its magic to find the fastest way to get your data to you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top