SQL CAST 与 CONVERT 类型转换实战

7次阅读

cast是sql标准、跨库兼容,convert是sql server特有且支持格式化;字符串转数字需先清洗再转换;日期转换应优先使用iso 8601格式;隐式转换易致性能下降和结果错误。

SQL CAST 与 CONVERT 类型转换实战

CAST 和 CONVERT 语法差异到底影响什么

两者都能做类型转换,但 CAST 是 SQL 标准写法,CONVERT 是 SQL Server/T-SQL 特有,带第三个格式参数。这意味着:跨数据库迁移时用 CAST 更安全;需要日期/数字格式化(比如 '2024-01-01''01/01/2024')时,只能靠 CONVERT

常见错误现象:CONVERT(VARCHAR, GETdate(), 101)postgresql 里直接报错 —— 因为它根本不认这个函数。

  • CAST 只接受两个参数:CAST(expression AS target_type)
  • CONVERT 第三个参数是风格码(style),仅对 datetimeStringstringdatetime 有效,比如 108 表示只取时间部分
  • mysql 用户注意:它只有 CAST,没有 CONVERT 函数(虽然有同名命令,但不是类型转换用途)

字符串转数字失败的典型场景

最常踩的坑不是语法错,而是数据里藏空格、逗号、单位符号。比如字段值是 ' 1,234 kg ',直接 CAST(col AS int) 必报 Conversion failed when converting the varchar value ' 1,234 kg ' to data type int.

解决思路不是硬扛转换,而是先清洗再转:

  • REPLACE(REPLACE(TRIM(col), ',', ''), 'kg', '') 去掉干扰字符(SQL Server)
  • PostgreSQL 可用正则:CAST(REGEXP_REPLACE(col, '[^0-9.-]', '', 'g') AS NUMERIC)
  • 如果字段中混有纯非数字(如 'N/A'),TRY_CAST(SQL Server 2012+)或 SAFE_CAST(BigQuery)能避免中断查询,返回 NULL 而非报错

日期字符串转 datetime 的精度陷阱

看似简单的 CAST('2024-01-01' AS DATETIME),在 SQL Server 中实际会变成 '2024-01-01 00:00:00.000';但如果你传的是 '2024-01-01 14:30',不同版本可能截断秒级精度,甚至因区域设置误判为 '2024-01-14'(当服务器设为 dmy 格式时)。

关键点在于:SQL Server 对无分隔符或模糊格式极其敏感。

  • 强制用 ISO 8601 格式最稳:'2024-01-01T14:30:00''20240101'(8位数字)
  • CONVERT(DATETIME, col, 126) 显式指定 style=126(ISO8601),比 CAST 更可控
  • 别依赖 GETDATE() 的默认输出格式去反向解析 —— 它受 LANGUAGEDATEFORMAT 设置影响

隐式转换比显式转换更危险

很多人以为只要没写 CAST 就没转换,其实 SQL Server 在比较、连接、计算时大量触发隐式转换。比如 WHERE varchar_col = 123,系统会把整数 123 隐式转成字符串,但若 varchar_col 有索引,这个操作大概率导致索引失效。

另一个经典问题:select * FROM t WHERE date_col > '2024-01-01' —— 字符串字面量被隐式转成 DATETIME,但转换逻辑取决于会话设置,可能出错也可能慢。

  • 始终让两边类型一致:用 date_col > CAST('2024-01-01' AS DATE)
  • SQL_VARIANT_PROPERTY 查字段真实类型,别信表结构文档里的“看着像”
  • 执行计划里看到 CONVERT_IMPLICIT 就是隐式转换在作祟,性能和准确性都可能翻车

类型转换真正难的不是写法,是搞清数据源头有没有脏、目标环境支不支持、执行路径里有没有偷偷转换 —— 这三处漏一个,结果就不可控。

text=ZqhQzanResources