SQL Server - 如何在删除表后DROP_TABLE TRIGGER触发时从删除的表中复制数据?

时间:2012-12-12 12:33:04

标签: sql-server

我不希望阻止表丢失,但是当在数据库中删除某些表时,我想备份整个表或查询行,并在删除之前选择特定行到另一个表中。

如果桌面上有正常的触发器,如果​​删除了某行,则可以访问“已删除”按钮。表并访问那些已删除的行。

删除表后会触发DROP_TABLE触发器。

DROP_TABLE触发器的Deleted表是否等效? 我可以使用不同的方法吗? 或者我将不得不重新编写Windows服务中的业务逻辑,从而创建并删除这些表?

(我真的不想编写一个触发器来回滚丢弃,访问和复制数据,然后重新删除表而不会递归触发触发器。我喜欢创造力,但这对我来说太糟糕了。)

我是在Microsoft SQL Server企业版(64位)上运行的 和Microsoft SQL Server Developer Edition(64位)

2 个答案:

答案 0 :(得分:1)

感谢帮助人员,但要直接回答我自己的问题:

  1. 对于DDL触发器(触发DROP TABLE),DELETE / UPDATE触发器中没有等效的Deleted表

  2. 如果没有回滚丢弃,复制数据并重新发布丢弃,则没有相应的解决方案

  3. 唯一合适且正确的方法是重新编写Windows服务中的业务逻辑,以创建和删除这些表 - 允许在需要时进行软删除/移动/重命名

答案 1 :(得分:0)

如果是触发器的递归触发困扰你,可以检查。这只会运行初始的DROP TABLE。

alter Trigger ddlt_ProcessDropTable
on all server for drop_table
AS
begin
    if( trigger_nestlevel() = 1 ) -- only run if top level drop table
    begin
        declare @data XML
        set @data = EVENTDATA()
        -- rollback the drop
        rollback;

        -- get table name
        declare @TableName sysname, @SchemaName sysname, @DataBaseName sysname, @Sql nvarchar(1000);
        select 
            @TableName = @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(2000)'),
            @SchemaName = @data.value('(/EVENT_INSTANCE/SchemaName)[1]', 'nvarchar(2000)'),
            @DataBaseName = @data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'nvarchar(2000)')

        /****
        Do stuff with the dropped table...
        ****/

        -- re-drop the table
        set @sql = 'Drop Table ' + 
            QuoteName(@DataBaseName) + '.' + QuoteName(@SchemaName) + '.' + QuoteName(@TableName)
        exec(@sql)
    end

end
GO