必须通过权限控制(deny alter/view definition)和ddl触发器双重防护才能有效防视图删除;schemabinding仅保护基表,不阻止drop view本身。

不能靠视图本身防删除,必须靠权限控制和对象依赖双重拦截。
为什么DROP VIEW不会被SCHEMABINDING拦住
SCHEMABINDING 只锁基表,不锁视图自己。你对带 WITH SCHEMABINDING 的视图执行 DROP VIEW,SQL Server 完全允许——它只关心“删视图”会不会影响其他依赖它的对象(比如索引视图),而不在乎谁删、有没有权限。
- 错误现象:
DROP VIEW vw_sales_summary成功执行,哪怕它是核心报表入口 - 真正起作用的是
VIEW DEFINITION或ALTER权限,不是绑定选项 - 如果视图被用于索引视图(
CREATE UNIQUE CLUSTERED INDEX),那删视图前得先删索引,否则报错 —— 但这属于间接约束,不可靠
用DENY阻止DROP VIEW的实操要点
直接回收删除权限是最有效、最可控的方式。注意:必须用 DENY,不是 REVOKE,因为 DENY 会压倒所有 GRANT(包括 db_owner 角色权限)。
- 对单个视图禁止删除:
DENY ALTER, VIEW DEFINITION ON [dbo].[vw_sales_summary] TO [dba_team] - 对整个 schema 禁止删视图:
DENY ALTER ON SCHEMA :: dbo TO [dba_team](但会影响建表/改表,慎用) - 关键细节:DBA 账号若属
db_owner角色,默认拥有ALTER权限;DENY必须显式执行,且需由更高权限账号(如sysadmin)运行 - 验证是否生效:
EXECUTE AS USER = 'dba_team'; DROP VIEW dbo.vw_sales_summary;应报错 “Permission denied”
配合DDL触发器做二次防护
权限控制可能被绕过(比如临时提权、sa 直接操作),DDL 触发器能补最后一道防线,但仅适用于明确知道哪些账号需要监控的场景。
- 创建数据库级触发器拦截:
CREATE TRIGGER tr_prevent_view_drop ON DATABASE FOR DROP_VIEW AS ... - 触发器内检查
ORIGINAL_LOGIN()和EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname') - 不要用
RAISERROR后直接ROLLBACK就完事——要记录日志到独立表或外部系统,否则 DBA 可能删掉日志表 - 性能影响极小,但需测试是否与备份、同步等维护任务冲突
最易被忽略的是:权限设置后没验证实际效果,或把 DENY 错写成 REVOKE。而 DDL 触发器一旦出错(比如引用了不存在的表),会导致所有 DROP VIEW 失败——连 sysadmin 都无法绕过。这两层机制一个管“该不该删”,一个管“删的时候能不能拦”,缺一不可。










