【问题标题】:SQL Server 2005 'INSTEAD OF' DELETE Trigger - Not deleting Source RecordsSQL Server 2005 'INSTEAD OF' DELETE 触发器 - 不删除源记录
【发布时间】:2014-11-11 23:03:48
【问题描述】:

我在 SQL Server 2005 中创建了一个触发器,该触发器在源表中发生删除时将记录插入到历史表中。记录正在被插入,但并未从源表中删除。

这是我的触发器:

CREATE TRIGGER TRG_EdiHistory 
ON  dbo.EDI10000 
INSTEAD OF DELETE
AS 
BEGIN
    SET NOCOUNT ON;

    SET IDENTITY_INSERT dbo.EDI10500 ON;

    INSERT INTO EDI10500(File_Id, Tp_Id, File_Name, File_Size, File_Data, Rec_Date, Content_Type, Update_Flag)
       SELECT 
          File_Id, Tp_Id, File_Name, File_Size, File_Data,
          Rec_Date, Content_Type, Update_Flag
       FROM 
          DELETED   
END
GO

我必须使用INSTEAD OF 触发器,因为我的表包含Image 类型的列。

请如果有人知道为什么会发生这种情况。

谢谢。

* 更新 *

CREATE TRIGGER TRG_EdiHistory 
ON  dbo.EDI10000 
INSTEAD OF DELETE
AS 
BEGIN
   SET NOCOUNT ON;

   SET IDENTITY_INSERT dbo.EDI10500 ON;

    INSERT INTO EDI10500 ([File_Id],Tp_Id,[File_Name],File_Size
                            ,File_Data,Rec_Date,Content_Type,Update_Flag)
    SELECT   [File_Id], Tp_Id, [File_Name], File_Size, File_Data,
          Rec_Date, Content_Type, Update_Flag
    FROM DELETED    

    DELETE FROM dbo.EDI10000
    WHERE EXISTS (SELECT 1 
                  FROM DELETED
                  WHERE [FILE_ID] = dbo.EDI10000.[File_Id])

END
GO

【问题讨论】:

  • 嗯,你希望一个叫做“INSTEAD OF DELETE”的东西到底能做什么?
  • 您需要AFTER DELETE Trigger。其余的应该没问题。
  • 你为什么使用图像数据类型?它自 2005 年以来已被弃用。请改用 varbinary(max)。
  • 不能使用带有 Image 数据类型的 AFTER DELETE 触发器。并且不能更改为 varbinary(MAX) 因为它的 SQL 2005。试图将其更改为 varbinary(MAX) 但不允许我。
  • @hmakled: SQL Server 2005 DOES 支持VARBINARY(MAX) .... 您是如何尝试将数据类型更改为VARBINARY(MAX),到底发生了什么?跨度>

标签: sql sql-server sql-server-2005 database-trigger


【解决方案1】:

而不是 Triggers , fire 而不是触发动作。在您的情况下,这不是 Trigger 触发并将数据插入到您的历史记录表中。

请注意,此触发器会触发而不是 Delete 命令。因此,如果您还想删除行,则需要在此触发器中添加 Delete 语句。

话虽如此,我认为如果您简单地定义一个与您的 this 而不是触发器具有相同定义的 After Trigger 而不是 Instead Trigger 将使事情变得非常简单。它会从表中删除行,然后将行插入到您的历史表中,正如您所期望的那样。

更新

由于您提到不能在 sql server 2005 中的 After Trigger 中使用图像数据类型,因此我不知道此限制。那么在这种情况下,您可以简单地在现有的而不是触发器中添加一个删除语句。

DELETE FROM dbo.table
WHERE EXISTS (SELECT 1 
              FROM deleted 
              WHERE Pk_Column = table.PK_Column)

【讨论】:

  • 我尝试了 After Trigger,但出现错误,因为我的表的 Image 数据类型不能与 SQL Server 2005 中的 After Trigger 一起使用。
  • hmmm...不确定这个限制,但无论如何只需在触发器定义中添加删除语句。
  • 如何在触发器中添加 Delete 语句?不知道怎么做。我只是从 dbo.table 中删除吗?
  • 这是我添加的,但仍未删除:DELETE FROM dbo.EDI10000 WHERE EXISTS (SELECT 1 FROM DELETED WHERE File_Id = EDI10000.File_Id)
  • 阿里先生,您看到我最后的回复了吗?我做对了吗,导致它没有被删除。我在“SELECT (.....) FROM DELETED”语句之后的最后添加了这个删除语句。
【解决方案2】:

代替delete 替换DELETE 语句的标准操作。

http://technet.microsoft.com/en-us/library/ms191208(v=sql.105).aspx

看看这里如何做你真正想做的事: How to create a before delete trigger in SQL Server?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 2011-09-21
    • 2017-11-26
    • 1970-01-01
    相关资源
    最近更新 更多