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を使用すると、従業員ファイル情報、および最も早いタイムアウトと最も遅いタイムアウトをすべて1回の読み取り(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で行う方法は複数ありますが、SQLSelectステートメントだけで簡単に始めましょう。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ステートメントですよね?多くのことが起こっています。

しかし、それは2つの部分に編成されています。最初の部分はhというテーブル式で、その日の各従業員の時間を取得します。2番目の部分には、テーブル式hとemployeesファイルから取得した、必要なすべての結果フィールドが一覧表示されます。両方のファイルの従業員番号を一致させることができます。行は、姓、名、および従業員番号でソートされて提供されます。

それでは、これを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 に答える