0
ALTER TRIGGER [dbo].[Check_time] on [dbo].[Schedule] after insert
AS 

if exists ((select * from Schedule as S Join inserted as i on S.DDate=i.DDate AND S.ST_TIME=i.ST_TIME AND S.END_TIME=i.END_TIME))
BEGIN 
print('INVALID TIME')
ROLLBACK TRANSACTION 
return
END 

*but there is another problem that the user can insert time before the end time for the previous user has been ended , how can i solve it?***

Mina Essam
  • 13
  • 1
  • 5
  • 1
    Why a trigger? Just declare `DDate, ST_TIME, END_TIME` UNIQUE. – Serg Oct 06 '19 at 12:28
  • 1
    _"...check that time that user choose it is empty or not?"_ Isn't the same as _"Check if exists or not"_. So what are you trying to do really? – Ilyes Oct 06 '19 at 12:35
  • Wouldn't a `CHECK CONSTRAINT` be better? – Thom A Oct 06 '19 at 12:43
  • Also, how can a `date` be "empty"? – Thom A Oct 06 '19 at 12:43
  • 1
    @Sami i want to make schedule for an advertising screen to make user choose the time he wants to view his content but must check that this time is available not taken by another user – Mina Essam Oct 06 '19 at 12:45
  • Then I think you're after `IF EXISTS(SELECT 1 FROM TABLE WHERE ...) --Do the job` @MinaEssam – Ilyes Oct 06 '19 at 12:51
  • @MinaEssam My hypothesis is that `DDate, ST_TIME, END_TIME` must be `UNIQUE` excluding cases when those dates are NULL. Maybe that's the reason why CHECK CONSTRAINT is not used? Please clarify – Alex Yu Oct 06 '19 at 12:54
  • @AlexYu in another day the time can be repeated , so I think that the unique CHECK CONSTRAINT not be useful – Mina Essam Oct 06 '19 at 13:06
  • @MinaEssam "in another day the time can be repeated" - UNIQUE constraint for combination of fields not for individual fields. E.g. `CONSTRAINT UI_DDATE_ST_TIME_END_TIME UNIQUE (DDATE, ST_TIME, END_TIME)`. Take a look on http://sqlfiddle.com/#!18/786cd/1 – Alex Yu Oct 06 '19 at 13:39
  • @AlexYu its ok ,but there is another problem that the user can insert time before the end time for the previous user has been ended , how can i solve it? – Mina Essam Oct 06 '19 at 15:00
  • @MinaEssam "user can insert time before the end time for the previous user has been ended" - does it means that time periods DDATE-ST_TIME-END_TIME from different rows must not intersect? E.g. it's impossible to have 01:00-05:00 and 02:00-03:00 in the same day? Explain and add to text of your question consisnency rules you need. – Alex Yu Oct 06 '19 at 17:05
  • @AlexYu yes i mean this – Mina Essam Oct 06 '19 at 17:27
  • @AlexYu Can you help me to make it ? – Mina Essam Oct 06 '19 at 18:47
  • @MinaEssam I hope I understood you correctly (or somewhere near to needed). Look at my answer, check this: https://stackoverflow.com/questions/12035747/date-range-overlapping-check-constraint - I used part of this answer. Hope this helps – Alex Yu Oct 06 '19 at 19:21
  • @AlexYu i don't understand it and whats meant by 0 and 1 – Mina Essam Oct 06 '19 at 20:07
  • @MinaEssam Actually it's `false`/`true` but that does not matter, it could any datatype. Constraint defined as: a) function that returns 0(false) in case when no overlaps exists and 1(true) - otherwise, b) CONSTRAINT itself thru application of this function. Every DML (INSERT/UPDATE) is checked, in case result is 0 (no overlaps) - row inserted/updated. – Alex Yu Oct 07 '19 at 04:21

3 Answers3

1

Since you used Trigger I will answer in Trigger format. Use INSTEAD OF instead of after insert. In this case, you check the table before setting a record. Use 2 as a suggestion

ALTER TRIGGER [dbo].[Check_time]
   ON  [dbo].[Schedule]
   INSTEAD OF INSERT
AS 
BEGIN
    DECLARE @Count INT = 0
    SELECT @Count = COUNT(*) 
    FROM Schedule AS S 
    INNER JOIN inserted AS i ON S.DDate=i.DDate AND S.ST_TIME=i.ST_TIME AND S.END_TIME=i.END_TIME

    IF ISNULL(@Count , 0) = 0
    BEGIN 
        INSERT INTO [dbo].[Schedule] ([MID], [SID], [ST_TIME], [END_TIME], [DDate], [ST_ID])
        select [MID], [SID], [ST_TIME], [END_TIME], [DDate], [ST_ID] FROM inserted
    END 

END
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

Your trigger is just checking for duplicated values. You are better off with a unique constraint:

alter table Schedule add constraint unq_schedule_ddate_st_time_end_time
    unique (ddate, st_time, end_time);
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
0

1. Problem clarification

After clarifications by OP in comments it become clear that the main goal is checking overlapping time periods.

E.g.

  • combination of periods (01:00:00-02:00:00, 02:01:00-03:00:00) - is allowed in the same day
  • (01:00:00-05:00:00, 02:01:00-03:00:00) or (01:00:00-03:00:00, 02:00:00-04:00:00) - are disallowed

(I hope that I understood correctly)

Checking for overlapping periods is typical task and I even found existing answer on SO: Date range overlapping check constraint

2. Proposed solution

With a little modification I can propose this solution: http://sqlfiddle.com/#!18/e2146/2

CREATE TABLE Schedule (
  ID BIGINT IDENTITY PRIMARY KEY,
  DDate date,
  ST_TIME time,
  END_TIME time
);

-- UNIQUE CONSTRAINT
CREATE UNIQUE INDEX UI_DDATE_ST_TIME_END_TIME ON Schedule(DDATE, ST_TIME, END_TIME);

-- CONSTRAINT FOR OVERLAPPING PERIODS
CREATE FUNCTION [dbo].[fn_chkOverlapping]
(
  @DDate AS DATE,
  @ST_TIME AS TIME,
  @END_TIME time
)
RETURNS BIT
AS 
BEGIN
 RETURN (
  SELECT 
  CASE
     WHEN @ST_TIME>@END_TIME THEN 0
     WHEN EXISTS(
          SELECT 1 FROM [dbo].[Schedule]
            WHERE
                @DDATE = DDATE
                AND @END_TIME >= ST_TIME
                AND END_TIME >= @ST_TIME
     ) THEN 0
     ELSE 1
  END
 )
END;

ALTER TABLE [dbo].[Schedule]  WITH CHECK ADD CONSTRAINT [CK_Overlapping] CHECK  ([dbo].[fn_chkOverlapping]([DDate],[ST_TIME],[END_TIME])=0);

3. Alternatives

It's absolutely possible to do this using triggers.

I myself prefer to define constraints by CREATE CONSTRAINT than other object types.

It's a question of taste not of necessity.

Alex Yu
  • 3,412
  • 1
  • 25
  • 38
  • but i didn't work the data is wrong data is entered – Mina Essam Oct 06 '19 at 19:55
  • @MinaEssam Because you did not defined what is wrong and what is correct. This information is known to only you. Modify INSERT statement with correct data in http://sqlfiddle.com/#!18/e2146/2 and then modify check function accordingly. What is exactly wrong? – Alex Yu Oct 07 '19 at 04:27