优先选CAST:跨数据库兼容且符合ANSI标准;CONVERT仅限SQL Server且含style参数,换库即失效;脏数据需先清洗再转换,避免报错。

跨数据库环境必须用 CAST,SQL Server 单独部署且需格式控制时才考虑 CONVERT;硬套函数不清理数据,90% 的报错都来自脏值而非语法。
CAST 和 CONVERT 到底该选哪个?
看目标环境再决定:如果脚本要跑在 PostgreSQL、MySQL 8.0+、SQL Server 或 SQLite 中,CAST 是唯一安全选择;CONVERT 在 PostgreSQL 里直接报错 function convert(unknown, unknown) does not exist,MySQL 虽然认但参数顺序和行为不一致,根本不可靠。
CAST 语法统一:CAST(expr AS target_type),所有主流数据库都按 ANSI 标准解析;CONVERT 是 SQL Server 扩展,第三个 style 参数只在它里面生效(比如 CONVERT(DATE, '15/06/2026', 103)),换库就失效。
- 跨平台迁移或 ORM 自动生成 SQL → 必用
CAST - 纯 SQL Server 报表,且要输出
'2026-06-22 14:30'或'22/06/2026'→ 可用CONVERT配style - 把
CONVERT(VARCHAR, GETDATE(), 120)复制进 pgAdmin → 直接报错,别试
字符串转数字总报 Conversion failed?先清再转
报错 Conversion failed when converting the varchar value 'N/A' to data type int 不是函数写错了,是数据里混着空格、单位、字母、空串——CAST 和 CONVERT 都不做容错,遇到第一个非法字符就中断。
SQL Server 推荐组合:TRY_CAST(TRIM(col) AS INT),TRIM 去首尾空格,TRY_CAST 容错返回 NULL;MySQL 没 TRY_CAST,得靠前置过滤:CAST(IF(col REGEXP '^[0-9]+$', col, NULL) AS SIGNED);PostgreSQL 得用正则:CAST(NULLIF(REGEXP_REPLACE(col, '[^0-9.-]', '', 'g'), '') AS NUMERIC)。
-
CAST('' AS INT)在 SQL Server 中直接报错,TRY_CAST('' AS INT)返回NULL -
CAST('123.45.67' AS DECIMAL(5,2))在 MySQL 中静默截断为123.45,不是报错 -
CAST(' 42 kg' AS SIGNED)在 MySQL 中返回42,但CAST('kg42' AS SIGNED)返回0—— 行为不一致,不能依赖
日期字符串转换最危险,ISO 格式是唯一共识
所有数据库都认 '2026-06-22',但对 '22/06/2026' 或 '06-22-2026' 解析规则完全不同:SQL Server 默认 MDY,PostgreSQL 看 datestyle 设置,MySQL 可能返回 NULL 或错成 1900-01-01。
安全做法只有两条:CAST('2026-06-22' AS DATE) 或带 style 的 CONVERT(仅限 SQL Server):CONVERT(DATE, '22/06/2026', 103)。别指望 CAST('22/06/2026' AS DATE) 在不同环境结果一致。
-
CONVERT(DATE, '01-Apr-2026', 106)看似可行,但依赖服务器语言设置,换环境可能失败 -
CAST('2026/06/22' AS DATE)在部分 MySQL 版本中会静默失败,返回NULL - 时间字段同理:
CAST('2026-06-22T14:30:00' AS DATETIME)比CAST('22-JUN-2026 14:30' AS DATETIME)可靠得多
WHERE 或 JOIN 里用 CAST 就等于放弃索引
WHERE CAST(order_no AS INT) > 1000 或 JOIN users ON CAST(log_user_id AS INT) = users.id 这类写法会让优化器无法使用 order_no 或 log_user_id 上的索引,执行计划里 key 显示为 NULL,实际是全表扫描。
真正有效的解法不是换函数,而是改结构:ALTER TABLE logs ADD user_id_int INT STORED AS (CAST(log_user_id AS SIGNED)),然后对新列建索引;或者在应用层/ETL 阶段提前清洗并存为正确类型。
-
WHERE order_no > '1000'(假设order_no是字符串且字典序可用)比CAST更快 -
ORDER BY CAST(created_at AS DATE)不如ORDER BY DATE(created_at),后者更易被优化器识别 - 嵌套转换如
CAST(CAST(x AS VARCHAR) AS INT)不仅难读,还放大性能风险,先查执行计划再动手
最常被忽略的是 NULL 和边界值处理逻辑不统一:CAST('' AS DATE) 得 NULL,CAST('' AS SIGNED) 在 MySQL 中得 0,这种差异在聚合或比较时可能引发隐性 bug,不能靠经验判断,得实测。

















