У меня есть две таблицы браслеты (IDbracelet, BALANCE) и MoneyLoad (IDMoneyLoad, IDbracelet, Value) Я хочу обновить баланс браслета значением MoneyLoad каждый раз, когда значение вставляется в таблицу MoneyLoad (баланс = баланс + значение).
Я новичок в триггерах, поэтому не знаю, как действовать. Может ли кто-нибудь дать мне некоторое представление о том, как я должен это делать?
Обновлено: Я пробовал следующее, но когда я вставляю запись в MoneyLoad, появляется ошибка, говорящая, что баланс не может иметь значения NULL;
if not exists (select 1 from Deleted) -- Insert Trigger
BEGIN
Update BRACELETS
Set BALANCE = BALANCE +
(
Select Sum(I.VALUE)
From Inserted I
Where BRACELETS.IDBRACELET = I.IDBRACELET
)
From BRACELETS
END
Хотели бы вы также обновлять браслеты при удалении или обновлении записей из MoneyLoad?
Нет, вставлен только @DavidDubois
В вашем заявлении об обновлении обновляется каждая строка браслетов. Для любой строки Bracelets, которая не соответствует ни одной строке Inserted, SUM равно NULL. Итак, вы добавляете NULL к существующему балансу, что приводит к NULL.
Представление, которое вычисляет баланс, было бы гораздо лучшим подходом - особенно для очень неопытных. Расчетное значение баланса может быть сохранено при необходимости, но такие решения должны быть приняты позже. Для реализации триггеров требуется гораздо больше опыта, чем у вас сейчас.


Что касается вашего сообщения об ошибке, я думаю, что BALANCE может иметь значение NULL. Вы проверили это (если ваш BALANCE имеет значение NULL для некоторого IDBRACELET). Если вы уверены, что ваш IDBRACELET всегда заполнен; вы можете попробовать этот запрос:
Update BRACELETS
Set BALANCE = ISNULL(BALANCE,0)+
(
Select Sum(I.VALUE)
From Inserted I
Where BRACELETS.IDBRACELET = I.IDBRACELET
)
From BRACELETS
Итак, если ваш IDBRACELET может быть нулевым, вы можете попробовать это:
Update BRACELETS
Set BALANCE = ISNULL(BALANCE,0) +
ISNULL(
Select Sum(I.VALUE)
From Inserted I
Where BRACELETS.IDBRACELET = I.IDBRACELET
),0)
From BRACELETS
Надеюсь, это поможет тебе.
Ваш триггер пытался обновить каждую строку таблицы браслетов. Для любой строки, которая не была включена во вставку, СУММ будет ПУСТО (NULL). Добавление NULL к балансу приводит к NULL. Вы хотите обновить только те записи, на которые ссылаются вставленные записи.
Помимо того, чтобы избежать этой проблемы с NULL, представьте, что ваша таблица Bracelets имеет миллион записей. Каждый раз, когда запись добавлялась в MoneyLoad, обновлялись все миллионы записей.
Кроме того, проверка НЕ СУЩЕСТВУЕТ в триггере INSERT. DELETED всегда будет пустым.
Этот триггер может хорошо работать для INSERT, но вы можете подумать, что произойдет, если какие-либо записи будут обновлены или удалены.
create table Bracelets
( IDBracelet nvarchar(30) not null primary key,
Balance money not null default 0 );
create table MoneyLoad
( IDBracelet nvarchar(30) not null
foreign key references Bracelets(IDBracelet),
[Value] money not null );
go
create trigger tx_MoneyLoad on MoneyLoad
for insert
as
begin
if not exists (select 1 from Deleted) -- Insert Trigger
BEGIN
Update BRACELETS
Set BALANCE = BALANCE +
(
Select Sum(I.VALUE)
From Inserted I
Where BRACELETS.IDBRACELET = I.IDBRACELET
)
where Bracelets.IDBracelet in ( select IDBracelet from Inserted )
END
end
go
insert into Bracelets ( IDBracelet ) values
( 'Bangle' ), ( 'Charm' ), ( 'Beaded' )
insert into MoneyLoad ( IDBracelet, [Value] ) values
( 'Bangle', 25 ), ( 'Charm', 10 ), ( 'Bangle', 20 )
select * from Bracelets
Результат:
IDBracelet Balance
------------------------------ ---------------------
Bangle 45.00
Beaded 0.00
Charm 10.00
Возможный дубликат SQL-триггер для вставки и обновления