2011-01-26 39 views
4

我把一個非常簡單的工作/項目衝牀/時鐘組合在一起,供員工進出。每行包含一個輸入和輸出。但是,有時員工忘記在適當的時間衝入或衝出,所以我必須修改他們的拳頭。工作/項目時間數據庫 - 編輯記錄

我的問題是:我如何檢查以確保我所做的更改不會與現有的打孔重疊?

編輯:

的TABEL看起來是這樣的:

Punch ID,Project Number,Employee ID,DateTime In,DateTimeOut 
138,PA15212,1234,1/1/2010 1:00,1/1/2010 5:45 
139,AD15217,5678,1/1/2010 1:00,1/1/2010 3:15 
140,SL15222,4567,1/1/2010 1:00,1/1/2010 2:30 
141,GA15151,5678,1/1/2010 3:20,1/1/2010 5:45 

EDIT 2

爲了澄清,我在下面留言,數據庫是工作/工程時間跟蹤系統。基本上員工打到一份工作。一旦他們這樣做,他們唯一的選擇就是衝出去。然後,他們可以衝入他們工作的下一份工作中,並且會在一天中完成幾項工作。在同一個記錄中擁有In和Out衝頭是一個簡單/不復雜的系統,可以很容易地匹配IN和OUT衝頭以及計算該記錄中的時間。但是,有時候他們會忘記衝上工作崗位,最終會這麼做,或者忘記衝出去。我需要修改那裏的拳頭,但我想確保該更改不會與該員工的現有進/出時間框架重疊。

+0

您至少需要提供該表的設計讓我們明白你的意思。 – Yahel 2011-01-26 21:46:18

+0

爲什麼修改現有的拳擊?爲什麼不插入一個記錄(標記爲管理/系統生成)的「失蹤」拳? – 2011-01-26 22:00:18

+0

那麼取決於他們如何搞砸我可能需要插入和/或修改記錄。 – 2011-01-26 22:17:14

回答

0
  1. 「桌子」有幾個問題讓你感到困難。

    • 丟失的打孔值是多少?您是如何產生或默認對於衝入但未衝出的員工?空值 ? 23:59? DateTimeIn?他們都不正確,但你必須有一些已知的價值。)

    • 當你回答這個問題時,我們可以編寫SQL(它確實是一個SQL問題)。

    • 您想更新失蹤衝出時間與什麼樣的價值:

    • 下一頁STARTIME零下5分鐘

    • 那裏沒有下一次啓動的時間? 17:00?
  2. 關於AFA數據庫設計而言,並沒有看到其他表格,表格應該如下。假設他們爲每個項目(工作?)衝入IN和OUT。

    CREATE TABLE Punch (
        PunchID,  -- No idea what use it has, but I will keep it anyway 
        ProjectNo, 
        EmployeeID, 
        DateTime, 
        IsStart  BIT -- boolean, tinyint 
        )

    • 當衝頭髮生了,衝出來還沒有發生,所以你存儲的任何值是假的。

    • 缺少的行很容易識別

  3. 前端,圖形用戶界面,基於字符的命令,什麼的,可以使用一點的改進。

    • 應該明確地衝IN或OUT

    • 當衝頭被註冊,如果沒有以前的衝出來,然後一系列的默認S的可以使用,並且衝出創建第一。例如同一天:使用當前的日期時間,第二天:使用前一天的17:00。

2

我想你想的東西太多了合併成一個表,發出此更加複雜。提議的設計的一個主要問題是沒有審計線索,因此如果存在賬單或員工爭議,那麼很難證明數據是有效的。

我會建議使用一個真正的事務日誌(僅限選擇/插入),它記錄時間被考慮的人和輸入數據的人以及導出摘要信息的數據視圖您正在尋找。然後,您可以通過瀏覽日誌查看相鄰事件(「拳」)來檢查衝突。

0

這是我的看法,爲您的問題增加清晰度。評論我錯誤理解並錯過的內容。我會盡量不斷修改。

您正在尋找針對「Punch」事件的兩個例外的解決方案。你想覆蓋的兩個例外是:

  1. 僱員使得衝出來,但忘了今天早上

  2. 的員工,使一拳打在衝卻忘了打卡下班昨天

    • 至於第一個例外,您可以用來創建邏輯的信息是當前的打孔時間。如果當前時間在12點之後,那麼今天9點加滿標準衝牀。

    • 第二次打孔可以類似處理;如果當前時間晚上過了03,那麼該員工可能已經忘記了昨天出拳了。

正如你可能知道,我明白,這簡單的邏輯可能不是你要找的答案。但對我在這裏錯過的內容發表評論,我會修改它以滿足您的需求。

0

這個怎麼樣的僞代碼:

onPunchIn() { 
if (DateTimeOut is null and now() < tomorrow()) { 
    Set DateTimeOut = now() 
    Create new record } 
if (DateTimeOut is null and now() > tomorrow()) { 
    Set DateTimeOut = getDefaultEndOfDayFromYesterdafy() 
    Create new record } 
} 
1

FWIW我想你應該只捕獲實際發生的事情,如果有人忘記打卡或縮小,然後應該有沒有相應的條目。

