在数据库视图开发中,日期字段通常以原始的 datetime 或 date 类型存储,直接查询出来的结果既包含时间部分,又不符合业务端想要的“年-月-日”或“YYYY年MM月DD日”等展示格式。为了让前端或报表直接拿到格式化字符串,我们可以在创建视图时用数据库内置函数处理日期列。不同数据库提供的函数并不通用,其中 SQL Server 常用 CONVERT,Oracle 常用 TO_CHAR,二者语法和适用场景有明显区别。

一、SQL Server 中 CONVERT 函数格式化日期
CONVERT 是 SQL Server 专有的类型转换函数,它不仅能转换数据类型,还能通过第三个参数“样式码”来定义日期的输出格式。在视图里使用 CONVERT 把 datetime 转成 varchar,就可以固定显示形式。它的基本语法是 CONVERT(目标类型, 日期表达式, 样式码),样式码是数值,例如 120 代表 ODBC 标准“YYYY-MM-DD HH:MI:SS”。
下面创建一个简单视图,把订单表的创建时间格式化成“YYYY-MM-DD”字符串:
CREATE VIEW v_order_simple AS
SELECT
order_id,
CONVERT(varchar(10), create_time, 120) AS create_date
FROM orders;
上面的 120 样式码会截取日期部分。如果需要“YYYY年MM月DD日”,SQL Server 没有直接的样式码,可以用 CONVERT 配合字符串拼接,或者改用 FORMAT 函数(较新版本)。使用 CONVERT 的优点是性能好、兼容老版本;缺点是样式码不够直观,记错数字就会得到奇怪结果。另外当 create_time 为 NULL 时,CONVERT 结果也是 NULL,视图不会报错,但前端需做空值判断。
常用 CONVERT 样式码对照
| 样式码 | 输出示例 | 说明 |
|---|---|---|
| 120 | 2023-08-15 13:24:00 | ODBC 标准,含时间 |
| 111 | 2023/08/15 | 日本格式,斜杠分隔 |
| 112 | 20230815 | 纯数字紧凑格式 |
在视图定义中写 CONVERT 时,注意目标长度要足够,如 varchar(10) 对于 120 样式的日期部分刚好,若只写 varchar(8) 会被截断。视图一旦编译,调用方无需关心底层格式化逻辑,直接 SELECT 即可。
二、Oracle 中 TO_CHAR 函数格式化日期
Oracle 数据库没有 CONVERT 函数,而是使用 TO_CHAR 把日期转成字符,它通过格式掩码(format mask)自由定义输出。语法为 TO_CHAR(日期列, '格式掩码', 'NLS参数')。格式掩码里 YYYY 表示四位年,MM 表示两位月,DD 表示两位日,中间分隔符可任意写。
同样以订单视图为例,Oracle 中可这样写:
CREATE OR REPLACE VIEW v_order_simple AS
SELECT
order_id,
TO_CHAR(create_time, 'YYYY-MM-DD') AS create_date
FROM orders;
若想要“YYYY年MM月DD日”,掩码写成 'YYYY"年"MM"月"DD"日"' 即可,双引号内是原文输出。TO_CHAR 非常灵活,还能格式化小时分钟如 'YYYY-MM-DD HH24:MI'。它的优势是可读性强、掩码直观;不足是在海量数据视图中,相对 CONVERT 字符串处理略重,且必须保证日期列不为非法值,否则会抛 ORA-01830 之类的格式错误。
TO_CHAR 常见掩码元素
- YYYY:四位年份,如 2023
- MM:两位月份,01 到 12
- DD:两位日期,01 到 31
- HH24:24 小时制小时,00 到 23
- MI:分钟,00 到 59
在视图里使用 TO_CHAR,如果源字段可能为空,可以用 NVL(create_time, SYSDATE) 给默认值,或者允许空字符串。需要留意 Oracle 会话的 NLS_DATE_LANGUAGE 参数,若写成 'MON' 显示英文月份简写,在中文环境可能不符合预期。
三、视图中格式化的取舍与兼容建议
把日期格式化放在视图层,能让多个查询复用同一逻辑,减少应用端代码。但如果系统同时跑 SQL Server 和 Oracle,就不能把 CONVERT 和 TO_CHAR 混进同一个视图定义,必须按库分别建视图,或者用 ORM 层做转换。另一种做法是在视图中保留原生日期类型,仅暴露格式化函数供特定报表调用,以兼顾性能与灵活。
从维护角度看,团队应约定统一的格式掩码或样式码文档。例如规定所有“日期仅展示”视图都用 YYYY-MM-DD,SQL Server 用 120 截取前 10 位,Oracle 用 'YYYY-MM-DD'。这样迁移脚本可以对照改写,降低出错概率。无论选哪种函数,都要在视图注释里写明格式化规则,方便后续接手的人理解。
四、综合示例与错误避免
下面是一个容易犯错的写法:在 SQL Server 视图里误用 TO_CHAR,或者在 Oracle 里写 CONVERT,数据库会提示标识符无效。正确方式见各自片段。此外,避免在 WHERE 条件中对格式化后的列加函数,否则索引失效,应在底层日期列上过滤。
-- SQL Server 正确示例:按日期字符串过滤原列 CREATE VIEW v_today_order AS SELECT order_id, CONVERT(varchar(10), create_time, 120) AS d FROM orders WHERE CONVERT(date, create_time) = CONVERT(date, GETDATE());
上述写法对 create_time 用 CONVERT(date,...) 做日期比较,而非对格式化字符串比大小,能利用日期索引。视图本身输出格式化的 d 列,查询时直接展示。掌握 CONVERT 与 TO_CHAR 的差异,就能在各自平台上写出清晰、稳定的日期格式化视图。