convert是sql server存储过程中最稳定的选择,自2000版起全版本支持、执行计划稳定;format仅2012+支持且性能开销大,仅用于中文格式等特殊需求;where中应避免对日期字段格式化以保障索引有效性。

CONVERT 是存储过程里最稳的选择
优先用 CONVERT,它从 SQL Server 2000 就存在,所有版本都支持,执行计划稳定,不会因格式代码变化引发隐式转换失败。关键不是“能不能用”,而是“传的格式代码是否匹配输入值的实际结构”:
-
CONVERT(VARCHAR(10), @date, 23)→ 输出2026-07-02,适合 WHERE 条件、JOIN 或生成文件名 -
CONVERT(VARCHAR(19), @date, 120)→ 输出2026-07-02 07:16:00,带空格、无毫秒,适合日志记录 - 如果
@date是NVARCHAR字符串(如'20260702'),必须先转日期再格式化:CONVERT(VARCHAR(10), CONVERT(DATE, @date, 112), 23) - 错误高发:用代码
103(dd/mm/yyyy)去格式化字符串'2026-07-02',SQL Server 会尝试按英国规则解析,可能报错或返回意外结果
FORMAT 只在明确需要时启用
FORMAT 依赖 .NET 运行时,每次调用触发 CLR 开销,在循环多、数据量大的存储过程中明显拖慢执行速度。但它能干 CONVERT 干不了的事:
- 输出中文格式:
FORMAT(@date, 'yyyy年MM月dd日')→2026年07月02日 - 带星期几:
FORMAT(@date, 'yyyy-MM-dd dddd')→2026-07-02 星期四 - 适配区域:
FORMAT(@date, 'D', 'zh-CN')→ 全中文长格式 - 注意:
FORMAT仅 SQL Server 2012+ 支持;目标库是 2008R2 或更早时,直接报错Invalid object name 'FORMAT'
WHERE 子句里别对日期字段做格式化
在查询条件中写 CONVERT(VARCHAR, date_col, 23) = '2026-07-02' 看似直观,但会让索引失效。正确做法是用范围查询:
- ✅
date_col >= '2026-07-02' AND date_col - ❌
CONVERT(VARCHAR(10), date_col, 23) = '2026-07-02' - 如果字段本身是
VARCHAR类型(如存成'20260702'),先用CONVERT(DATE, date_col, 112)转类型,再参与比较,避免隐式转换风险
拼接动态 SQL 时小心单引号和转义
用 FORMAT 拼接字符串生成动态 SQL,比如加 ISO 时间戳后缀,容易漏转义:
- ❌
FORMAT(GETDATE(), 'yyyy-MM-dd'T'HH:mm:ss')—— 缺少转义,语法错误 - ✅
FORMAT(GETDATE(), 'yyyy-MM-dd''T''HH:mm:ss')—— 中间T前后各需两个单引号 - 更安全的做法:用
QUOTENAME包裹整个值,或改用CONVERT+ 标准样式(如120)避免手写分隔符











