工作/项目时间数据库 - 编辑记录

工作/项目时间数据库 - 编辑记录

问题描述:

我把一个非常简单的工作/项目冲床/时钟组合在一起,供员工进出。每行包含一个输入和输出。但是,有时员工忘记在适当的时间冲入或冲出,所以我必须修改他们的拳头。工作/项目时间数据库 - 编辑记录

我的问题是:我如何检查以确保我所做的更改不会与现有的打孔重叠?

编辑:

的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

  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。

我想你想的东西太多了合并成一个表,发出此更加复杂。提议的设计的一个主要问题是没有审计线索,因此如果存在账单或员工争议,那么很难证明数据是有效的。

我会建议使用一个真正的事务日志(仅限选择/插入),它记录时间被考虑的人和输入数据的人以及导出摘要信息的数据视图您正在寻找。然后,您可以通过浏览日志查看相邻事件(“拳”)来检查冲突。

这是我的看法,为您的问题增加清晰度。评论我错误理解并错过的内容。我会尽量不断修改。

您正在寻找针对“Punch”事件的两个例外的解决方案。你想覆盖的两个例外是:

  1. 雇员使得冲出来,但忘了今天早上

  2. 的员工,使一拳打在冲却忘了打卡下班昨天

    • 至于第一个例外,您可以用来创建逻辑的信息是当前的打孔时间。如果当前时间在12点之后,那么今天9点加满标准冲床。

    • 第二次打孔可以类似处理;如果当前时间晚上过了03,那么该员工可能已经忘记了昨天出拳了。

正如你可能知道,我明白,这简单的逻辑可能不是你要找的答案。但对我在这里错过的内容发表评论,我会修改它以满足您的需求。

这个怎么样的伪代码:

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 } 
} 

FWIW我想你应该只捕获实际发生的事情,如果有人忘记打卡或缩小,然后应该有没有相应的条目。

如果你模拟真正发生的事情,那么你总是可以根据你的应用程序中的任何业务规则或通过存储过程,随时为丢失的数据创建缺省值。这也可以让你改变默认设置,因为你总是在计算它们。此外,它允许发生这种情况时的报告/统计数据,谁是罪犯等等。此外,重要的是,您的数据库代表真正发生的事情,而不是一些软糖。

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

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建议的每个活动的开始时间。这意味着你必须有一个专门打孔的项目。您可以通过插入缺失的时间来修复错过的拳击。 该解决方案也将确保有在的时候没有洞,除了有意者(其中活动是特殊的“冲出来”活动 这是最好的设计,恕我直言

当你问。: (1)修改/添加打孔 - >(2)验证 - >(3)是否保存

一般来说,“我需要在那里修改一下,但我想确保更改不重叠”你不应该在不关闭EndDate的情况下为员工添加冲突 然后 - >如果所有拳击都是“关闭”的,你可以添加新的StartDate大于任何其他雇员的EndDate - 但如果发生这种情况,当日员工忘记盖章(进出),你将不得不在其他人之间添加一个“新老”的打卡工具 - 所以:你选择员工,设置你的StartDate和EndDate,项目ID和其他 - >并且你签入DB如果:

  1. 有你的起始日期和结束日期 之间StartDates或EndDates在DB - >重叠(其他冲压 开始或结束您的新冲床内)

  2. 有StartDates姑娘比你 StartDate和EndDate大于 您的EndDate - >重叠(您的新 pu NCH是其他冲床内)

所有SQL这些查询必须为一名雇员来完成(一个员工不能在多个项目在同一时间)

如果没有这种错误的出现,你可以安全添加一拳。我很喜欢伪代码和我的英文。我希望它有用一点。

首先,就您的问题而言,从架构的角度来解决此问题的方法是将每个行的前一次超时。这个技巧在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。应该发生什么可能涉及更复杂的业务规则。