【问题标题】:How to delete all rows without deleting the last returned row in SQL Server?如何在不删除 SQL Server 中最后返回的行的情况下删除所有行?
【发布时间】:2013-05-06 15:18:42
【问题描述】:

我想在执行删除查询时使用触发器删除 SELECT 中的所有行,而不删除最后返回的行。

此触发器不起作用,因此非常感谢任何帮助。

CREATE TRIGGER TR_StergereOfertaSpeciala
ON OferteSpeciale
INSTEAD OF DELETE
AS
DECLARE @nr INTEGER;

IF (EXISTS(SELECT * FROM DELETED))
BEGIN
SET @nr = (SELECT COUNT(*) FROM DELETED); 

DELETE FROM (   
SELECT TOP(@nr - 1)* FROM OferteSpeciale
INNER JOIN DELETED ON OferteSpeciale.codP = Deleted.codP 
    AND OferteSpeciale.codM = Deleted.codM 
    AND OferteSpeciale.dela = Deleted.dela)

END

【问题讨论】:

  • 你没有ORDER BY,如何确定“最后一行”?
  • 触发器不起作用”是什么意思?它现在做了什么,或者它给出了什么错误?
  • 另外,... {codp, codM, dela}OferteSpeciale 表上的唯一键或主键吗?
  • 是的 codP、codM 和 dela 是唯一的主键。触发器给出了一个合成错误。

标签: sql sql-server tsql triggers


【解决方案1】:

以下是让您的概念正常工作的示例:

CREATE TRIGGER TR_StergereOfertaSpeciala
ON OferteSpeciale
INSTEAD OF DELETE
AS BEGIN
    DECLARE @nr INT
    SET @nr = (SELECT COUNT(*) FROM DELETED)
    IF (@nr > 1) BEGIN
        DELETE o
        FROM OferteSpeciale AS o
            INNER JOIN (SELECT TOP (@nr - 1) * FROM DELETED /* ORDER BY ??? */) AS d
                ON o.codP = d.codP 
                AND o.codM = d.codM 
                AND o.dela = d.dela
    END
END

注意使用连接删除的语法。另请注意,我们任意选择要保留的 1 行。我建议,正如@RBarryYoung 所提到的,专门按 something 排序集合以了解我们保留哪一行。

另一种可以避免有些动态的TOP 子句(聪明,顺便说一句)的方法是专门排除您要使用NOT EXISTS/IN 保留的记录

此外,在这种情况下,您可能希望避免使用 trigger recursionnested triggers

【讨论】:

  • +1:虽然实际上,如果@nr大于1,你只需要执行DELETE
  • 非常感谢!这正是我所需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 2021-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多