WITH ENCRYPTION仅擦除视图定义明文且不可恢复,非真正加密;须显式声明、ALTER时重写全部逻辑并再次指定,配合REVOKE VIEW DEFINITION和schema权限隔离才有效防逻辑泄露。

WITH ENCRYPTION 能防住常规查看,但不是“加密”意义上的保护——它直接丢弃明文,后续无法恢复,也不提供权限控制。真要防逻辑泄露,得配合 REVOKE VIEW DEFINITION 和 schema 权限隔离。
CREATE VIEW 时必须显式写 WITH ENCRYPTION
它不是开关,不写就不生效,哪怕之前加过也无效。SQL Server 不会记住“这个视图曾经加密过”。新建视图时漏掉这一项,等于没做任何保护。
-
CREATE VIEW vw_customers_encrypted WITH ENCRYPTION AS SELECT id, name FROM customers;✅ 正确 -
CREATE VIEW vw_customers_encrypted AS SELECT id, name FROM customers;❌ 未加密,即使名字里带“encrypted”也没用 - 没有
CREATE OR ALTER VIEW ... WITH ENCRYPTION的简写语法;想加密,必须完整重写整个AS SELECT...部分
ALTER VIEW 后必须重写全部定义 + 再次声明 WITH ENCRYPTION
加密不是属性,不能“追加”或“开启”。已有视图想加密,ALTER VIEW 必须带完整逻辑和 WITH ENCRYPTION,否则会自动解除加密状态。
- 错误做法:
ALTER VIEW vw_customers_encrypted AS SELECT id, name, email FROM customers;→ 解密了 - 正确做法:
ALTER VIEW vw_customers_encrypted WITH ENCRYPTION AS SELECT id, name, email FROM customers; - SSMS 右键“修改”会失败,报错
Cannot modify encrypted objects.,因为图形界面生成的脚本不含原始逻辑
加密后 sp_helptext、sys.sql_modules.definition 全部失效
这不是权限问题,是 SQL Server 的设计行为:源码在创建/修改时就被擦除,不存明文,所以查不到不是“被拦”,而是“根本没存”。
-
EXEC sp_helptext 'vw_customers_encrypted';→ 返回空或报错Cannot view the text for this object, because it is encrypted. -
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('vw_customers_encrypted');→ 返回NULL - DBA、DAC 连接、备份还原、
DBCC命令都绕不过去——没明文,就真没有
真正要防的是人,不是工具:加密 ≠ 权限控制
WITH ENCRYPTION 只管“能不能看定义”,不管“能不能查数据”。用户只要能 SELECT 视图,就能拿到结果,甚至通过执行计划、IO 统计、依赖关系反推逻辑。
- 必须同步回收权限:
REVOKE VIEW DEFINITION ON OBJECT::vw_customers_encrypted TO [user]; - 把视图放进独立 schema(如
secure),只授SELECT,不授REFERENCES或CONTROL - 如果逻辑极其敏感,别放视图里——下推到应用层,或改用行级安全策略(
CREATE SECURITY POLICY)控制数据可见性
ALTER VIEW 却忘了加 WITH ENCRYPTION,结果整条链路暴露。备份未加密版本、记录变更日志、限制 DDL 权限,比依赖 WITH ENCRYPTION 更实在。

















