我有一张表,其中包含一组临时工,他们的合同期限可以不确定,并且可以在不同部门续签。续签到其他部门后,需要更新结束日期,并且开始日期必须是结束日期加1天。
当前输出:
+---------------------+------------------+------------------+------------------+
| Name | Department | Start Date | End Date |
+---------------------+------------------+------------------+------------------+
| Tom | Finance | 2010-08-09 | 9999-12-31 |
+---------------------+------------------+------------------+------------------+
所需的输出
+---------------------+------------------+------------------+------------------+
| Name | Department | Start Date | End Date |
+---------------------+------------------+------------------+------------------+
| Tom | Finance | 2010-08-09 | 2010-10-10 |
| Tom | HR | 2010-10-11 | 9999-12-31 |
+---------------------+------------------+------------------+------------------+
当前,我将现有记录保存到临时表中。然后,我对现有表的多个字段进行联接,以查看此人之前是否存在。如果此人存在,那么我将数据保存到临时表中并执行更新,然后再返回并更新主表。我不喜欢这种解决方案,而且非常复杂。有没有更好的解决方案来解决上述问题?
答案 0 :(得分:0)
编辑。由于已经存在存储过程,因此可以将类似的逻辑嵌入到SP中。我创建了一个示例存储过程,该过程将使用员工姓名,更新部门,然后实施您的业务逻辑。再次,将真实的主键字段(而不是员工姓名)作为参数,否则您可能最终会更新多个记录。
ALTER PROCEDURE UpdateDepartment @EmpName VARCHAR(20), @Dept VARCHAR(20)
AS
BEGIN
DECLARE @Changed TABLE
(
EmpName VARCHAR(20),
OldDepartment VARCHAR(20),
NewDepartment VARCHAR(20),
StartDate DATETIME2,
EndDate DATETIME2
)
UPDATE TempEmployees
SET
Department = @Dept
output
inserted.EmpName,
deleted.Department,
inserted.Department,
inserted.StartDate,
inserted.EndDate
into @Changed
WHERE EmpName = @EmpName
DECLARE @OldDept VARCHAR(20);
SELECT @OldDept = OldDepartment FROM @Changed
UPDATE TempEmployees
SET
EndDate = CURRENT_TIMESTAMP,
Department = @OldDept
WHERE EmpName = @EmpName;
INSERT INTO TempEmployees
SELECT
EmpName,
NewDepartment,
DATEADD(DAY, 1, CURRENT_TIMESTAMP),
'99991231'
FROM @Changed
END
一种选择是使用触发器,并利用UPDATE语句生成的输出表。运行UPDATE
语句时,将生成inserted
和deleted
输出表,其中详细说明了记录的前状态和后状态。
请参见下面的代码,并尝试为您的应用程序对其进行修改。请注意,此触发器的当前版本使用Employee Name作为更新谓词的一部分。如果您有一个以上特定雇员姓名的记录,那么所有记录都会被更新。因此,最好在表上使用真实的主键字段,以确保仅更新 个记录。
CREATE TRIGGER TempEmployeeMovedDepartment
ON TempEmployees
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF UPDATE(Department)
BEGIN
--Update the End Date for the Current Record. In this case, I'm using the EmpName
--field to denote the record to update. Presumably, you'd have an actual Primary Key
DECLARE @PK VARCHAR(20);
DECLARE @OldDept VARCHAR(20);
SELECT @PK = EmpName, @OldDept = Department FROM deleted;
UPDATE TempEmployees
SET
EndDate = CURRENT_TIMESTAMP,
Department = @OldDept
WHERE EmpName = @PK;
INSERT INTO TempEmployees
SELECT
EmpName,
Department,
DATEADD(DAY, 1, CURRENT_TIMESTAMP),
'99991231'
FROM inserted
END
END