如何通过sys.sql_modules系统视图或SHOW CREATE命令查看SQL存储过程的源代码?
- 内容介绍
- 相关推荐
本文共计694个文字,预计阅读时间需要3分钟。
查看SQL Server源代码,使用 `sys.sql_modules`;MySQL使用 `SHOW CREATE PROCEDURE` —— 但两者差异极大,不能混用,也不能仅复制一条命令就完事。
SQL Server 查不到源码?先确认 sys.sql_modules.definition 是否为空
执行 SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('your_proc_name') 返回 NULL,不是语法错,大概率是这几种情况:
- 存储过程名没带 schema,比如写成
'usp_GetUser'而不是'dbo.usp_GetUser',OBJECT_ID()默认查当前数据库 + 当前用户默认 schema,跨 schema 必须显式指定 - 过程被创建时加了
WITH ENCRYPTION,此时definition字段永远为 NULL,sp_helptext同样失效,没有绕过办法 - 权限不足:当前登录用户没被授予对
sys.sql_modules的 SELECT 权限(虽少见,但在严格管控库中存在)
MySQL 的 SHOW CREATE PROCEDURE 报 “PROCEDURE does not exist” 怎么办
这不是过程真不存在,而是 MySQL 没找对地方。它只在当前数据库(即 USE db_name 指定的库)里查,不跨库搜索。
- 先运行
SELECT DATABASE()确认当前库名 - 查所有库里的过程:用
SELECT ROUTINE_SCHEMA, ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'PROCEDURE' - 跨库查必须写全名:
SHOW CREATE PROCEDURE mydb.my_proc(注意是英文点号,不是下划线或反引号包裹)
Oracle 用 user_source 查过程源码,line 排序不能漏
SELECT text FROM user_source WHERE name = 'MY_PROC' AND type = 'PROCEDURE' 看起来能跑通,但返回结果顺序混乱,根本没法读——因为 PL/SQL 源码是按行拆存的,text 字段本身不含换行符,靠 line 字段标序。
- 必须加
ORDER BY line,否则第一行可能是结尾的 END,第二行才是 CREATE -
name值默认大写,如果建过程时用了双引号定义小写名(如"my_proc"),查询时也得写成小写并加双引号 - 查别人家的过程,别用
user_source,换成all_source并带上owner条件,例如WHERE owner = 'HR' AND name = 'EMP_REPORT'
真正容易被忽略的点是:SQL Server 的 sys.sql_modules 和 MySQL 的 SHOW CREATE PROCEDURE 都不保留原始注释和缩进;Oracle 的 user_source 虽保留格式,但每行最多 4000 字符,超长语句会被自动截断分多行——遇到大过程,得检查 line 是否连续、有无跳号。
本文共计694个文字,预计阅读时间需要3分钟。
查看SQL Server源代码,使用 `sys.sql_modules`;MySQL使用 `SHOW CREATE PROCEDURE` —— 但两者差异极大,不能混用,也不能仅复制一条命令就完事。
SQL Server 查不到源码?先确认 sys.sql_modules.definition 是否为空
执行 SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('your_proc_name') 返回 NULL,不是语法错,大概率是这几种情况:
- 存储过程名没带 schema,比如写成
'usp_GetUser'而不是'dbo.usp_GetUser',OBJECT_ID()默认查当前数据库 + 当前用户默认 schema,跨 schema 必须显式指定 - 过程被创建时加了
WITH ENCRYPTION,此时definition字段永远为 NULL,sp_helptext同样失效,没有绕过办法 - 权限不足:当前登录用户没被授予对
sys.sql_modules的 SELECT 权限(虽少见,但在严格管控库中存在)
MySQL 的 SHOW CREATE PROCEDURE 报 “PROCEDURE does not exist” 怎么办
这不是过程真不存在,而是 MySQL 没找对地方。它只在当前数据库(即 USE db_name 指定的库)里查,不跨库搜索。
- 先运行
SELECT DATABASE()确认当前库名 - 查所有库里的过程:用
SELECT ROUTINE_SCHEMA, ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'PROCEDURE' - 跨库查必须写全名:
SHOW CREATE PROCEDURE mydb.my_proc(注意是英文点号,不是下划线或反引号包裹)
Oracle 用 user_source 查过程源码,line 排序不能漏
SELECT text FROM user_source WHERE name = 'MY_PROC' AND type = 'PROCEDURE' 看起来能跑通,但返回结果顺序混乱,根本没法读——因为 PL/SQL 源码是按行拆存的,text 字段本身不含换行符,靠 line 字段标序。
- 必须加
ORDER BY line,否则第一行可能是结尾的 END,第二行才是 CREATE -
name值默认大写,如果建过程时用了双引号定义小写名(如"my_proc"),查询时也得写成小写并加双引号 - 查别人家的过程,别用
user_source,换成all_source并带上owner条件,例如WHERE owner = 'HR' AND name = 'EMP_REPORT'
真正容易被忽略的点是:SQL Server 的 sys.sql_modules 和 MySQL 的 SHOW CREATE PROCEDURE 都不保留原始注释和缩进;Oracle 的 user_source 虽保留格式,但每行最多 4000 字符,超长语句会被自动截断分多行——遇到大过程,得检查 line 是否连续、有无跳号。

