在删除 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 之前显示结果的主要内容,如果未能解决你的问题,请参考以下文章
4 - SQL Server 2008 之 使用SQL语句删除表格