SQL触发器-插入记录后更新余额

时间:2018-11-21 11:47:02

标签: sql sql-server

我有两个桌子 手镯(IDbracelet,BALANCE)和MoneyLoad(IDMoneyLoad,IDbracelet,Value) 我要完成的工作是,每次在MoneyLoad表中插入一个值(balance = balance + value)时,用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

2 个答案:

答案 0 :(得分:0)

关于您的消息错误,我认为BALANCE可以为NULL值。您是否进行了验证(如果您的BALANCE的IDBRACELET值为NULL)。如果您确定自己的IDBRACELET始终被填充;您可以尝试以下查询:

Update BRACELETS
Set BALANCE = ISNULL(BALANCE,0)+ 
    (
    Select Sum(I.VALUE)
    From Inserted I 
    Where BRACELETS.IDBRACELET = I.IDBRACELET
    )
From BRACELETS

因此,如果您的IDBRACELET可以为null,那么您可以尝试以下操作:

Update BRACELETS
Set BALANCE = ISNULL(BALANCE,0) + 
    ISNULL(
    Select Sum(I.VALUE)
    From Inserted I 
    Where BRACELETS.IDBRACELET = I.IDBRACELET
    ),0)
From BRACELETS

希望这可以为您提供帮助。

答案 1 :(得分:0)

您的触发器正在尝试更新Bracelets表的每一行。对于插入中未包含的任何行,SUM为NULL。将NULL添加到天平将导致NULL。您只想更新插入的记录所引用的那些记录。

除了避免出现NULL之外,还可以想象您的Bracelets表具有一百万条记录。每次将一条记录添加到MoneyLoad时,将更新所有百万条记录。

此外,在INSERT触发器中将不需要NOT NOTISTS检查。 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