物理ファイル(PF)に次のフィールドがある勤怠管理システムを実行しています。
User ID(key field),Date,Time In,Time Out
......
問題は、特定のユーザーIDと日付、およびその日のタイムアウトの最大値を選択しようとすることです。タイムアウト値をプログラムの変数に移動します。
RPGLEソースはどのようになりますか?
物理ファイル(PF)に次のフィールドがある勤怠管理システムを実行しています。
User ID(key field),Date,Time In,Time Out
......
問題は、特定のユーザーIDと日付、およびその日のタイムアウトの最大値を選択しようとすることです。タイムアウト値をプログラムの変数に移動します。
RPGLEソースはどのようになりますか?
従来の方法は、ユーザーID、日付とタイムアウトをキーとして、日付とタイムアウトを降順で論理ファイルを作成することです。次に、ユーザーIDと今日の日付を部分キーとして使用して論理にチェーンするだけで、最新のレコードが得られると思います。
埋め込みSQLも機能します。
SELECT MAX(timeout)
INTO :outTime
FROM PF
WHERE userid = :selected_user_id
AND date = :selected_date`
あなたが従業員ファイルと、あなたが説明したような勤続年数のファイルを持っているとしましょう。また、特定の日の各従業員の最も早いタイムアウトと最も遅いタイムアウトを報告する必要があります。
したがって、従業員ファイルを読み取るループがあり、そのループで、@ 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オプティマイザーが魔法のように機能して、データを取得するための最速の方法を見つけることができます。