【问题标题】:Update Automation in SQL-ServerSQL-Server 中的更新自动化
【发布时间】:2012-08-28 07:12:37
【问题描述】:

我正在做一个名为“考勤管理系统”的项目

公司有自己的生物指纹扫描仪,用于检查员工的出勤情况并存储在数据库表中。

表格由(ID autonumber, EmployeeNo, CheckTime and CheckType)4个字段组成

Timekeeping系统存储所有员工的日志和考勤,但它没有指定checktype是“I”还是“O”。如下图所示,员工每次登录,系统都会自动存入数据库,但存为“I”,当同一员工再次登录时,会再次存为“I”。

我的客户希望它尽可能自动化。一旦员工再次登录,他想将检查类型更改为“O”。

例如:

我是一名员工。我今天早上8点登录,然后它会存储到数据库中

今天上午 8 点,检查类型为“I”.. 因为我不知道我已经登录,所以我在上午 8:04 再次登录了第二次.. 系统再次将其存储为“I”好像我要在下午5点登出,系统也记录为“我”..

我希望它自动更新数据库。无需用户提供任何参数。我希望它在一个存储过程中以自动化该过程。

应限制在同一员工内: 示例:

Employee1 今天早上 8 点登录..(检查类型“I”) Employee1 在今天上午 11 点再次登录......(检查类型“O”) 员工 1 在今天中午 12 点再次登录..(检查类型“I”) employee1 在今天下午 4 点再次登录(检查类型“O”)

标准应限制在员工编号内,仅限检查时间。并且还希望根据给定数据更新检查类型。

旧系统无法将登录信息存储为“O”,它纯粹是“I”..

如何做到这一点?我需要你的投入和帮助!请问?

我创建了一个存储过程,但不知道在哪里可以启动它,而且我不知道完成该过程并使其工作..

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE AUTOMATIC_OVERRIDE
    @ID INT,
    @EMPLOYEENO NVARCHAR(20),
    @CHECKTIME DATETIME,
    @CHECKTYPE NVARCHAR(1)

AS
    SET NOCOUNT ON;
    WHILE @ID = (SELECT ID FROM CHECKTIME)

        SELECT ID,EMPLOYEENO,CHECKTIME,CHECKTYPE
          FROM CHECKTIME
         GROUP BY ID,EMPLOYEENO,CHECKTIME,CHECKTYPE
         ORDER BY CHECKTIME
GO

请帮我解决这个问题。谢谢。

【问题讨论】:

  • 所以基本上你想要的是为单个员工交替In and Out 结帐,这样就可以知道什么时候进来和什么时候出去。
  • 是的……但我做不到……你能帮帮我吗?
  • T&A 是一个相当复杂的过程,通常通过一个或多个班次模式进行管理。这使得将时间映射到来自时钟系统的数据变得更加容易。处理时钟时间的规则是什么?如果您在 0800 和 0804 打卡,那将是实际开始时间?
  • @u07ch ,如果我在 0800 打卡,那么开始时间会晚点..
  • 检查我的答案,编辑添加修改代码和更新 SQL Fiddle 代码以满足您的日期期望。

标签: sql sql-server stored-procedures insert time-and-attendance


【解决方案1】:

编辑:

进入PRC的解决方案:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE AutomaticOverrideByID
    @ID INT,
    @EMPLOYEENO NVARCHAR(20)

AS

    UPDATE CHECKTIME
    SET CHECKTYPE = CASE WHEN (SELECT
    COUNT(ID) AS CountOfLogin
    FROM CHECKTIME
    WHERE CHECKTIME.EMPLOYEENO = @EMPLOYEENO 
    AND CHECKTIME.CheckTime < C.CheckTime) % 2 = 1 THEN 'O' ELSE CHECKTYPE END
    FROM CHECKTIME C
    WHERE C.ID = @ID

GO

这里是 Dhenn 询问的现有数据集的更新:

UPDATE CHECKTIME
SET CHECKTYPE = CASE WHEN (SELECT
COUNT(ID) AS CountOfLogin
FROM CHECKTIME
WHERE CHECKTIME.EMPLOYEENO = C.EMPLOYEENO 
AND CHECKTIME.CheckTime < C.CheckTime) % 2 = 1 THEN 'O' ELSE CHECKTYPE END
FROM CHECKTIME C

SQL Fiddle 已附上。