如果你模擬真正發生的事情,那麼你總是可以根據你的應用程序中的任何業務規則或通過存儲過程,隨時爲丟失的數據創建缺省值。這也可以讓你改變默認設置,因爲你總是在計算它們。此外,它允許發生這種情況時的報告/統計數據,誰是罪犯等等。此外,重要的是,您的數據庫代表真正發生的事情,而不是一些軟糖。

PunchID, EmployeeID, ProjectNbr, Timestamp, Direction 
111, 111, 101, 1/1/11 8:00, IN 
111, 111, 101, 1/1/11 17:00, OUT 
1

SQL查找重疊記錄(關鍵是要加入表本身):

SELECT * 
    FROM TABLE_XXX x1, TABLE_XXX x2 
WHERE x1.employee_id = x2.employee_id 
    AND x1.DateTimeIn < x2.DateTimeIn 
    AND x1.DateTimeOut > x2.DateTimeIn 
    AND x1.DateTimeIn > ? -- start of the day in question 
    AND x1.DateTimeIn < ? -- end of the day in question 
    AND EMPLOYEE_ID = ? 

我對設計2C:

  1. 如果保持目前的設計你應該創建插入和更新觸發器來檢查重疊,並在創建時引發異常。

  2. 只存儲PerformanceDBA建議的每個活動的開始時間。這意味着你必須有一個專門打孔的項目。您可以通過插入缺失的時間來修復錯過的拳擊。 該解決方案也將確保有在的時候沒有洞,除了有意者(其中活動是特殊的「衝出來」活動 這是最好的設計,恕我直言

0

當你問。: (1)修改/添加打孔 - >(2)驗證 - >(3)是否保存

一般來說,「我需要在那裏修改一下,但我想確保更改不重疊」你不應該在不關閉EndDate的情況下爲員工添加衝突 然後 - >如果所有拳擊都是「關閉」的,你可以添加新的StartDate大於任何其他僱員的EndDate - 但如果發生這種情況,當日員工忘記蓋章(進出),你將不得不在其他人之間添加一個「新老」的打卡工具 - 所以:你選擇員工,設置你的StartDate和EndDate,項目ID和其他 - >並且你簽入DB如果:

  1. 有你的起始日期和結束日期 之間StartDates或EndDates在DB - >重疊(其他衝壓 開始或結束您的新衝牀內)

  2. 有StartDates姑娘比你 StartDate和EndDate大於 您的EndDate - >重疊(您的新 pu NCH是其他衝牀內)

所有SQL這些查詢必須爲一名僱員來完成(一個員工不能在多個項目在同一時間)

如果沒有這種錯誤的出現,你可以安全添加一拳。我很喜歡僞代碼和我的英文。我希望它有用一點。

0

首先,就您的問題而言,從架構的角度來解決此問題的方法是將每個行的前一次超時。這個技巧在ProjectNumber,EmployeeId和DateTimeIn上設計了一個唯一的約束,並在ProjectNumber,EmployeeId和PreviousDateTime上設置了ProjectNumber,EmployeeId,DateTimeOut的外鍵引用。還應該注意的是,我依賴於唯一約束,允許在所有數據庫系統中都不是真的單個null(當然,我也依賴於數據庫系統遵守檢查約束,這在所有數據庫系統中都不是這樣) )。

Create Table Punches 
    (
    PunchId int not null Primary Key 
    , ProjectNumber varchar... 
    , EmployeeId int not null.. 
    , DateTimeIn datetime not null 
    , DateTimeOut datetime null 
    , PreviousDateTimeOut datetime null 

    , Unique (ProjectNumber, EmployeeId, DateTimeIn) 
    , Unique (ProjectNumber, EmployeeId, DateTimeOut) 
    , Unique (ProjectNumber, EmployeeId, PreviousDateTimeOut) 

    , Check (DateTimeIn <= DateTimeOut) 
    , Check(PreviousDateTimeOut <= DateTimeIn) 

    , Foreign Key (ProjectNumber, EmployeeId, PreviousDateTimeOut) 
     References Punches(ProjectNumber, EmployeeId, DateTimeOut) 
    ) 

這種方法的好處是模式本身可以防止重疊。缺點是插入有點棘手。給定項目的給定員工的第一行將需要爲PreviousDateTimeOut使用空值,因爲我們不會有前一行。其次,這意味着一次衝入將需要查找以前的日期時間。

Insert Punches(ProjectNumber, EmployeeId, DateTimeIn, PreviousDateTimeOut) 
Select ProjectNumber, EmployeeId, CURRENT_TIMESTAMP 
    , Coalesce(
     (
     Select Max(DateTimeOut) 
     From Punches 
     Where DateTimeOut Not Null 
     ) 
     , CURRENT_TIMESTAMP) 

上面只是解決了重疊問題。然而,這並不一定能解決一個被遺忘的擊出其他的問題,而不是防止穿在沒有預先打孔防止兩行的插入對於同一ProjectNumber與員工和空DateTimeOut。應該發生什麼可能涉及更復雜的業務規則。