4

我有一个包含几个表的数据库:tab1、tab2、tab3。如何仅为 tab2(不适用于 tab1 和 tab3)在 drop table 上创建 DDL 触发器。何时drop tab2调用我需要更新此表中的值但不删除 tab2。我怎样才能做到这一点?我发现了这个,但不明白它是如何工作的:

create trigger trDatabse_OnDropTable
on database
for drop_table
as
begin
 set nocount on;
 select
  'Table dropped: ' +
  quotename(eventdata().value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname')) + N'.' +
  quotename(eventdata().value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname'));
end;

谢谢!

4

3 回答 3

3
create trigger trDatabse_OnDropTable
on database
for drop_table
as
begin
    set nocount on;

    --Get the table schema and table name from EVENTDATA()
    DECLARE @Schema SYSNAME = eventdata().value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname');
    DECLARE @Table SYSNAME = eventdata().value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname');

    IF @Schema = 'dbo' AND @Table = 'tab2'
    BEGIN
        PRINT 'DROP TABLE Issued.';

        --Optional: error message for end user.
        RAISERROR ('[dbo].[tab2] cannot be dropped.', 16, 1);

        --Rollback transaction for the DROP TABLE statement that fired the DDL trigger
        ROLLBACK;

        --Run your update after the ROLLBACK
        BEGIN TRAN
            UPDATE dbo.tab2
            SET ... ;
        COMMIT;
    END
    ELSE
    BEGIN
        --Do nothing.  Allow table to be dropped.
        PRINT 'Table dropped: [' + @Schema + '].[' + @Table + ']';
    END
end;
于 2016-07-01T17:49:38.107 回答
3

您可以使用 ddl 触发器防止删除表。就像是:

CREATE TRIGGER drop_safe 
ON DATABASE 
FOR DROP_TABLE 
AS 
   PRINT 'You must disable Trigger "drop_safe" to drop table!' 
   ROLLBACK
;

为了只防止在您指定的表上删除,您必须仅在这种特殊情况下查看 eventdata() 和 ROLLBACK。

于 2015-12-10T15:20:11.763 回答
1

在本文DDL 触发器中,您会发现没有 INSTEAD OF DDL 触发器,就像在 DML 触发器中一样,因此您无法阻止删除并改为执行您自己的命令:

DDL 触发器仅在触发它们的 DDL 语句运行后触发。DDL 触发器不能用作 INSTEAD OF 触发器。DDL 触发器不会触发以响应影响本地或全局临时表和存储过程的事件。

您发布的这段代码用于记录 DROP TABLE 事件。eventdata()包含有关事件的一些信息的 XML:LoginName、ObjectName、TSQLCommand、PostTime 等等。

于 2014-12-29T11:37:43.790 回答