with encryption 并非加密,而是删除视图原始sql文本,导致sys.sql_modules.definition为null、sp_helptext报错;不防dba,不可逆,且无法追加,必须重写完整语句并显式指定。

WITH ENCRYPTION 不是加密,是删源码
SQL Server 的 WITH ENCRYPTION 从不加密视图定义,它只是在 CREATE VIEW 或 ALTER VIEW 执行时,主动丢弃原始 SQL 文本。一旦执行成功,sys.sql_modules.definition 就返回 NULL,sp_helptext 直接报错 Cannot view the text for this object, because it is encrypted.。这不是权限控制,是物理删除——没存,自然查不到。
常见错误现象:
- 误以为加了
WITH ENCRYPTION就能防 DBA:其实 DBA 用 DAC 连接、还原备份、查计划缓存或内存 dump,仍可能还原逻辑 - 在 SSMS 右键“修改”视图,弹出
Cannot modify encrypted objects.:图形界面无法生成含原始逻辑的脚本,你连改都改不了 - 先
CREATE VIEW vw_x AS ...,再想补加加密:不行。SQL Server 不支持“追加加密”,必须重写完整语句
必须显式写出 WITH ENCRYPTION,且不能省略 AS SELECT 部分
加密不是属性开关,是语法级要求。只要漏写 WITH ENCRYPTION,哪怕视图名里带 _encrypted,也完全无效。
正确写法:
CREATE VIEW vw_salary_formula WITH ENCRYPTION AS SELECT employee_id, base_salary * (1 + bonus_rate) AS total_comp FROM employees;
错误写法(全部失效):
-
CREATE VIEW vw_salary_formula AS SELECT ...→ 没写WITH ENCRYPTION,明文可见 -
ALTER VIEW vw_salary_formula AS SELECT ...→ 缺少WITH ENCRYPTION,自动解密 -
CREATE OR ALTER VIEW vw_salary_formula WITH ENCRYPTION AS ...→ 语法错误,SQL Server 不支持这种简写
ALTER VIEW 加密必须重写全部逻辑
已有视图想补上加密?不能只改声明,必须把整个 AS SELECT 块重写一遍,并带上 WITH ENCRYPTION。
例如,原视图是:
CREATE VIEW vw_orders AS SELECT order_id, total FROM orders;
现在要加字段并加密,必须这样写:
ALTER VIEW vw_orders WITH ENCRYPTION AS SELECT order_id, total, status, created_at FROM orders WHERE status != 'cancelled';
否则,只要 ALTER VIEW 语句里没带 WITH ENCRYPTION,SQL Server 就会把它当普通修改处理,原始定义立刻暴露。
风险点:
- 没备份原定义就执行加密,之后发现逻辑有误,既看不到原文,也无法回退
- 开发环境和生产环境脚本不一致,导致上线后视图行为突变却查不出原因
真正该防的不是“看代码”,而是“查数据”
用户只要能 SELECT 视图,就能拿到结果;通过执行计划、IO 统计、依赖关系甚至反复构造查询,都能反推出业务逻辑。所以把安全押在 WITH ENCRYPTION 上,等于防门锁却忘了开窗。
更可控的做法:
- 复杂计算逻辑尽量下推到应用层(Python/Java),SQL 层只做简单投影和过滤
- 必须留在数据库的敏感逻辑,优先用行级安全(
CREATE SECURITY POLICY)控制谁能看到哪些行,而不是藏代码 - 对应用账号严格限权:
REVOKE VIEW DEFINITION、REVOKE SELECT ON sys.sql_modules,只给EXECUTE或SELECT权限
加密不可逆,且不解决根本问题——它只拦得住 sp_helptext,拦不住能跑查询的人。最容易被忽略的是:加了加密后,连你自己都改不了、看不见、没法审计硬编码的密钥或逻辑漏洞。










