Ral*_*alf 12 index sql-server view materialized-view sql-server-2012
正如标题行所暗示的那样:在具有索引的 VIEW 上使用 ALTER VIEW 语句将在没有警告的情况下从 VIEW 中删除此(所有?)索引。我希望 ALTER VIEW 语句失败,通知我先删除索引。
SQL SERVER 中是否有更改此行为的设置?还是在 SQL 2012 (SP3) 之后的版本中发生了变化?
Dav*_*oft 11
您可以防止使用 DDL 触发器更改索引视图。但是实现有点复杂,因为DDL触发器是在视图被修改和索引被删除之后运行的,但是在提交修改之前,你不能直接检测到视图之前有索引。
因此,您必须使用扩展属性进行一些恶作剧,只要在视图上创建索引,就将扩展属性放置在视图上。
例如:
create or alter trigger ddl_trig_prevent_alter_indexed_view
on database
for drop_index, create_index, alter_view
as
begin
--select eventdata().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)') , eventdata()
declare @schemaName sysname, @objectName sysname, @eventType varchar(50), @targetObjectType varchar(50)
,@targetObjectName sysname, @targetObjectSchemaName sysname
declare @e xml = eventdata();
select @eventType = @e.value('(/EVENT_INSTANCE/EventType)[1]','varchar(50)'),
@targetObjectType = @e.value('(/EVENT_INSTANCE/TargetObjectType)[1]','varchar(50)'),
@targetObjectName = @e.value('(/EVENT_INSTANCE/TargetObjectName)[1]','sysname'),
@schemaName = @e.value('(/EVENT_INSTANCE/SchemaName)[1]','sysname'),
@objectName = @e.value('(/EVENT_INSTANCE/ObjectName)[1]','sysname')
if @eventType = 'DROP_INDEX' and @targetObjectType = 'VIEW'
begin
--print @eventType
set @targetObjectSchemaName = (select schema_name(schema_id) from sys.views where name = @targetObjectName)
if exists( select * from fn_listextendedproperty ('HasIndex', 'SCHEMA', @targetObjectSchemaName, 'VIEW', @targetObjectName, NULL, NULL) )
and not exists( select * from sys.indexes where object_id = object_id( concat(quotename(@targetObjectSchemaName),'.',quotename(@targetObjectName))) )
begin
exec sp_dropextendedproperty
@name = N'HasIndex'
,@level0type = N'Schema', @level0name = @targetObjectSchemaName
,@level1type = N'View', @level1name = @targetObjectName
print 'Extended property HasIndex on view dropped.'
end
end
else if @eventType = 'CREATE_INDEX' and @targetObjectType = 'VIEW'
begin
--print @eventType
set @targetObjectSchemaName = (select schema_name(schema_id) from sys.views where name = @targetObjectName)
if exists( select * from fn_listextendedproperty ('HasIndex', 'SCHEMA', @targetObjectSchemaName, 'VIEW', @targetObjectName, NULL, NULL) )
begin
exec sp_updateextendedproperty
@name = N'HasIndex'
,@value = N'1'
,@level0type = N'Schema', @level0name = @targetObjectSchemaName
,@level1type = N'View', @level1name = @targetObjectName
print 'Extended property HasIndex on view updated.'
end
else
begin
exec sp_addextendedproperty
@name = N'HasIndex'
,@value = N'1'
,@level0type = N'Schema', @level0name = @targetObjectSchemaName
,@level1type = N'View', @level1name = @targetObjectName
print 'Extended property HasIndex on view added.'
end
end
else if @eventType = 'ALTER_VIEW'
begin
--print @eventType
if exists( select * from fn_listextendedproperty ('HasIndex', 'SCHEMA', @schemaName, 'VIEW', @objectName, NULL, NULL) where value = '1' )
begin
;throw 50001,'Cannot alter view with an index. Drop the index first.', 1;
rollback;
return;
end
end
else
begin
;throw 50001,'Unexpected event type in ddl trigger.', 1
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
721 次 |
| 最近记录: |