SQL Server触发器活动卡
我有以下表格:SQL Server触发器活动卡,sql,sql-server,database,triggers,Sql,Sql Server,Database,Triggers,我有以下表格: 卡(IDCard、IDPerson、余额、活动) 个人(个人) 每次插入新卡时,我都需要检查该卡是否已经属于某个人。如果是这样的话,我需要将“活动”更改为“假”,并且新卡必须收到上一张卡的余额,并且状态必须为“真” select count(c.IDPerson) from cards c, inserted i where c.IDPerson = i.IDPerson; if @@ROWCOUNT > 0 begin print'this card a
- 卡(IDCard、IDPerson、余额、活动)
- 个人(个人)
select count(c.IDPerson)
from cards c, inserted i
where c.IDPerson = i.IDPerson;
if @@ROWCOUNT > 0
begin
print'this card already exists'
select c.IDPerson, c.Balance, c.Active
INTO #tmp
FROM Cards c, inserted i
where c.IDCard = i.IDCard
update Cards
set Active = 0
from #tmp
where #tmp.IDPerson = Cards.IDPerson;
end
当我在cards表中插入一条新记录时,旧卡确实会变为false(0),但新卡也会保持active等于false。
这是在卡片表上的后插入
有人能告诉我如何解决这个问题吗?尽管您的触发器正在事务中运行,但我认为它仍然能够自我更新 当您更新INSERTED.IDPERSON=CARD.IDPERSON的位置时-这包括您插入的记录;因此,所有记录都更新为Active=false 相反,你应该这样做
update Cards
set Active = 0
from #tmp
where #tmp.IDPerson = Cards.IDPerson
AND Cards.IDCARD != #tmp.IDCARD --This is the new condition
我已经创建了一个副本,我相信你在这方面的要求
用户marc_s说您应该在这里使用连接语法也是正确的。您的整个操作可以在一个更简洁的语句中完成
UPDATE c
SET c.Active = 0
FROM Cards c
INNER JOIN Inserted i
ON i.IDPERSON = c.IDPERSON
AND i.IDCARD != c.IDCARD
如果不合适,则使用
。请记住,触发器可以同时处理多行
显式的join
执行所需的筛选。这有点复杂,但您可以使用两个join
s来完成:
update c2
set Active = (case when c2.IDCard = i.IDCard then 1 else 0 end)
from Cards c
inserted i
on c.IDCard = i.IDCard join
Cards c2
on c.IDPerson = c2.IDPerson;
你想在哪里处理这件事?例如,您的所有插入都将通过SP进行吗?-在ANSI-92 SQL标准(25年前)中,用正确的ANSIJOIN
语法替换了老式的逗号分隔的表列表样式,并且它的使用非常方便discouraged@Larnu不,不会的。我正在使用常规插入进行测试。插入到值中…您可能希望在此处使用而不是触发器,但是,我更愿意控制SP的插入过程,并停止盲目应用模式,而无需特殊原因。当方法具有有益效果时,应选择该方法。在单个语句可以完成所有需要的工作的情况下,此模式通常只会创建额外的工作,而没有任何好处。