sql server 2022 不支持在视图上直接启用动态数据屏蔽(ddm),ddm 只能定义在基表列上,视图不继承、不传播、也不可配置屏蔽规则;masked with 是表级列属性,非表达式函数,故 create view 中使用会报语法错误。

SQL Server 2022 不支持在视图上直接启用动态数据屏蔽(Dynamic Data Masking, DDM)——DDM 只能定义在基表的列上,视图本身不继承、不传播、也不可配置屏蔽规则。
为什么 CREATE VIEW 里加 MASKED WITH 函数会报错
尝试在 CREATE VIEW 的 SELECT 列表中写 email MASKED WITH (FUNCTION = 'email()') 会触发语法错误,因为 MASKED WITH 是表级列属性,不是表达式函数。DDM 的元数据只存于 sys.masked_columns 和 sys.columns.is_masked = 1,而视图列没有对应的系统表字段承载该属性。
- DDM 规则必须在基表创建或修改时通过
ALTER TABLE ... ALTER COLUMN ... ADD MASKED WITH (...)添加 - 视图查询该列时,是否显示掩码内容,取决于当前用户权限(是否被
UNMASK授权),而非视图定义 - 即使视图做了
SELECT email AS masked_email,只要底层表列启用了 DDM,且用户无UNMASK权限,结果仍是掩码值
如何让视图“配合”DDM 实现更可控的数据暴露
虽然不能在视图里定义 DDM,但可通过组合策略增强效果:
- 在基表敏感列(如
ssn、phone、salary)上先启用 DDM,例如:ALTER TABLE Employees ALTER COLUMN ssn ADD MASKED WITH (FUNCTION = 'default()') - 用视图封装逻辑,同时显式排除高敏列,只暴露已屏蔽列或脱敏后列(比如用
LEFT(ssn, 3) + '***' + RIGHT(ssn, 4)替代原始列) - 对不同角色创建不同视图:给 HR 视图保留完整
ssn(再配合行级安全 RLS 过滤部门),给普通员工视图只返回ssn_masked计算列 - 注意:计算列方式绕过 DDM,不享受
UNMASK权限控制,需靠GRANT SELECT/DENY SELECT管理列级访问
和行级安全(RLS)一起用时的典型陷阱
RLS 谓词函数在视图上生效的前提是:视图基于单个基表(或带 SCHEMABINDING 的多表视图),且启用 RLS 的表已绑定安全策略。但 DDM 和 RLS 是正交机制——RLS 控制“看到哪些行”,DDM 控制“每行里看到哪些字符”。两者叠加时容易误判:
- 用户有
UNMASK权限,但 RLS 过滤后没数据 → 以为 DDM 失效,其实是没匹配行 - 视图 JOIN 多张表,其中一张表的列启用了 DDM,另一张没启用 → 结果集混杂掩码/明文,语义不一致
- 使用
WITH ENCRYPTION加密视图后,无法查看定义,但 DDM 效果仍存在(因为 DDM 属于基表元数据)
真正要小心的是:把 DDM 当成视图的安全替代品。它不防 DBA,不防 SELECT *,也不防导出工具直连基表——它只是面向应用层用户的轻量级显示遮罩。需要强隔离,必须搭配 RLS、列级权限、甚至 Always Encrypted。










