必须先设 ANSI_NULLS 和 ANSI_PADDING 为 ON,因为 SQL Server 强制要求这些选项在创建带 SCHEMABINDING 的视图及后续 DML 中均为 ON,否则即使指定了 WITH SCHEMABINDING,CREATE VIEW 也会报错“Cannot create index on view 'xxx' because the view is not schema bound”。

必须用 WITH SCHEMABINDING 创建视图,且第一个索引必须是唯一聚集索引,否则无法启用查询优化器对视图的自动匹配。
为什么必须先设 ANSI_NULLS 和 ANSI_PADDING 为 ON?
SQL Server 强制要求这些 SET 选项在创建和后续所有 DML 操作中都为 ON。如果会话当前是 OFF(比如通过某些 ODBC 驱动或旧版 DB-Library 连接),CREATE VIEW 会直接报错:Cannot create index on view 'xxx' because the view is not schema bound. 即使你写了 WITH SCHEMABINDING,也会失败。
- 执行
SET ANSI_NULLS ON; SET ANSI_PADDING ON;后再建视图 - 检查当前会话:运行
SELECT SESSIONPROPERTY('ANSI_NULLS'), SESSIONPROPERTY('ANSI_PADDING');,两个结果都应为 1 - SSMS 默认新建查询窗口是符合的,但通过应用程序连接时需显式设置
WITH SCHEMABINDING 的硬性限制有哪些?
架构绑定不是可选装饰,而是索引视图存在的前提。它强制视图与基表强耦合,防止底层表结构变更破坏视图语义。违反任一条件都会导致 CREATE VIEW 失败。
- 所有引用的表、函数必须用两部分名(如
dbo.Orders),不能用Orders或mydb.dbo.Orders - 视图和所有基表必须属于同一数据库、同一所有者(通常是
dbo) - 不能在视图定义中使用
SELECT *、GETDATE()、NEWID()、子查询中的聚合(除非配GROUP BY)、TOP、ROW_NUMBER()等非确定性表达式 - 若引用了用户定义函数,该函数也必须用
WITH SCHEMABINDING创建
创建唯一聚集索引时最容易忽略的三件事
即使视图成功创建并带 SCHEMABINDING,CREATE UNIQUE CLUSTERED INDEX 仍可能失败——不是语法问题,而是语义约束未满足。
- 视图 SELECT 列表中必须包含一个**明确的、无歧义的唯一键组合**,通常来自基表的主键或唯一约束列;仅靠
COUNT(*)或MAX(id)不行 - 确保该键组合在视图结果集中**实际不重复**:例如
LEFT JOIN可能引入 NULL 或一对多膨胀,导致唯一索引创建失败并报错Cannot create index on view because it contains a left join or outer join - 不要跳过验证步骤:先运行
SELECT COUNT(*) FROM your_view v1 JOIN your_view v2 ON [key_cols] WHERE v1.[key_cols] = v2.[key_cols] AND v1.%%physloc%% != v2.%%physloc%%(或更稳妥地用GROUP BY + HAVING COUNT(*) > 1)确认候选键真唯一
最常被绕过的坑是:以为只要加了索引就“自动生效”,其实查询优化器是否使用索引视图取决于成本估算,而它默认不会重写涉及基表的查询去匹配视图——除非视图定义完全覆盖查询所需列+谓词,且统计信息足够新。上线前务必用 SET STATISTICS XML ON 看执行计划里是否出现 Index Seek/Scan 对应你的视图名,而不是原表名。

















