SQL Server触发器用于更新另一个表的列

6
我有两个SQL Server表,分别为Table ATable B。我有一个应用程序,可以同时向Table A插入一行记录,并向Table B插入三行记录。如下图所示,我们可以根据Table AID列和Table BTransID列来链接这些插入的记录。

在插入Table B数据时,如果其中任何一行的Printed列包含一个值为Printed,则我希望将Table A相关记录的PrintStatus列也更新为Printed

我该如何编写SQL Server触发器来实现这一功能?


1
我认为你可以在不使用触发器的情况下完成这个任务。 - Arnaud Peralta
没有人可以更改应用程序。我猜这不是一个开源应用程序。 - Crysis Hhtht
我正在使用触发器编写查询。我没有考虑应用程序的锁定代码。 - Arnaud Peralta
@CrysisHhtht . . . 触发器解决方案相当复杂。它需要考虑更新、插入和删除。 - Gordon Linoff
是的,但如果Crysis确定不会更新数据,我们可以在INSERT上设置一个简单的触发器。 - Arnaud Peralta
显示剩余4条评论
3个回答

4

最佳方案是在您的代码(app)中执行此操作,但如果没有办法,您可以编写类似于下面触发器示例的表B插入后触发器:

CREATE TRIGGER [dbo].[YourTrigger] ON [dbo].[TableB]
    AFTER INSERT
AS
DECLARE @id INT
BEGIN
SET NOCOUNT ON;
 SET @id = (SELECT DISTINCT ID FROM Inserted)
 IF EXISTS (SELECT * FROM Inserted WHERE Printed='Printed')   
  UPDATE TableA
  SET PrintStatus='Printed'
  WHERE ID = @id

END

希望这能对您有所帮助


是的,我知道。我会检查这个触发器并让你知道。谢谢。 - Crysis Hhtht
好的,我会看一下它们。 - Crysis Hhtht
1
你的触发器存在一个重大缺陷,即你似乎假设它将在每行一次调用 - 这并不正确。触发器将每个语句触发一次,因此如果你的INSERT导致该触发器插入3行,则触发器会触发一次,而Inserted伪表将包含25行。你的代码将从Inserted中选择哪些3行?这是不确定的,你将得到一个任意的行,而你将忽略所有其他行。你需要重写你的触发器以考虑这一点! - marc_s
好的,我没有看到马克提出的观点。是的,也许我应该稍后添加它。谢谢@marc_s。 - El.Hum

2
这可能适合您的问题:(并不百分之百确定)"最初的回答"。
CREATE TRIGGER TriggerTableB
ON TableB
AFTER INSERT
AS
    UPDATE TableA AS A
    SET PrintStatus = 'Printed'
    WHERE A.TranID = inserted.ID
        AND 'Printed' = (SELECT MAX(I.Printed)
                         FROM inserted AS I)

1
谢谢Amaud。我会查看并告诉你。 - Crysis Hhtht

0
我建议查询这些信息:
select a.*,
       (case when exists (select 1
                          from b
                          where b.id = a.tranid and b.printed = 'Printed'
                         )
             then 'Printed'
        end) as printstatus
from a;

这比编写查询简单,而且您可以将其包装在视图中。

从性能角度来看,在b(id,printed)上创建索引应该会使其非常快速 - 而不会减慢插入速度。

如果要考虑insertupdatedelete,触发器可能会相当复杂。 如果可能的话,我更喜欢避免这种复杂性。


高登在插入数据后,不会有任何更新或删除已插入数据的操作。因此,您能告诉我如何为插入触发器更新此操作吗? - Crysis Hhtht

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接