基本上我需要做的是在Reservation
,vehicleID
和startDate
表格endDate
中加入。
我可以做得很好,但我想对其进行验证,以便在当前日期为vehicleID
的情况下无法插入<= endDate
,因为目前我可以继续添加Reservation
1}}表在同一vehicleID
这只是简单的插入SQL语句。
strInsert = String.Format("Insert into Reservation (VehicleID, startDate, enddate) VALUES ('{0}','{1}','{2}')", vID, now, now5)
问候。
答案 0 :(得分:3)
如果今天的日期小于您要插入的结束日期,请勿尝试插入?
If Date.Today <= now5 Then
Throw New Exception("Invalid Date")
Else
strInsert = String.Format("Insert into Reservation (VehicleID, startDate, enddate) VALUES ('{0}','{1}','{2}')", vID, now, now5)
End If
<强>更新强>
如果要在SQL中实现这一切,那么我建议使用存储过程,但在任何一种情况下逻辑都是相同的。检查是否存在今天重叠的保留,如果存在,则从SQL中抛出异常。
请注意GETDATE()
不是正确的值,因为它返回当前时间戳,但不知道值是如何存储的,它用作近似值,可以在以后清理。
CREATE PROCEDURE s_AddReservation
@VehicleID INT ,
@StartDate DATETIME ,
@EndDate DATETIME
AS
IF EXISTS(SELECT 1
FROM Reservation
WHERE VehicleID = @VehicleID
AND StartDate <= GETDATE()
AND EndDate >= GETDATE())
BEGIN
RAISERROR('This care has already been rented', 16, 1);
END
ELSE
BEGIN
Insert into Reservation (VehicleID, startDate, enddate) VALUES (@VehicleID, @StartDate, @EndDate)
END
GO
从您的代码中调用此存储过程:
var oCommand = new SqlCommand('s_AddReservation', conn);
oCommand.CommandType = CommandType.StoredProcedure;
oCommand.Parameters.AddWithValue("@VehicleID", vID);
oCommand.Parameters.AddWithValue("@StartDate", now);
oCommand.Parameters.AddWithValue("@EndDate", now5);
oCommand.ExecuteNonQuery();
答案 1 :(得分:1)
如果您使用where
代替select
,则可以使用values
强制执行条件:
insert Reservation
(VehicleID, startDate, enddate)
select '{0}', '{1}', '{2}'
where getdate() > '{2}'
答案 2 :(得分:0)
您可以使用约束和触发器来完成此操作,因此无论您如何插入或更新数据,数据库都会强制执行您的逻辑。
CREATE TABLE dbo.Reservation(
Id int IDENTITY(1,1) NOT NULL,
VehicleId int NOT NULL,
StartDate datetime NOT NULL,
EndDate datetime NULL,
CONSTRAINT pk_dbo_reservation PRIMARY KEY NONCLUSTERED (Id ASC),
CONSTRAINT uq_dbo_reservation UNIQUE CLUSTERED (VehicleId ASC, StartDate ASC)
)
GO
ALTER TABLE dbo.Reservation WITH CHECK ADD CONSTRAINT ck_dbo_reservation_startdate_before_enddate CHECK (StartDate < EndDate)
GO
ALTER TABLE dbo.Reservation ADD CONSTRAINT df_dbo_reservation_startdate DEFAULT (GETDATE()) FOR StartDate
GO
---------------------------------------
CREATE TRIGGER dbo.trg_insupd_ReservationNoOverlap ON dbo.Reservation
AFTER INSERT, UPDATE
AS
SET NOCOUNT ON
IF EXISTS (
-- reservation is already active during the new time frame
SELECT b.VehicleId
FROM dbo.Reservation b
INNER JOIN inserted ins
ON b.VehicleId = ins.VehicleId
AND b.Id <> ins.Id
WHERE ( b.StartDate <= ins.StartDate
AND ( b.EndDate IS NULL
OR b.EndDate > ins.StartDate ) )
OR ( b.StartDate > ins.StartDate
AND ( ins.EndDate IS NULL
OR ins.EndDate > b.StartDate ) )
)
BEGIN
RAISERROR ('Dates cannot overlap for vehicle reservation.', 16, 1) WITH SETERROR;
ROLLBACK TRANSACTION;
RETURN
END
GO
测试用例:
INSERT INTO dbo.Reservation (VehicleId, StartDate, EndDate) VALUES (1, '12/01/2011', '12/06/2011') -- ok
INSERT INTO dbo.Reservation (VehicleId, StartDate, EndDate) VALUES (1, '12/06/2011', '12/08/2011') -- ok
INSERT INTO dbo.Reservation (VehicleId, StartDate, EndDate) VALUES (1, '12/03/2011', '12/04/2011') -- not ok (overlaps)
INSERT INTO dbo.Reservation (VehicleId, StartDate, EndDate) VALUES (1, '12/08/2011', NULL) -- ok (open-ended)
INSERT INTO dbo.Reservation (VehicleId, StartDate, EndDate) VALUES (1, '11/20/2011', '11/26/2011') -- ok
INSERT INTO dbo.Reservation (VehicleId, StartDate, EndDate) VALUES (1, '11/28/2011', NULL) -- not ok (overlaps)