优先用 CAST,它更标准、可移植性高;SQL Server 需格式化时用 CONVERT;MySQL 中 CONVERT 是 CAST 别名;跨库迁移或混用 DBMS 时应统一用 CAST。

CAST 和 CONVERT 用哪个?先看数据库类型
PostgreSQL、SQLite、标准 SQL 用 CAST;SQL Server 同时支持 CAST 和 CONVERT,但 CONVERT 多一个格式化参数,比如日期转字符串时控制样式;MySQL 实际上只认 CAST(CONVERT 是它的别名,行为一致)。别硬套 SQL Server 写法到 PostgreSQL 里——会报 ERROR: function convert(unknown, unknown) does not exist。
常见错误现象:
在 pgAdmin 或 DBeaver 里粘贴 SQL Server 的 CONVERT(VARCHAR, GETDATE(), 120),直接报错。
使用场景:跨数据库迁移脚本、团队混用不同 DBMS 时写通用 SQL。
实操建议:
• 优先用 CAST,它更标准、可移植性高
• SQL Server 中需要格式化日期/数字时再用 CONVERT,例如 CONVERT(CHAR(10), order_date, 120)
• MySQL 不要依赖 CONVERT(... USING ...) 做字符集转换——那是另一回事,和类型转换无关
字符串转数字失败?空格和 NULL 是隐形杀手
CAST(' 123 ' AS INTEGER) 在 PostgreSQL 和 SQL Server 都能成功,但 CAST('123abc' AS INTEGER) 或 CAST(NULL AS INTEGER) 就不行。问题不总出在语法,而在于数据质量。
常见错误现象:ERROR: invalid input syntax for integer: "123.45"(PostgreSQL)Conversion failed when converting the varchar value 'N/A' to data type int.(SQL Server)
实操建议:
• 先用 TRIM() 清空格,再用正则或条件判断过滤非法值(如 PostgreSQL 的 ~ '^[0-9]+$')
• SQL Server 可用 TRY_CAST('abc' AS INT) 返回 NULL 而非报错,避免中断查询
• 别在 WHERE 条件里直接 CAST(col AS INT) > 100——如果 col 有非数字内容,整条语句就挂,应先加过滤
日期字符串转 DATE 类型:格式不匹配比想象中更常见
不是所有 '2023-05-20' 都能被顺利转成 DATE。PostgreSQL 默认接受 ISO 格式,但 SQL Server 对 '20/05/2023' 这种可能按 MDY 还是 DMY 解析,取决于 SET DATEFORMAT 或登录语言设置。
常见错误现象:ERROR: date/time field value out of range: "31/02/2023"
或者明明是 2023 年 5 月 20 日,转出来变成 2023-20-05(日月颠倒)
实操建议:
• 输入字符串尽量统一为 YYYY-MM-DD 格式,这是唯一跨库安全的日期字面量
• SQL Server 中用 CONVERT(DATE, '20/05/2023', 103) 显式指定格式(103 = DD/MM/YYYY)
• PostgreSQL 可用 TO_DATE(col, 'DD/MM/YYYY') 替代 CAST,更可控
• 避免依赖隐式转换,比如 WHERE order_date > '2023-05-20' 看似没问题,但如果 order_date 是字符串类型,比较就变成字典序了
性能陷阱:别在 WHERE 或 JOIN 条件里反复 CAST
对字段做 CAST(created_at AS DATE) 再比较,很可能让索引失效。尤其当 created_at 是 TIMESTAMP 类型、你又想查“某天的所有记录”时,CAST(created_at AS DATE) = '2023-05-20' 会让优化器放弃使用索引。
使用场景:
大表按日期范围查询、ETL 中清洗时间字段、报表取当天数据
实操建议:
• 改用范围查询:created_at >= '2023-05-20' AND created_at <br>• 如果必须用日期函数,PostgreSQL 可建函数索引:<code>CREATE INDEX idx_created_date ON orders ((created_at::DATE))
• SQL Server 中 CONVERT(DATE, created_at) 同样无法走索引,除非用计算列+索引
类型转换看着简单,真正卡住人的往往是数据里的空格、区域设置、索引失效这些细节。写完 CAST/CONVERT,记得看执行计划,而不是只盯着结果对不对。

