【讨论】:

  • 该公司使用 SQL Server 2000 无法识别“WITH”CLAUSE..您有任何解决方法吗?
  • 你能帮我更新一下吗?因为我还不清楚..我必须输入员工编号吗?..你能让它自动吗?还有身份证?
  • 你也应该输入ID和员工编号。您可以使用这两个值创建一个过程,然后您可以更新它们中的任何一个
  • 嗨 Andras,我希望它处于循环中,而 ID 位于 select 子句以及 employeeno...
  • 你能解释一下 update 语句是做什么的吗?我不明白这是为了什么?AND CHECKTIME.ID
【解决方案2】:

试试这个选项 (SQL Fiddle code),应该对 MS SQL Server 2000 有效。

这里有完整的工作代码,复制并粘贴到 SSMS 选项卡上。用它来创建你的过程。

DECLARE @Checktime TABLE([ID] int, [EmployeeNo] NVARCHAR(5), [CheckTime] datetime, [CheckType] NVARCHAR(1));

INSERT INTO @Checktime
    ([ID], [EmployeeNo], [CheckTime], [CheckType])
VALUES
(1, '111-1', '20120826 08:00:00', 'I'),
(2, '222-2', '20120826 08:05:00', 'I'),
(3, '333-3', '20120826 08:07:00', 'I'),
(4, '444-4', '20120826 08:09:00', 'I'),
(5, '555-5', '20120826 08:10:00', 'I'),
(6, '666-6', '20120826 08:12:00', 'I'),
(591, '050-71-1', '20120703 13:06:18', 'O'),
(592, '050-71-1', '20120703 13:06:16', 'O'),
(593, '050-71-1', '20120703 12:54:01', 'O'),
(594, '050-71-1', '20120703 12:53:59', 'O'),
(617, '050-71-1', '20120703 07:53:14', 'O'),
(631, '050-71-1', '20120702 17:36:12', 'O'),
(641, '050-71-1', '20120702 12:13:50', 'O'),
(642, '050-71-1', '20120702 12:13:49', 'O'),
(646, '050-71-1', '20120702 12:00:33', 'O'),
(647, '050-71-1', '20120702 12:00:31', 'O'),
(678, '050-71-1', '20120702 08:07:50', 'O'),
(679, '050-71-1', '20120828 18:07:48', 'O');

DECLARE @Employee NVARCHAR(5)='050-71-1'

INSERT INTO @Checktime ([ID], [EmployeeNo], [CheckTime], [CheckType])
SELECT TOP 1 680 'NewId', EmployeeNo, GETDATE(),
       'NewCheck' = CASE 
           WHEN DATEDIFF(dd, CheckTime, GETDATE())>0 THEN 'I'
           WHEN CheckType = 'I' THEN 'O'
           ELSE 'O'
       END
  FROM @Checktime
 WHERE EmployeeNo = @Employee
 ORDER BY CheckTime DES

SELECT * FROM @Checktime

结果:

ID  EmployeeNo          CheckTime          CheckType
1     111-1     2012-08-26 08:00:00.000       I
2     222-2     2012-08-26 08:05:00.000       I
3     333-3     2012-08-26 08:07:00.000       I
4     444-4     2012-08-26 08:09:00.000       I
5     555-5     2012-08-26 08:10:00.000       I
6     666-6     2012-08-26 08:12:00.000       I
7     222-2     2012-08-28 09:37:41.917       O

【讨论】:

  • 谢谢雅罗斯洛夫!它起作用了..我现在要在服务器上测试它:)
  • 不客气。注意INSERT INTO,因为我强制 ID 为 7,但您将其作为自动数字,因此您不需要将其包含在 INSERT 子句中
  • 你还强制@Employee NVARCHAR(5)='222-2',我怎样才能让它自动和连续?
  • 是的,当然。这就是为什么我评论说你应该使用代码来创建过程,但是改变你需要的任何东西来实现你的目标。在这种情况下,员工编号应该是传递给程序的参数,或者至少是我的想法。这样,INSERT 将为该员工完成。
  • 如何在程序中将其合并到一个循环中?...我需要一段时间吗?我忘了说ID不应该由用户输入,它应该自动选择以及员工编号......请原谅我问了太多问题......我只是sql新手......谢谢
【解决方案3】:

我认为最好使用CheckINCheckOut 列而不是CheckTimeCheckType

  • 如果他已经登录,更新checkOut时间。

  • 如果他没有登录,保存CheckINCheckOut时间,在这种情况下很可能是同一时间。

没有比这更容易的了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    • 2013-04-03
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    相关资源
    最近更新 更多