【问题标题】:Trigger or stored procedure触发器或存储过程
【发布时间】:2018-01-18 09:19:06
【问题描述】:

每当 table2 上有新条目时,我都需要从 table2.field2 更新 table1.field1。我创建了一个可以做到这一点的触发器:

CREATE [dbo].[insert_trg]
on [dbo].[TheCat99]
AFTER INSERT AS
BEGIN
Update therefore.dbo.thecat99
SET factura = (SELECT dbo.pedido.num_factura
                    From dbo.Pedido
                    Where  dbo.thecat99.pedido=dbo.pedido.num_pedido)
WHERE dbo.thecat99.pedido = ( SELECT dbo.pedido.num_pedido
                           FROM dbo.pedido
                           Where dbo.thecat99.pedido = dbo.pedido.Num_Pedido)
AND dbo.thecat99.factura is NULL
END

触发器有效,但尚未投入生产。我一直在阅读有关触发器如何坏和坏的信息,但我不知道如何使用存储过程来做到这一点。 触发器是个好主意吗?如果没有,我怎样才能对存储过程做同样的事情?

【问题讨论】:

  • 你从哪里读到触发器是坏的和邪恶的,你有参考吗?使用过程,您需要将这两个动作都封装在过程中,并确保没有人在过程之外修改 table2。
  • 触发器本质上并不邪恶。 忽略 inserted 伪表(如此处)或未能说明包含 0、1 或多行的表的触发器通常会被破坏。当前,您的触发器中没有任何内容可以阻止它在每次插入期间必须扫描两个表的整体,而不是仅受插入的行的限制。

标签: sql sql-server triggers procedure


【解决方案1】:

触发器既不坏也不坏。它们是一个很棒的工具(对于某些任务,是唯一的工具),但它们确实需要知识和谨慎使用,因为它们并不像乍一看那样简单。

作为一般规则,触发器应尽可能轻巧且有效。 这是因为在触发器也完成之前,SQL Server 不会将控制权返回给执行触发触发器的语句的人。

话虽如此,你的更新代码可以这样写(这样会更高效、更易读):

UPDATE t
SET factura = p.num_factura
FROM therefore.dbo.thecat99 t
INNER JOIN  dbo.Pedido p ON t.pedido= p.num_pedido
WHERE t.factura IS NULL

但是由于您没有使用inserted 表,这意味着每次将任何行插入TheCat99 时,pedido 值与num_pedido 匹配的所有行Pedido 将用于更新。仍有改进的空间 - 使用 inserted 表而不是 thecat99 意味着您将只使用刚刚插入到 thecat99 表中的记录,因此您的代码将更加高效:

UPDATE t
SET factura = p.num_factura
FROM inserted t
INNER JOIN  dbo.Pedido p ON t.pedido= p.num_pedido
WHERE t.factura IS NULL

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 2013-09-12
    • 2016-06-25
    • 1970-01-01
    • 2013-12-30
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    相关资源
    最近更新 更多