1

在 Sql Server 中,我想防止用户删除标有特定扩展属性的对象。我认为这可以通过 DROP 事件上的 DDL 触发器轻松完成。事实证明,这些触发器是在对象被删除后触发的,因此不再可能访问扩展属性,并且它们在事件数据中不可用。

有什么方法可以访问 DDL 触发器中已删除对象的扩展属性?

下面的代码不起作用,因为扩展属性已被删除:

CREATE TRIGGER PreventDeletionOfAutogeneratedTriggers ON DATABASE 
FOR DROP_TRIGGER
AS
    DECLARE @TriggerName sysname    =     EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname')
    DECLARE @TriggerSchema sysname  = EVENTDATA().value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname')
    DECLARE @ObjectId int           = OBJECT_ID(QUOTENAME(@TriggerSchema) + '.' + QUOTENAME(@TriggerName))
IF EXISTS (
    SELECT
        *
    FROM
        sys.extended_properties
    WHERE
        major_id = @ObjectId AND
        name = 'Autogenerated'
)
BEGIN
    RAISERROR ('Cannot drop triggers that are autogenerated.',16, 10)
    ROLLBACK
END 
GO
4

1 回答 1

0

目前,DDL 触发器仅在 DDL 语句完成后触发,这意味着您将无权访问适当的元数据以强制回滚。

DDL 语句不存在 INSTEAD OF 触发器,这基本上是完成此任务所需的。

您可以在此处投票支持 INSTEAD OF DDL 触发器: https ://connect.microsoft.com/SQLServer/feedback/details/243986

我的建议是将这些对象放在单独的架构中并在架构上设置权限,或者通过用户角色和权限锁定它们。

这是指向有关 DDL 触发器的更多信息的链接。 https://technet.microsoft.com/en-us/library/ms175941(v=sql.120).aspx

于 2015-03-17T12:13:23.413 回答