SQL Server靠GRANT EXECUTE+REVOKE VIEW DEFINITION实现可执行不可看源码;MySQL需同时撤销SHOW ROUTINE和INFORMATION_SCHEMA.SELECT;Oracle的WRAP仅为混淆,非权限控制。

SQL Server 中能实现“可执行但不可看源码”,核心靠 EXECUTE + 撤销 VIEW DEFINITION,不是靠加密或隐藏。
SQL Server:GRANT EXECUTE 但 REVOKE VIEW DEFINITION
SQL Server 默认不暴露源码,除非显式授予 VIEW DEFINITION 权限。只要没给这个权限,用户调用 sp_helptext、查 sys.sql_modules 或用 SSMS 右键“修改”都会失败或返回空。
-
GRANT EXECUTE ON PROCEDURE [Rptg].[usp_GetSalesReport] TO [app_role];—— 允许执行 -
REVOKE VIEW DEFINITION ON PROCEDURE [Rptg].[usp_GetSalesReport] FROM [app_role];—— 剥夺查看定义能力 - 若已误授过
VIEW DEFINITION,仅REVOKE不够,还要检查是否继承自数据库级权限:REVOKE VIEW DEFINITION ON DATABASE::[MyDB] FROM [app_role]; - 注意:
VIEW DEFINITION是对象级权限,必须对每个过程单独REVOKE,不能靠“禁止整个 schema”一揽子控制
MySQL:EXECUTE 授权必须精确 + 关闭两个隐性源码通道
MySQL 没有 VIEW DEFINITION 权限,源码可见性由两个独立权限控制:SHOW ROUTINE 和 SELECT on INFORMATION_SCHEMA.ROUTINES。只给 EXECUTE 不等于安全。
-
GRANT EXECUTE ON PROCEDURE `mydb`.`calc_score` TO 'app_user'@'%';—— 必须带库名和过程名,mydb.*或calc_score都非法 -
REVOKE SHOW ROUTINE ON *.* FROM 'app_user'@'%';—— 否则SHOW CREATE PROCEDURE calc_score成功 -
REVOKE SELECT ON INFORMATION_SCHEMA.ROUTINES FROM 'app_user'@'%';—— 否则SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES可直接读明文 - MySQL 5.7 不支持
ON PROCEDURE语法,必须升级到 8.0.16+ 才能用精确的GRANT EXECUTE ON PROCEDURE
Oracle:WRAP 加密 ≠ 权限控制,它只影响查询视图
Oracle 的 WRAP 是单向混淆,不是权限机制。它让 USER_SOURCE 返回乱码,但不阻止执行、不改变权限模型、也不防 DBA 查底层字节。
- 加密后
SELECT text FROM USER_SOURCE WHERE name = 'MY_PROC';返回不可读二进制,但CALL my_proc;照常运行 - 必须用 Oracle 自带
wrap工具,且输入文件末尾必须有/,否则编译报ORA-00900 -
DBMS_DDL.CREATE_WRAPPED会直接创建加密对象;DBMS_DDL.WRAP只返回加密字符串,不建对象 - 加密文件不向下兼容(如 19c 生成的
.plb在 12.2 上会报ORA-24344),且无法在线修改,必须回退原始.sql
真正容易被忽略的是权限作用域匹配:SQL Server 要确认 REVOKE VIEW DEFINITION 是否被数据库级权限覆盖;MySQL 要核对 'app_user'@'%' 和实际连接主机名是否一致;Oracle 的 WRAP 结果在不同版本间可能根本无法加载——这些细节不对,前面所有操作都白做。

















