Проверка перекрытия даты / времени в SQL Server для планирования событий - PullRequest
5 голосов
/ 26 декабря 2011

У меня есть таблица событий со следующими столбцами:

StartDate datetime
EndDate datetime
StartTime nvarchar(10)
EndTime nvarchar(10)

Допустим, запись имеет следующие значения в таблице:

StartDate: 2011-12-22 00:00:00.000
EndDate: 2011-12-22 00:00:00.000
StartTime: 4:00 PM
EndTime: 5:00 PM

Теперь, если кто-то придет запланировать событие, мне нужно убедиться, что он не может запланировать его на то же время или между временем начала и окончания этого существующего события.

Таким образом, он может планировать с 17:00 до 18:00 или с 11:00 до 16:00, но не с 11:00 до 17:00 или с 16:30 до 17:00. .

Как я могу проверить это? Я знаю, что это не лучший дизайн для этой таблицы, но я должен придерживаться этого дизайна, иначе нам придется изменить много кода среднего уровня и клиентской части.

Ответы [ 3 ]

3 голосов
/ 26 декабря 2011

При добавлении новой записи или изменении существующих вы должны убедиться, что ваши начальные или конечные временные метки не попадают в уже существующие временные диапазоны, а новый диапазон не охватывает существующие.

Предполагая, что дата также имеет значение, а не только времязатем лучший способ сохранить даты и время начала и окончания в виде столбцов DATETIME, например StartDT и EndDT - в этом случае вы должны проверить непересекающиеся другие строки с помощью этого оператора

Where not exists(
    select * from yourtable 
    where (@newstart >= StartDT AND @newstart < EndDT) 
    OR (@newend > StartDT AND @newend <= EndDT) 
    OR (@newstart <= StartDT AND @newend >= EndDT)
)

Конечно, вы можетепереписать его как предложение EXISTS вместо NON EXISTS

Итак, если вы не можете изменить схему, вы должны просто изменить StartDT и EndDT на выражения, которые составляют соответствующие значения из нижележащих строковых столбцов, например

 StartDT = SUBSTRING(StartDate, 1, 10) + ' '+ StartTime
0 голосов
/ 27 декабря 2011

Просто хотел опубликовать мой запрос здесь - может кому-то помочь. Работает как шарм. Спасибо за помощь!

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[PS_Event_Insert]
(
@UserID int,
@AmenityID int,
@DateFrom datetime,
@DateTo datetime,
@TimeFrom nvarchar(50),
@TimeTo nvarchar(50),
@Description nvarchar(max),
@IsPrivate bit,
@NumberOfPeople nvarchar(100),
@Food bit,
@StatusID int,
@Notes nvarchar(500) = NULL,
@EventID int OUTPUT
)
AS
declare @newdtfrom datetime = cast(@DateFrom + ' ' + @TimeFrom as datetime)
declare @newdtto datetime = cast(@DateTo + ' ' + @TimeTo as datetime)

DECLARE @RecCount int

BEGIN

SET @RecCount = (
select count(*) from [events]   
where (@newdtfrom >= cast([datefrom] + ' ' + [timefrom] as datetime) and @newdtfrom   <= cast([dateto] + ' ' + [timeto] as datetime))
or (@newdtto > cast([datefrom] + ' ' + [timefrom] as datetime) and @newdtto <=   cast([dateto] + ' ' + [timeto] as datetime))
or (@newdtfrom <= cast([datefrom] + ' ' + [timefrom] as datetime) and @newdtto >= cast([dateto] + ' ' + [timeto] as datetime))  
AND
[AmenityID] = @AmenityID
AND 
[StatusID] = 5
)

IF (@RecCount = 0)
BEGIN
    INSERT INTO [Events]
    (
        [UserID],
        [AmenityID],
        [DateFrom],
        [DateTo],
        [TimeFrom],
        [TimeTo],   
        [Description],
        [IsPrivate],
        [NumberOfPeople],
        [Food],
        [StatusID],
        [Notes]
    )
    VALUES
    (
        @UserID,
        @AmenityID,
        @DateFrom,
        @DateTo,
        @TimeFrom,
        @TimeTo,
        @Description,
        @IsPrivate,
        @NumberOfPeople,
        @Food,
        @StatusID,
        @Notes
    )

SET @EventID = SCOPE_IDENTITY()
END
ELSE
BEGIN
    SET @EventID = -999
END
END
0 голосов
/ 26 декабря 2011

Попробуйте это

declare @apptDate DATETIME

SET @apptDate = '12/22/2011 4:30PM'
select COUNT(*) 
from t1
where @apptDate Between
CAST( StartDate+StartTime as DateTime) and CAST( EndDate+EndTime as DateTime)  

SET @apptDate = '12/22/2011 6:30PM'
select COUNT(*) 
from t1
where @apptDate Between
CAST( StartDate+StartTime as DateTime) and CAST( EndDate+EndTime as DateTime)  

Если count (*)> 0, встреча существует. Если нет, то место бесплатно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...