sys.objects是查询sql server存储过程的首选系统视图,因它底层稳定、权限要求低、全版本兼容;需用where type='p' and is_ms_shipped=0过滤,并配合schema_name(schema_id)获取架构名,避免混入系统对象或非存储过程类型。

直接查 sys.objects 就能拿到所有存储过程,但必须过滤掉系统对象和非存储过程类型,否则结果混杂、不可用。
为什么 sys.objects 是首选起点
它比 sys.procedures 更底层、更稳定,不依赖额外权限(如对 sys.sql_modules 的 SELECT 权限),且在 SQL Server 2005+ 全版本中行为一致。但它本身不存源码、不暴露参数,只提供元数据 —— 所以别指望靠它看定义或入参。
常见错误是直接 SELECT * FROM sys.objects 然后手动翻找,结果被一堆视图、函数、约束淹没。
- 必须加
WHERE type = 'P':'P'是存储过程的固定类型码,不是'SP'或'PROC' - 必须加
AND is_ms_shipped = 0:否则会混入sp_help、sp_who2这类系统自带过程,干扰排查 -
schema_id要配合SCHEMA_NAME()一起用,否则只看到数字 ID,没法对应到dbo或sales这样的实际架构名
sys.objects 查询语句怎么写才靠谱
最简可用的查询长这样:
SELECT SCHEMA_NAME(schema_id) AS schema_name, name AS procedure_name, create_date, modify_date FROM sys.objects WHERE type = 'P' AND is_ms_shipped = 0 ORDER BY schema_name, name;
注意几个关键点:
- 不要用
object_id当显示字段 —— 它只是内部编号,对运维没意义 - 别漏
ORDER BY:上百个存储过程堆在一起,不排序根本没法人工核对 - 如果要导出给开发看,建议加上
OBJECT_DEFINITION(object_id)—— 但这个函数性能开销大,仅限单个过程查定义时用,千万别放 WHERE 后面全量查
查出来后发现名字乱码或带特殊字符怎么办
这是 sys.objects.name 字段类型为 sysname(等价于 nvarchar(128))导致的,本质是 Unicode 支持没问题,但某些旧客户端(比如老版本 SSMS 或某些 ODBC 驱动)默认用 ANSI 编码渲染,显示成问号或方块。
- 优先确认客户端是否启用 UTF-8:SSMS 中右键查询窗口 → “高级” → 检查“Unicode 输出”是否勾选
- 避免用
CAST(name AS varchar)强转 —— 会截断中文、丢失符号,反而让问题更隐蔽 - 真要兼容旧环境,改用
QUOTENAME(name)包裹,至少保证复制粘贴时语法安全
查不到新加的存储过程?先盯住这三个地方
不是 sys.objects 失效,而是你执行查询的上下文错了:
- 确认当前
USE [YourDB]切换到了目标数据库 ——sys.objects是数据库级视图,跨库查必须显式切换 - 检查存储过程是否建在
tempdb或其他用户数据库里,而不是你正在查的那个库 - 如果过程是用
WITH ENCRYPTION创建的,不影响sys.objects显示,但后续用sp_helptext查定义时会报错,这是正常现象,别误判为没建成功
真正容易被忽略的是:SQL Server 对象名区分大小写与否,取决于数据库的排序规则(collation)。如果你的库是 SQL_Latin1_General_CP1_CS_AS,而过程名叫 usp_GetUser,却搜 usp_getuser,sys.objects 里就真找不到 —— 它不帮你做大小写归一化。










