在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
答案 0 :(得分:0)
目前,DDL触发器仅在DDL语句完成后触发,这意味着您无权访问相应的元数据以强制执行ROLLBACK。
对于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