Вопрос в том, что должно произойти, если какой-либо сотрудник уже достиг максимального количества вопросов и вставлен новый. Должны ли вы поднять и ошибка и отклонить новую запись? Или не меняете эту таблицу и не пишите вставку в другую таблицу? Или что-нибудь еще? Я предполагаю, что вы хотите вызвать ошибку . В этом случае в триггере нам нужно вычислить границы недели и извлечь данные (количество вопросов) для всех сотрудников, вставленных сейчас (вы можете вставить несколько строк одновременно, и триггер сработает только один раз со всеми новыми строками во вставленной псевдотаблице) , В этом случае ваш триггер может выглядеть примерно так:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[Contentmenttable_AfterInsert]
ON [dbo].[Contentmenttable]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
SET DATEFIRST 1; -- Make Monday first day of the week
declare @StartOfTheWeek date, @StartOfNextWeek date, @QuestionsCount int, @EmployeeId int
-- datetiff calculates the number of whole weeks between current date and some other "zero" date
-- dateadd add back this number of whole weeks to this "zero" date to get the beginning of the current week.
select @StartOfTheWeek = dateadd(wk, datediff(wk, 0, getdate()), 0)
set @StartOfNextWeek = dateadd(day, 7, @StartOfTheWeek)
-- Get the employee with the highest number of questions returned by the derived table bellow
select top 1 @QuestionsCount = q.QuestionCount, @EmployeeId = q.EmployeeId
from (
-- Calculate number of questions per affected employee for current week
select count(distinct questionid) as QuestionCount, t.EmployeeId
from [dbo].[Contentmenttable] t
-- inserted pseudo table contains the rows that were added to the table
-- it may contain multiple rows for different employees if we are inserting more than one row at once
-- e.g. insert into Contentmenttable values(1, 111, '20180101', 0), (2, 222, '20180101', 0)
where t.EmployeeId in (select EmployeeId from inserted)
and t.[Date] >= @StartOfTheWeek and t.[Date] < @StartOfNextWeek
group by t.EmployeeId
) q
order by QuestionsCount desc
-- If the highest number of questions is more than 10, raise an error and rollback the insert
if (@QuestionsCount > 10)
raiserror('EmployeeId %d already has 10 questions this week.', 16, 1, @EmployeeId)
END
GO
ОБНОВЛЕНИЕ: Если строки в таблице будут вставляться только одна за другой, код может быть упрощен. Также это позволит устранить несоответствие с вводом строк за прошлые даты, которых нет на текущей неделе. Упрощенный триггер может выглядеть примерно так:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[Contentmenttable_AfterInsert]
ON [dbo].[Contentmenttable]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
if (select count(*) from inserted) > 1
raiserror('Rows in this table should inserted only one by one.', 16, 1)
SET DATEFIRST 1; -- Make Monday first day of the week
declare @StartOfTheWeek date, @StartOfNextWeek date, @QuestionsCount int, @EmployeeId int, @Date date
select @EmployeeId = EmployeeId, @Date = [Date]
from inserted
-- datetiff calculates the number of whole weeks between current date and some other "zero" date
-- dateadd add back this number of whole weeks to this "zero" date to get the beginning of the current week.
select @StartOfTheWeek = dateadd(wk, datediff(wk, 0, @Date), 0)
set @StartOfNextWeek = dateadd(day, 7, @StartOfTheWeek)
-- Calculate number of questions per affected employee for current week
select @QuestionsCount = count(questionid)
from [dbo].[Contentmenttable] t
where t.EmployeeId = @EmployeeId
and t.[Date] >= @StartOfTheWeek and t.[Date] < @StartOfNextWeek
-- If the highest number of questions is more than 10, raise an error and rollback the insert
if (@QuestionsCount > 10)
raiserror('EmployeeId %d already has 10 questions this week.', 16, 1, @EmployeeId)
END
GO