SQL Server:插入当前日期>结束日期

时间:2011-12-13 22:27:17

标签: asp.net sql-server vb.net

基本上我需要做的是在ReservationvehicleIDstartDate表格endDate中加入。

我可以做得很好,但我想对其进行验证,以便在当前日期为vehicleID的情况下无法插入<= endDate,因为目前我可以继续添加Reservation 1}}表在同一vehicleID

这只是简单的插入SQL语句。

strInsert = String.Format("Insert into Reservation (VehicleID, startDate, enddate) VALUES ('{0}','{1}','{2}')", vID, now, now5)

问候。

3 个答案:

答案 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)