SQL根据另一个表将值分配到表中

时间:2017-11-13 21:31:42

标签: sql sql-server

我正在努力寻找一种更好的方法来完成我想要做的事情。

我有两个数据库表(Booking和TimeSlots)

预订是一个约会列表,TimeSlots是一个时间列表。

我想要做的是当某些内容被插入到Booking中时,获取未标记为已拍摄的第一行TimeSlot(没有人应该具有相同的TimeSlot),然后将TimeSlot标记为已采用,因此不再使用第一行未标记为已采取

我最初有这个:

SELECT TOP 1 @DateSlot = dateSlot, @TimeSlot = timeSlot FROM TimeSlots WHERE taken = 0

UPDATE TimeSlots SET taken = 1 WHERE dateSlot = @DateSlot AND timeSlot = @TimeSlot

INSERT INTO Booking (email, dateSlot, timeSlot, startTime, dateCreated, createdBy, dateModified, modifiedBy, isWaitList) VALUES (@Email, @DateSlot, @TimeSlot, @StartTime, GETDATE(), @Email, GETDATE(), @Email, @IsWaitListed)

但是如果两个插入是在同一时间制作的,那么它们的问题就是得到相同的日期和时间段。

所以我想出了这个:

SELECT @AppointmentAccepted = 1
SELECT @IsWaitListed = 0

//Insert Into the database

INSERT INTO Booking (email, dateSlot, timeSlot, startTime, dateCreated, createdBy, dateModified, modifiedBy, isWaitList) VALUES (@Email, ‘’, '', @StartTime, GETDATE(), @Email, GETDATE(), @Email, @IsWaitListed)

//Get the ID of the new insert

SET @TableA_PK=SCOPE_IDENTITY()

//Get Time Slot Where slotOrder = New Insert ID

SELECT @DateSlot = dateSlot, @TimeSlot = timeSlot FROM TimeSlots WHERE slotOrder = @TableA_PK

//Update The database with Date and Time Slot

UPDATE Booking SET dateSlot = @DateSlot, timeSlot = @TimeSlot WHERE id = @TableA_PK

//Update Time Slot as taken

UPDATE TimeSlots SET taken = 1 WHERE slotOrder = @TableA_PK

哪个还不错,我获取插件的ID根据插槽中的slotOrder和ID获取时隙,然后更新时间段并更新约会日期和时间段。

这个问题,我的数据库并不总是从1开始,我无法获取未标记为已拍摄的第一个时间段,如果删除了TimeSlot,则插入约会表中将不会一个时间段,我不喜欢根据最近插入的ID从另一个表中获取另一个值的想法

有没有关于如何改进这一点的建议,我没有根据ID获取行,理想情况下,我希望根据行顺序而不是ID来获取

1 个答案:

答案 0 :(得分:0)

使用事务获取时间段值,然后更新它以将其设置为采用。这将使其他用户无法获得相同的时间段。

var dataAccess = new Mock<IDataAccess>();
dataAccess.SetUp(d => d.ExecuteReaderFromStoredProcedure(null, null)).Returns(IDataReader);

现在没有两个用户会获得相同的时间段,即使他们同时提交请求也是如此。适用于数十个用户。在事务未提交时,将阻止用户。而且由于事务中只有2行SQL,因此速度非常快。我怀疑用户会注意到(只要begin transaction SELECT TOP 1 @DateSlot = dateSlot, @TimeSlot = timeSlot FROM TimeSlots WHERE taken = 0 UPDATE TimeSlots SET taken = 1 WHERE dateSlot = @DateSlot AND timeSlot = @TimeSlot commit transaction INSERT INTO Booking (email, dateSlot, timeSlot, startTime, dateCreated, createdBy, dateModified, modifiedBy, isWaitList) VALUES (@Email, @DateSlot, @TimeSlot, @StartTime, GETDATE(), @Email, GETDATE(), @Email, @IsWaitListed) 查询返回快速 - 如果没有,你将需要索引该表,以便它立即返回。)

此外,您是否需要在select top 1 ...查询中使用order by子句,以确保它始终以相同的顺序返回可用的时间段?