在删除 SQL Server 之前显示结果

Posted

技术标签:

【中文标题】在删除 SQL Server 之前显示结果【英文标题】:Display Results Before Delete SQL Server 【发布时间】:2017-11-24 17:12:47 【问题描述】:

我很接近得到这个答案,但我觉得我错过了最后一部分。

我创建了一个DELETE 触发器,它应该显示来自SELECT 语句的值从表中删除它们之前。但是,当调用触发器时,我得到一个空白结果,但值(order_id=10001 AND product_id=25)仍然从表中删除。

我在运行触发器之前验证了SELECT 语句的工作原理,因此我确信该部分是正确的。

我尝试使用INSTEAD OF DELETE 触发器,但值最终没有被删除。我不相信 SQL Server 有 BEFORE DELETE 函数?有解决办法吗?

建议?

CREATE TRIGGER deleteOrderTrigger
ON order_details
FOR DELETE
AS
    SELECT order_details.product_id, products.name, 
           order_details.quantity AS 'Quantity being deleted from order', 
           SUM(products.quantity_in_stock) + order_details.quantity AS 'In Stock Quantity after Deletion'
    FROM order_details
    LEFT JOIN products ON products.product_id = order_details.product_id
    WHERE order_details.order_id = 10001 AND products.product_id = 25
    GROUP BY order_details.product_id, products.name, order_details.quantity

GO

-- Below is the code that will fire the trigger
DELETE order_details
WHERE order_id = 10001 AND product_id = 25

【问题讨论】:

这真的没有意义。我建议您在触发器中没有选择或删除。根据您的确切意图,您可以执行以下操作 - 创建一个运行删除的 SP,您的触发器可以将项目弹出到临时表或暂存区域,然后您的 SP 在删除语句之后询问该数据。 我应该创建一个临时表,还是应该使用虚拟 INSERTED 表? 【参考方案1】:

@JoeC - 使用 proc 可能是最好的答案。

如果您必须使用触发器,请记住必须对其进行编码以支持集合。如果有人执行delete order_details where order_id = 10001,那么您的触发器将需要返回订单中每个产品的库存水平。

此外,在编写触发器代码时,您可以访问名为已删除的内置表。此表包含已删除的记录。

所以你可以这样做:

CREATE TRIGGER deleteOrderTrigger
ON order_details
FOR DELETE
AS

INSERT INTO deleted_order_products_log

SELECT order_details.product_id
      ,products.name
      ,[Quantity being deleted from order] = order_details.quantity
      ,[In Stock Quantity after Deletion] = SUM(products.quantity_in_stock) + order_details.quantity
  FROM order_details
    INNER JOIN deleted d
        ON order_details.primaryKey = d.primaryKey
      LEFT JOIN products
          ON products.product_id = order_details.product_id
 GROUP BY order_details.product_id
         ,products.name
         ,order_details.quantity;

然后您可以查询日志文件以获取计算结果。

【讨论】:

我将看看你和@Joe C 的答案,看看有什么用。谢谢! 所以我认为这是最正确的答案,因为它使用了deleted 表,这是我在最终代码中使用的。谢谢你和@Joe C 帮助我:)【参考方案2】:

我没有经常使用触发器,但是您似乎有一个 AFTER 触发器,它无法读取已删除的行,这就是您得到空白结果的原因。

触发器的东西是插入和删除的表,也许这会有所帮助:https://docs.microsoft.com/en-us/sql/relational-databases/triggers/use-the-inserted-and-deleted-tables

如您所述,您需要一个 INSTEAD OF 触发器,但您必须自己执行删除操作。有关此主题的更多信息:https://docs.microsoft.com/en-us/sql/relational-databases/triggers/dml-triggers 和此处的一个示例:https://***.com/a/3267726/5605866

【讨论】:

【参考方案3】:

将触发器结果放入审计表中,您将看到触发器的结果。我从未见过与您的类似 where 子句的触发器。 插入表 x 选择...。您还想使用已删除的表(有一个插入的表),该表是为每次出现的触发器创建的,该触发器将包含刚刚删除的任何/所有行。删除发生在代码的主体中。然后调用触发器并删除包含已删除行的表(您只能在触发器中执行 delete * from deleted)。

【讨论】:

太好了,谢谢。我会查一下审计表是什么,看看能不能得到结果。 不,我的意思是审计表是您创建用于存储触发器结果的常规表。有一个 SQL Server 审计的概念,但这不是我所指的。

以上是关于在删除 SQL Server 之前显示结果的主要内容,如果未能解决你的问题,请参考以下文章

sql server 一直显示恢复怎么解决

SQL Server - 读取第一行并删除

4 - SQL Server 2008 之 使用SQL语句删除表格

sqlserver 怎么 修改数据

SQL Server:删除除最新的“n”个结果之外的所有结果

如何在 SQL Server 中运行 DELETE 语句之前确定要在相关/其他表中删除的记录