2012-07-11 182 views
0

我做考勤系統在我的物理文件(PF)具有以下字段:如何爲給定條件的字段選擇最高值?

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

的問題是,我儘量選擇超時的那一天特定的用戶名和日期及最高值。並將超時值移到我的程序中的一個變量中。

如何將RPGLE源代碼看起來像?

+1

如果它們屬於一起,請不要區分日期和時間字段。除非你對空間有嚴格限制,否則節省的金額不值得處理它的頭痛(主要是在使用SQL - **時應該是**)。 – 2012-07-11 16:06:40

+0

是的,建議您最好使用嵌入式SQL,如下面的@Buck所示。理解這些概念可能需要更多的努力,但是它可以帶來很大的收益,並且可以導致設計更簡單,編寫和運行速度更快。 – WarrenT 2012-07-13 22:56:51

回答

3

傳統的方法是建立一個邏輯文件,其中包含用戶ID,日期和超時作爲關鍵字,日期和時間遞減。然後,我認爲只要將用戶ID和今天的日期作爲部分密鑰進行邏輯鏈接即可獲得最新的記錄。

+0

謝謝...另一個愚蠢的問題要問...我可以聲明另一個領域的關鍵字段?..甚至在我的PF認爲我只宣佈USRID作爲關鍵字段.. ?? ...應該在相同類型的關鍵字段(因爲當我使用Chain時,其他字段的錯誤不是同一類型)?... – user1516536 2012-07-16 07:48:44

+0

RPG程序中的關鍵字段必須與文件上的關鍵字段匹配。如果您需要額外的關鍵字段,請使用您需要的鍵創建一個邏輯文件,並將其用於您的RPG程序中。 – 2012-07-16 15:56:28

+0

@BuckCalabro,你寫的說法不正確。例如,可以通過USER,Date和Time In(或Out)...鍵入文件,程序可能只引用USER作爲鍵。這很好。我認爲你的意思是,你的程序不能作爲一個關鍵字引用,這個關鍵字在文件中沒有被定義爲關鍵字。該文件將需要使用附加的鍵(NOTE!DATA LOSS!)重新創建,或者可以使用ALTER TABLE添加約束。或者,如你所建議的那樣,可能會創建一個新的邏輯。 – Dennis 2012-07-30 13:15:10

2

嵌入式SQL也將工作:

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

不能使用嵌入式SQL ..任何其他建議 – user1516536 2012-07-16 07:44:02

+0

根據個人喜好從最壞到最差排名:閱讀每條記錄並自己跟蹤這些值,FMTDTA,OPNQRYF都是SQL的替代品。 – 2012-07-16 16:05:19

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優化器發揮魔力,找到將數據傳遞給您的最快方式。

+0

不能使用嵌入式SQL ..任何其他建議.... – user1516536 2012-07-16 07:43:35

+0

如果您無法使用嵌入式SQL,那麼Martin的答案可能是一個不錯的選擇。但是,如果您想追求SQL選項,那麼您可以將SELECT語句放在QM查詢中並將輸出發送到文件。 QM查詢使您能夠指定變量,方法是在CL中用「&」符號前綴名稱。 STRQMQRY命令允許您傳入變量的值。所以你可以說'STRQMQRY myqry OUTPUT(* FILE)OUTFILE(qtemp/results)SETVAR((&MYVARIABLE'''2012-07-14'''))''。 – WarrenT 2012-07-16 14:21:35

相關問題