我的任务是更新位于 SQL 2005 数据库中的表中的一些字段。我目前正在使用 vb.net 2010 (.net 4) 并且仍在学习这些东西,所以请保持温和。如果我错过了什么,请告诉我,我会尽快补上。最后,对不起,这太长了,但否则我很难创建一个描述。
除了包含的表格中显示的字段外,还有一些其他字段,但在整体方案中并不重要。此表用于劳动力跟踪,因此操作员/用户登录到工作并填充以下字段:EmployeeWorkID(主键)、EmployeeID(从单独的表派生)、LoginDatetime(日期时间戳)和状态。填充 db 表的真实世界示例:
运行应用程序之前的表格:
EmplWorkID EmplID LoginDateTime LogoutDateTime Status LoggedIn LoggedOut
93464 376 2013-01-31 15:00 2013-01-31 17:25 C 0 0
93466 376 2013-01-31 17:26 2013-01-31 23:00 C 0 0
93468 376 2013-02-01 15:00 2013-02-01 23:00 C 0 0
93484 380 2013-02-01 07:00 2013-02-01 09:17 C 0 0
93485 380 2013-02-01 09:18 2013-02-01 11:22 C 0 0
93486 380 2013-02-01 11:23 NULL A 0 0
93479 385 2013-01-31 07:03 2013-01-31 09:32 C 0 0
93481 385 2013-01-31 09:33 NULL A 0 0
93473 385 2013-02-01 07:05 2013-02-01 09:13 C 0 0
93482 385 2013-02-01 09:14 2013-02-01 11:34 C 0 0
93480 385 2013-02-01 11:35 2013-02-01 13:41 C 0 0
93483 385 2013-02-01 13:42 2013-02-01 15:03 C 0 0
93478 394 2013-01-31 23:03 2013-02-01 00:53 C 0 0
93475 394 2013-02-01 00:54 2013-02-01 03:26 C 0 0
93476 394 2013-02-01 03:27 2013-02-01 05:39 C 0 0
93477 394 2013-02-01 05:44 2013-02-01 07:03 C 0 0
第一次运行后的表:
EmplWorkID EmplID LoginDateTime LogoutDateTime Status LoggedIn LoggedOut
93464 376 2013-01-31 15:00 2013-01-31 17:25 C 1 0
93466 376 2013-01-31 17:26 2013-01-31 23:00 C 0 1
93468 376 2013-02-01 15:00 2013-02-01 23:00 C 1 1
93484 380 2013-02-01 07:00 2013-02-01 09:17 C 1 0
93485 380 2013-02-01 09:18 2013-02-01 11:22 C 0 0
93486 380 2013-02-01 11:23 2013-02-01 15:00 C 0 1
93479 385 2013-01-31 07:00 2013-01-31 09:32 C 1 0
93481 385 2013-01-31 09:33 2013-01-31 15:00 C 0 1
93473 385 2013-02-01 07:00 2013-02-01 09:13 C 1 0
93482 385 2013-02-01 09:14 2013-02-01 11:34 C 0 0
93480 385 2013-02-01 11:35 2013-02-01 13:41 C 0 0
93483 385 2013-02-01 13:42 2013-02-01 15:00 C 0 1
93478 394 2013-01-31 23:00 2013-02-01 00:53 C 1 0
93475 394 2013-02-01 00:54 2013-02-01 03:26 C 0 0
93476 394 2013-02-01 03:27 2013-02-01 05:39 C 0 0
93477 394 2013-02-01 05:44 2013-02-01 07:00 C 0 1
第二次运行后的表:
EmplWorkID EmplID LoginDateTime LogoutDateTime Status LoggedIn LoggedOut
93464 376 2013-01-31 15:00 2013-01-31 17:25 C 1 0
93466 376 2013-01-31 15:00 2013-01-31 23:00 C **1** 1
93468 376 2013-02-01 15:00 2013-02-01 23:00 C 1 1
93484 380 2013-02-01 07:00 2013-02-01 09:17 C 1 0
93485 380 2013-02-01 07:00 2013-02-01 11:22 C **1** 0
93486 380 2013-02-01 11:23 2013-02-01 15:00 C 0 1
93479 385 2013-01-31 07:00 2013-01-31 09:32 C 1 0
93481 385 2013-01-31 07:00 2013-01-31 15:00 C **1** 1
93473 385 2013-02-01 07:00 2013-02-01 09:13 C 1 0
93482 385 2013-02-01 07:00 2013-02-01 11:34 C **1** 0
93480 385 2013-02-01 11:35 2013-02-01 13:41 C 0 0
93483 385 2013-02-01 13:42 2013-02-01 15:00 C 0 1
93478 394 2013-01-31 23:00 2013-02-01 00:53 C 1 0
93475 394 2013-02-01 00:54 2013-02-01 03:26 C 0 0
93476 394 2013-02-01 03:27 2013-02-01 05:39 C 0 0
93477 394 2013-02-01 05:44 2013-02-01 07:00 C 0 1
The second run shows the records that have been incorrectly updated. The Login/LogoutDateTimes were updated as well as the LoggedIn flag. What I need my vb app to do is set each employee's first LoginDateTime = Time & Attendance clock-in, and set their last LogoutDateTime = T&A clock out. The included images show the first, and second runs of my app where it sets the LoggedIn and LoggedOut fields where necessary. However, this app will be ran several times during the day and will update new records as they are added. The problem: (yeah I know...finally) subsequent runs of the application (see 'Table after second run:') pick up extra records that should not be updated. For example, on the second run of the app the record for EmployeeWorkID = 93466 is picked up and the LoginDateTime is set to the T&A clock in (it would look like EmployeeWorkID = 93464), and the LoggedIn flag would be set to 1. I've tried numerous ways of doing this both through SQL queries and vb code but am left without a solution. Here is the main SQL call that I make within the app, it may not look pretty but it is effective (for one run at least).
SELECT
ew2.EmployeeWorkID
, qryID.Empl
, qryID.LoggedIn
, qryID.LoginDateTime
, ew2.LogoutDateTime
, qryID.RoundedInPunchDate
, qryID.RoundedOutPunchDate
, qryID.ScheduledInDateTime
, qryID.ScheduledOutDateTime
FROM
(
SELECT
ew.EmployeeID
, stmE.Empl
, stmE.STM_Employee_id
, MIN(ew.LoginDateTime) AS LoginDateTime
, vIO.RoundedInPunchDate
, vIO.RoundedOutPunchDate
, vES.ScheduledInDateTime
, vES.ScheduledOutDateTime
, ew.LoggedIn
FROM
tblEmployeeWork AS ew INNER JOIN
tblEmployees AS e ON ew.EmployeeID = e.EmployeeID INNER JOIN
STROMBERG.StrombergTest.dbo.STM_Employee AS stmE ON e.Empl = stmE.Empl INNER JOIN
STROMBERG.StrombergTest.dbo.v_BI_Employee_InOutPunches_AutoLogout2 AS vIO ON
stmE.STM_Employee_id = vIO.STM_Employee_id
AND CONVERT(varchar, ew.LoginDateTime, 101) = CONVERT(varchar, vIO.RoundedInPunchDate,
101) INNER JOIN
STROMBERG.StrombergTest.dbo.v_BI_DailyEmplScheduleAndHoursWorked AS vES ON
vIO.STM_Employee_id = vES.STM_Employee_id AND
CONVERT(varchar, vIO.RoundedInPunchDate, 101) =
CONVERT(varchar,vES.ScheduledInDateTime, 101)
WHERE
(ew.LogoutDateTime BETWEEN '1/31/2013' AND DATEADD(d, 2, '1/31/2013')) AND
(vIO.RoundedInPunchDate BETWEEN '1/31/2013' AND DATEADD(d, 2, '1/31/2013')) AND
(ew.LoginDateTime BETWEEN '1/31/2013' AND DATEADD(d, 2, '1/31/2013'))
GROUP BY DAY(CONVERT(varchar, ISNULL(ew.LoginDateTime, vES.ScheduledInDateTime), 101)),
ew.EmployeeID, vIO.RoundedOutPunchDate, stmE.Empl, stmE.STM_Employee_id,
vIO.RoundedInPunchDate, vES.ScheduledInDateTime, vES.ScheduledOutDateTime, stmE.Empl,
ew.LoggedIn) AS qryID INNER JOIN
tblEmployeeWork AS ew2 ON qryID.EmployeeID = ew2.EmployeeID AND qryID.LoginDateTime =
ew2.LoginDateTime
ORDER BY ew2.EmployeeID