以下SQL Server代码成功计算并插入所有员工的月薪及其staffID
号码,并将其插入Tablepayroll
。
INSERT INTO Tablepayroll (StaffID,Totalpaid)
(SELECT Tabletimelog.StaffID , Tabletimelog.hoursworked * Tablestaff.hourlypay
FROM Tabletimelog
JOIN Tablestaff ON
Tabletimelog.StaffID = Tablestaff.StaffID)
但是,我希望能够插入一个batchID
,这样您就可以在每次运行上面的插入时识别它以及当时插入的记录。这意味着同时计算的所有员工工资单将具有相同的batchID
个数字。随后的每个batchID
应该增加1。
请参阅下面的图片以获取直观说明。
我认为Select MAX(batch_id) + 1
可行,但我不知道如何将其包含在插入语句中。
答案 0 :(得分:2)
您可以使用子查询使用此查询从当前表中查找最新的batch_id
:
INSERT INTO TablePayroll (StaffID, TotalPaid, batch_id)
SELECT T1.StaffID
, T1.HoursWorked * T2.HourlyPay
, ISNULL((SELECT MAX(batch_id) FROM TablePayRoll), 0) + 1 AS batch_id
FROM TableTimeLog AS T1
INNER JOIN TableStaff AS T2
ON T1.StaffID = T2.StaffID;
正如您所看到的,我只是将1添加到当前MAX(batch_id)
,就是这样
顺便说一句,学会使用别名。它会让你的生活更轻松
另一个解决方案是将batch_id
作为GUID,这样您就不必创建序列或从当前表中获取MAX(batch_id)
。
DECLARE @batch_id UNIQUEIDENTIFIER = NEWID();
INSERT INTO TablePayroll (StaffID, TotalPaid, batch_id)
SELECT T1.StaffID, T1.HoursWorked * T2.HourlyPay, @batch_id
FROM TableTimeLog AS T1
INNER JOIN TableStaff AS T2
ON T1.StaffID = T2.StaffID;
答案 1 :(得分:0)
<强>更新强>
首先在大表中获取最大值(基于表必须大的表名)可能非常昂贵。特别是如果列batch_id
其次,如果你有竞争性插入,你的解决方案SELECT MAX(batch_id) + 1
可能会表现不正确。如果同时并行运行两个插入,@ EvaldasBuinauskas的解决方案无需打开事务和正确的隔离级别也可以导致相同的batch_id
。
如果您的SQL Server版本为2012或更高版本,则可以尝试SEQUENCE
。这至少可以确保没有重复batch_id
创建SEQUENCE
:
CREATE SEQUENCE dbo.BatchID
START WITH 1
INCREMENT BY 1 ;
-- DROP SEQUENCE dbo.BatchID
GO
使用它:
DECLARE @BatchID INT
SET @BatchID = NEXT VALUE FOR dbo.BatchID;
INSERT INTO Tablepayroll (StaffID,Totalpaid, batch_id)
(SELECT Tabletimelog.StaffID , Tabletimelog.hoursworked * Tablestaff.hourlypay, @BatchID
FROM Tabletimelog
JOIN Tablestaff ON Tabletimelog.StaffID = Tablestaff.StaffID)
替代SEQUENCE
可能是附加表:
CREATE TABLE dbo.Batch (
ID INT NOT NULL IDENTITY
CONSTRAINT PK_Batch PRIMARY KEY CLUSTERED
,DT DATETIME
CONSTRAINT DF_Batch_DT DEFAULT GETDATE()
);
此解决方案甚至可以在旧版本的服务器上运行。
DECLARE @BatchID INT
INSERT INTO dbo.Batch (DT)
VALUES (GETDATE());
SET @BatchID = SCOPE_IDENTITY();
INSERT INTO Tablepayroll (StaffID,Totalpaid, batch_id)
(SELECT Tabletimelog.StaffID , Tabletimelog.hoursworked * Tablestaff.hourlypay, @BatchID
FROM Tabletimelog ...
是的,所有这些解决方案都不能保证编号中没有漏洞。这可能发生在事务回滚期间(例如死锁)