【问题标题】:SQL Trigger action based off comparing deleted and inserted value基于比较删除和插入值的 SQL 触发器操作
【发布时间】:2020-10-27 01:06:58
【问题描述】:

我用 C# 编写了一个库存应用程序,并希望跟踪库存数量的变化。为此,我有两个表:tblInventory 和 tblInvChange。目前我有一个更新后触发器,它通过将以下内容添加到 tblInvChange 中效果很好:(使用 d. 表示已删除,i. 表示插入)d.lastphysical; i.lastphysical; d.数量; i.数量。

我的问题是,如果我在同一天返回并更改一件商品的数量,我将获得同一商品同一日期的两条记录。如果日期不存在,我想让触发器将记录插入到 tblInvChange 表中,如果存在则更新当前记录。

    BEGIN
If(Select [fldlastPhysical] from deleted) <> (Select [fldLastPhysical] from inserted)

INSERT tblInvTracking(keyProductID, fldLocationId, fldLastPhysical, fldQuantity, fldInventoryChange, fldNewQuantity)
SELECT
   D.keyProductID, D.fldLocationID, D.fldLastPhysical, d.fldQuantity, i.fldLastPhysical, i.fldQuantity
FROM
   DELETED D JOIN INSERTED I ON D.keyProductID = I.keyProductID AND D.fldLocationID = I.fldLocationID;

Else

UPDATE tblInvTracking(keyProductID, fldLocationId, fldLastPhysical, fldQuantity, fldInventoryChange, fldNewQuantity)
SELECT
   D.keyProductID, D.fldLocationID, D.fldLastPhysical, d.fldQuantity, i.fldLastPhysical, i.fldQuantity
FROM
   DELETED D JOIN INSERTED I ON D.keyProductID = I.keyProductID AND D.fldLocationID = I.fldLocationID;

END

这是我的理解,但不起作用。一个关于正确方法的例子将不胜感激。

【问题讨论】:

  • Dale,我正在使用您的示例,以确保无需额外的 cmets 即可使其正常工作。你非常有帮助,我刚刚回到网站接受你的回答。注意:我对像 Marc 这样批评评论但不提供答案的人不满意。 sql-server 标记从一开始就存在。他的目的是什么?
  • @Charles 不用担心延迟接受这个答案,但请重新审视你的旧问题并接受答案,甚至在适用的情况下接受你自己的答案。您可以投票任何有用的答案,即使您不能接受他们的答案,也可以奖励他们。
  • 如果您查看编辑历史记录(单击我名字上方的“昨天编辑”链接),您会发现当您最初发布问题时它没有标签“SQL Server”,这是由“a_horse_with_no_name”在随后的编辑中添加的。 SO 是一个非常没有人情味的网站,人们是非常实事求是的 - 最好不要把它当作个人。
  • 还有一个错误我想不通;第 22 行 [第 6 行批处理开始] 操作数数据类型日期对于添加运算符无效。

标签: sql-server tsql database-trigger


【解决方案1】:

您需要创建 2 个语句,一个插入不存在的记录,一个更新存在的记录。尽我所能告诉它如下所示,但这不会 100% 正确,您需要仔细研究逻辑并确保它与您想要实现的目标相匹配。

注意:这是假设 fldLastPhysical 是感兴趣的日期,并且它是 date 而不是 datetime

-- WHERE THE RECORD DOESN'T EXIST FOR THE GIVEN DATE - ADD A NEW ONE
INSERT tblInvTracking(keyProductID, fldLocationId, fldLastPhysical, fldQuantity, fldInventoryChange, fldNewQuantity)
    SELECT D.keyProductID, D.fldLocationID, D.fldLastPhysical, d.fldQuantity, i.fldLastPhysical, i.fldQuantity
    FROM DELETED D
    JOIN INSERTED I ON D.keyProductID = I.keyProductID AND D.fldLocationID = I.fldLocationID
    -- ONLY ADD A NEW RECORD FOR THIS DATE IF IT DOESN"T ALREADY EXIST
    WHERE NOT EXISTS (
      SELECT 1
      FROM tblInvTracking T
      WHERE T.fldlastPhysical = D.fldLastPhysical
      AND T.keyProductID = D.keyProductID AND T.fldLocationID = D.fldLocationID
    );

-- WHERE THE RECORD EXISTS FOR THE GIVEN DATE - UPDATE EXISTING
UPDATE T SET
    fldQuantity = T.fldQuantity + X.fldQuantity
    -- It appears the following line is a datetime column, so you will need to determine what logic is required there - maybe just a straight update.
    , fldInventoryChange = X.fldInventoryChange
    , fldNewQuantity = T.fldNewQuantity + X.fldNewQuantity
FROM tblInvTracking T
INNER JOIN (
    SELECT D.keyProductID, D.fldLocationID, D.fldLastPhysical, d.fldQuantity, i.fldLastPhysical fldInventoryChange, i.fldQuantity fldNewQuantity
    FROM DELETED D
    JOIN INSERTED I ON D.keyProductID = I.keyProductID AND D.fldLocationID = I.fldLocationID
    -- ONLY ADD A NEW RECORD FOR THIS DATE IF IT DOESN"T ALREADY EXIST
    WHERE EXISTS (
      SELECT 1
      FROM tblInvTracking T
      WHERE T.fldlastPhysical = D.fldLastPhysical
      AND T.keyProductID = D.keyProductID AND T.fldLocationID = D.fldLocationID
    )
) X ON T.fldlastPhysical = X.fldLastPhysical AND T.keyProductID = X.keyProductID AND T.fldLocationID = X.fldLocationID

【讨论】:

  • Dale,你是说我不需要 IF 语句吗?我的字段是日期字段。你的逻辑是正确的。我知道你有两个陈述,但你不需要逻辑吗?另外,“从……中选择 1”?谢谢。
  • @Charles - 不,你不是IF - 那是过程逻辑,在 SQL Server 中最好使用基于集合的逻辑。只需将所有条件放在WHERE 子句中即可。其中一个语句可能不会影响任何行,但没关系。
  • select 1 from 正在检查您是否已经拥有该组合(产品、位置和日期)的跟踪记录,这是我从您的问题中了解到的您想要做的事情。但我可能是错的,因为您的 IF 似乎是在比较 Inserted 和 Deleted。
  • 您可能需要在WHERE 子句中进行额外检查,以检查任何值是否已更改。
  • 我可能仍然遗漏了一些东西,但最后一行有错误。 'FldLastPhysical 列已为 X 指定了多次"。我仍在努力理解您向我展示的内容,但由于您对我的帮助很大,我继续将其标记为已回答。我们将不胜感激。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-10
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-25
相关资源
最近更新 更多