真正起作用的注释位置只有三个:参数声明后的块注释说明业务含义、关键逻辑段前解释目的、IF/CASE分支内部阐明意图;必须用/ /而非--写长注释;参数注释需与声明对齐;缩进统一为4空格;命名须语义明确、避免保留字;动态SQL注释需注入字符串并验证。

SQL Server 存储过程中注释写在哪才真有用
注释不是写给编译器看的,是写给三个月后的你自己或刚接手的同事看的。在 CREATE PROCEDURE 里把注释堆在开头、堆在末尾,基本等于没写。
真正起作用的位置只有三个:/* */ 包裹的块注释放在参数声明后(说明每个 @param 的业务含义),关键逻辑段前(比如“此处计算用户7日留存,含去重与时间窗口校验”),以及 IF/CASE 分支内部(避免只看到条件却猜不出意图)。
- 别在
AS后面空两行再写注释——人眼扫描时会跳过,等同于隐藏 - 避免用
--写长段落注释:SQL Server 对单行注释长度无限制,但编辑器折叠、SSMS 高亮常出问题,/* */更稳 - 参数注释必须和声明对齐,例如:
CREATE PROC dbo.usp_GetOrderSummary<br> @StartDate DATE, /* 起始日期,含当日,格式 YYYY-MM-DD */<br> @Status TINYINT /* 0=全部, 1=已发货, 2=已取消 */
别让缩进暴露你的 SQL 风格混乱
SQL Server 不依赖缩进执行,但人脑靠缩进识别嵌套层级。一个 SELECT 套三层 JOIN 再加子查询,如果全顶格写,等于强迫别人手动数括号。
核心原则:每级结构换行 + 缩进 4 空格(不是 Tab),且缩进位置严格对应逻辑块边界。特别注意 WHERE、GROUP BY、ORDER BY 必须单独成行,条件之间用换行而非逗号分隔。
-
FROM和后续所有JOIN对齐,ON条件缩进一层,多条件换行 -
SELECT列表每列一行,别挤在一行里用逗号连写(尤其含函数或别名时) - CTE 的
WITH块必须整体缩进,AS (后换行,)单独成行并与WITH对齐
命名不规范比逻辑错更难 debug
看到 @a、@tmp1、sp_xxx 这类名字,第一反应不是查逻辑,而是翻文档或问人——这已经拖慢了 3 分钟。
存储过程名必须带业务动词前缀,如 usp_CalculateMonthlyRevenue(usp = user stored procedure),临时表用 #OrderTemp 而非 #t1,变量名直说用途:@MaxRetryCount 比 @cnt 强十倍。
- 避免 SQL Server 保留字作名:哪怕加了方括号,
[order]也比OrderData多一次认知负担 - 大小写保持一致:SQL Server 默认不区分,但团队统一用 PascalCase(如
@CustomerID)比全小写更易扫读 - 别用拼音缩写:如
@khmc(客户名称),换成@CustomerName,多打 5 个字符,省下 5 分钟理解时间
动态 SQL 注释失效时怎么保命
用 EXEC(@sql) 或 sp_executesql 时,所有写在外部的注释对生成的语句完全无效。这时候注释必须“注入”到字符串里,否则等于裸奔。
安全做法是在拼接前就把注释塞进 @sql 变量,且用 /* */(-- 在字符串里容易被误截断)。同时,务必在执行前用 PRINT @sql 或 SELECT @sql AS GeneratedSQL 输出验证——很多逻辑错误其实就藏在拼出来的 SQL 里。
- 别在
EXEC('SELECT ...')里硬写注释:字符串内单引号需转义,--极易因拼接顺序被吞掉 - 用
CHAR(13) + CHAR(10)换行,保证生成 SQL 可读;纯空格缩进会被忽略,必须用真实换行符 - 如果动态部分来自参数,注释里要写死示例值,比如:
/* @Status=1 → WHERE Status = 1 */
最常被忽略的点:注释里的业务规则一旦变更,代码未必同步更新。定期用 SELECT OBJECT_NAME(object_id), definition FROM sys.sql_modules WHERE definition LIKE '%// TODO%' 类似方式扫残留标记,比靠人记靠谱。

















