Худшее, что вы делали, - это получение очень дорогого счета только для проверки на существование.Это дорого и не нужно - тем более, что вы использовали это, чтобы решить, собираетесь ли вы обновлять ИЛИ вставку.В случае вставки из нескольких строк вам может потребоваться выполнить оба действия.
Шаг 1. Обновите существующие
;WITH x AS
(
SELECT d = DATEADD(DAY, 0, DATEDIFF(DAY, 0, i.TimeOut)),
h = DATEPART(HOUR, i.TimeOut),
m = DATEPART(MINUTE, i.Timeout)
FROM inserted
),
y AS
(
SELECT d, h, m, Total = COUNT(*)
FROM x GROUP BY d, h, m
)
UPDATE h
SET Total += y.Total,
LastUpdate = CURRENT_TIMESTAMP
FROM dbo.DataWarehouse_HourlyStats AS h
INNER JOIN y
ON h.[Day] = y.d
AND h.HourOfTheDay = y.h
AND h.MinuteOfTheHour = y.m;
Шаг 2. Вставьте те, которые не
;WITH x AS
(
SELECT d = DATEADD(DAY, 0, DATEDIFF(DAY, 0, i.TimeOut)),
h = DATEPART(HOUR, i.TimeOut),
m = DATEPART(MINUTE, i.Timeout)
FROM inserted
),
y AS
(
SELECT d, h, m, Total = COUNT(*)
FROM x WHERE NOT EXISTS
(
SELECT 1 FROM dbo.DataWarehouse_HourlyStats
WHERE [Day] = x.d
AND HourOfTheDay = x.h
AND MinuteOfTheHour = x.m
)
GROUP BY d, h, m
)
INSERT dbo.DataWarehouse_HourlyStats
(
HourOfTheDay,
MinuteOfTheHour,
[Day],
Total
)
SELECT h,m,d,Total
FROM y;
Похоже, больше кода, но я уверяю вас, это более эффективно и более точно, чем ваша существующая версия.
Тем не менее, это будет довольно дорогой триггер, независимо от того, есть ли у васмного вставок.Я надеюсь, что, по крайней мере, в столбцах «День», «Час», «Минута» есть хороший индекс поддержки.
Может быть, лучше составить статистику с использованием ежечасного или ежедневного пакетного задания.Сам триггер по определению является частью транзакции, поэтому вы не можете отложить принятие, если вы просто не поместите данные в таблицу очередей или фоновую таблицу и не исправите ее каким-либо другим заданием.