Добрый день, уважаемые участники сообщества. Я снова к вам за помощью. Помогите разобраться. У меня есть бд(в прикрепленном файле)
Не могу понять, как выполнить вот эти пункты:
Запретить записывать клиента к барберу на уже занятое
время и дату
В этом случае по всей видимости триггер, я сделал что-то вроде:
create trigger tg_booking_taboo on bookings
after insert
as
begin
if exists(select*from
bookings b,inserted i
where b.start_time=i.start_time and b.barber_id=i.barber_id
and b.week_day_id=i.week_day_id)
begin
rollback tran
print('This date is busy')
end
end
Но это, естественно, не правильно и я не пойму, как реализовать то,чтобы учитывалось расписание барбера, продолжительность услуги и так далее.
Показать свободные временные слоты на неделю конкрет-
ного барбера. Информация о барбере и дне передаётся
в качестве параметра
Ну и здесь подобная ситуация, только тут я решил сделать хранимую процедуру. Я связываю джоинами все, на мой взгляд, нужные таблицы, но как учесть остальное:
create proc sp_free_time @day nvarchar(30),@name nvarchar (50),@surname nvarchar(50)
as
begin
select b.f_name,b.l_name
from [services] s join barber_service bs on s.id=bs.service_id
join barbers b on b.id=bs.barber_id
join schedule sc on sc.barber_id=b.id
join week_days w on w.id=sc.week_day_id
join bookings bk on bk.week_day_id=w.id
where @day=w.name and @name=b.f_name and @surname=b.l_name
end
Чтобы узнать продолжительность, нужно посмотреть в [services] длительность услуги. И да, наверно, нужно еще добавить join booking_service. И я все равно не понимаю как все это посчитать.Мой мозг закипел
Так посчитать же просто, по ссылке выше что-то типа b.start_time < (i.start_time + i.duration) and (b.start_time + b.duration) > i.start_time (синтаксис скорее всего неправильный, возможно нужны алиасы и т.п. для duration)
надо только правильно приджоинить всё.
create trigger tg_booking_taboo on bookings
after insert
as
begin
if exists(select*from
bookings b join inserted i on b.barber_id=i.barber_id and b.week_day_id=i.week_day_id
join booking_service bs
on bs.booking_id=b.id join [services] s on s.id=bs.service_id
where b.start_time<(select dateadd(minute,datepart(minute,s.duration),i.start_time))
and (select dateadd(minute,datepart(minute,s.duration),b.start_time))>i.start_time)
begin
rollback tran
print('This date is busy')
end
end
И теперь у меня проблема, как сделать так чтобы тут
Теперь вроде бы почти все работает, за исключением того, что я могу спокойно добавить клиента, когда рабочий день закончился и когда он еще не начался, не понимаю в чем дело, вроде все логично:
create trigger tg_booking_taboo on bookings
after insert
as
begin
declare @duration_sum int
declare @client int
declare @barber int
declare @end_time time
declare @start_time time
declare @week_day int
select @client=client_id, @barber=barber_id, @week_day=week_day_id
from inserted
set @end_time=(select end_time from schedule where barber_id=@barber
and week_day_id=@week_day)
set @start_time=(select start_time from schedule where barber_id=@barber
and week_day_id=@week_day)
set @duration_sum=(select sum(datediff(minute,'00:00:00',s.duration))
from bookings b join booking_service bs on bs.booking_id=b.id
join [services] s on s.id=bs.service_id where b.client_id=@client)
if exists(select*from
bookings b join inserted i on b.barber_id=i.barber_id
and b.week_day_id=i.week_day_id
join booking_service bs on bs.booking_id=b.id
join [services] s on s.id=bs.service_id
where b.start_time<(dateadd(minute,@duration_sum,i.start_time))
and (dateadd(minute,@duration_sum,b.start_time))>i.start_time
and i.start_time>=@end_time
and i.start_time<@start_time)
begin
rollback tran
print('This date is busy')
end
end
Я делаю вроде проверку:
and i.start_time>=@end_time
and i.start_time<@start_time)
а оно не работает
Эти базы данных просто сводят меня с ума))
Так а тут и не просили проверять работает ли он в это время.
Это можно отдельным тригером или if’ом сделать, чтобы не путаться (и выдать соотв. сообщение).
В первом видимо должно быть start_time + duration_sum.
Так и не разобрался с этой задачей. Переделал немного теперь вообще никто не добавляется
create trigger tg_booking_taboo on bookings
after insert
as
begin
declare @duration_sum int
declare @end_time time
declare @start_time time
declare @client int
declare @barber int
declare @week_day int
select @client=client_id, @barber=barber_id, @week_day=week_day_id
from inserted
set @duration_sum=(select sum(datediff(minute,'00:00:00',s.duration))
from bookings b join booking_service bs on bs.booking_id=b.id
join [services] s on s.id=bs.service_id where b.client_id=@client)
set @end_time=(select end_time from schedule where barber_id=@barber
and week_day_id=@week_day)
set @start_time=(select start_time from schedule where barber_id=@barber
and week_day_id=@week_day)
if exists(select*from inserted i,bookings b
where i.id=b.id
and (b.start_time<(dateadd(minute,@duration_sum,i.start_time))
and (dateadd(minute,@duration_sum,b.start_time))>i.start_time)
or (i.start_time<@start_time and
(dateadd(minute,@duration_sum,i.start_time)>=@end_time)))
begin
rollback tran
print('This time is busy')
end
end
Мне кажется, я не правильно джойню. В этом случае if exists(select*from inserted i,bookings b where i.id=b.id у меня вообще нет джойнов и я не могу добавить никого вообще. А в первом случае if exists(select*from bookings b join inserted i on b.barber_id=i.barber_id and b.week_day_id=i.week_day_id join booking_service bs on bs.booking_id=b.id join [services] s on s.id=bs.service_id
добавляю куда хочу. Нужно найти золотую середину)
Да я уже все перепробовал. Вот, например, был у меня и такой вариант, который тоже не работает:
create trigger tg_booking_taboo on bookings
instead of insert
as
begin
declare @duration_sum int
declare @end_time time
declare @start_time time
declare @client int
declare @barber int
declare @week_day int
select @client=client_id, @barber=barber_id, @week_day=week_day_id
from inserted
set @duration_sum=(select sum(datediff(minute,'00:00:00',s.duration))
from bookings b join booking_service bs on bs.booking_id=b.id
join [services] s on s.id=bs.service_id where b.client_id=@client)
set @end_time=(select end_time from schedule where barber_id=@barber
and week_day_id=@week_day)
set @start_time=(select start_time from schedule where barber_id=@barber
and week_day_id=@week_day)
if exists(select*from
bookings b join inserted i on b.barber_id=i.barber_id and b.week_day_id=i.week_day_id
join booking_service bs
on bs.booking_id=b.id join [services] s on s.id=bs.service_id
where (b.start_time<(dateadd(minute,@duration_sum,i.start_time))
and (dateadd(minute,@duration_sum,b.start_time))>i.start_time))
begin
print('This time is busy')
rollback tran
end
else if exists(select*from inserted i,bookings b
where i.id=b.id
and i.start_time<@start_time and
(dateadd(minute,@duration_sum,i.start_time)>=@end_time))
begin
print('The working day has not started or has ended')
rollback tran
end
else
begin
insert bookings(client_id,barber_id,week_day_id,start_time)
select client_id,barber_id,week_day_id,start_time
from inserted
end
end
Ура!!! Я понял в чем дело! Вот окончательный рабочий вариант:
create trigger tg_booking_taboo on bookings
after insert
as
begin
declare @duration_sum int
declare @end_time time
declare @start_time time
declare @client int
declare @barber int
declare @week_day int
select @client=client_id, @barber=barber_id, @week_day=week_day_id
from inserted
set @duration_sum=(select sum(datediff(minute,'00:00:00',s.duration))
from bookings b join booking_service bs on bs.booking_id=b.id
join [services] s on s.id=bs.service_id where b.client_id=@client)
set @end_time=(select end_time from schedule where barber_id=@barber
and week_day_id=@week_day)
set @start_time=(select start_time from schedule where barber_id=@barber
and week_day_id=@week_day)
if exists(select*from
bookings b join inserted i on b.barber_id=i.barber_id and b.week_day_id=i.week_day_id
join booking_service bs
on bs.booking_id=b.id join [services] s on s.id=bs.service_id
where (b.start_time<(dateadd(minute,@duration_sum,i.start_time))
and (dateadd(minute,@duration_sum,b.start_time))>i.start_time))
begin
rollback tran
print('This time is busy')
end
else if exists(select*from inserted i join bookings b
on i.barber_id=b.barber_id and i.client_id=b.client_id
where i.start_time<@start_time or
(dateadd(minute,@duration_sum,i.start_time)>=@end_time))
begin
rollback tran
print('The working day has not started or has ended')
end
end
Вот тут у меня было "and’’.
where i.start_time<@start_time **or**
(dateadd(minute,@duration_sum,i.start_time)>=@end_time))
И понятное дело оно не работало. Спасибо, что не послали меня подальше и привели меня к правильному решению)
А теперь не пойму, как это вот сделать. С какой стороны вообще подойти к этому? Как вообще эти слоты показать? Цикл тут нужен наверное? Но как, все равно не понимаю