Oracle将空字符串''自动转为NULL,导致= ''判断失效;MySQL则严格区分''与NULL,支持直接比较。跨库需用LENGTH(TRIM(col)) > 0等兼容写法。

MySQL 和 Oracle 对 '' 的处理完全不兼容:在 MySQL 中它是可比较的合法字符串;在 Oracle 中它被自动转成 NULL,所有 = '' 判断都失效。
Oracle 中 = '' 永远查不到数据
因为 Oracle 在底层将空字符串字面量 '' 视为 NULL,而任何与 NULL 的等值比较(包括 = '')都会返回 UNKNOWN,不是 TRUE,所以 WHERE 条件不成立。
-
INSERT INTO t (name) VALUES ('');实际存入的是NULL,不是空字符串 -
SELECT * FROM t WHERE name = '';返回 0 行,哪怕表里真有那条记录 -
SELECT * FROM t WHERE name IS NULL;会同时命中原生NULL和插入的'' - 这种行为是 Oracle SQL 标准三值逻辑(
TRUE/FALSE/UNKNOWN)的直接体现
MySQL 中 = '' 是安全且明确的
MySQL 把 '' 当作一个长度为 0 的具体字符串值,和 NULL 严格区分,支持直接比较、索引、函数处理。
-
INSERT INTO t (name) VALUES ('');存的就是'',SELECT出来也是'' -
SELECT * FROM t WHERE name = '';能精准匹配空字符串行 -
SELECT * FROM t WHERE name IS NULL;只匹配真正的NULL,不会误伤'' -
IFNULL(col, 'default')不会影响'',但COALESCE(col, 'default')也不会——因为''不是NULL
跨库迁移时最易踩的坑:NOT NULL 字段 + 空字符串
MySQL 允许 NOT NULL 字段存 '';Oracle 不允许——它会把 '' 转成 NULL,直接违反约束报错 ORA-01400: cannot insert NULL into ...。
- 迁移前必须检查所有
NOT NULL的VARCHAR字段是否含''值 - 修复方式不是简单替换为
' '(带空格),而是统一用有意义默认值(如'N/A')或改字段为允许NULL - 应用层写入时,应避免传入
''给 Oracle,建议统一在 ORM 或 DAO 层拦截并转为空值或默认值 - 如果业务逻辑确实需要区分“未填写”(
NULL)和“填了但为空”(''),Oracle 无法原生支持,只能靠额外字段或约定值模拟
安全写法:用 TRIM() + IS NULL 或 LENGTH() 统一判断非空
想写一条在两个库都生效的“非空”条件,不能依赖 = '' 或 IS NULL 单独判断,得组合逻辑。
- MySQL 下:
WHERE col IS NOT NULL AND TRIM(col) != ''或WHERE LENGTH(TRIM(col)) > 0 - Oracle 下:
WHERE col IS NOT NULL AND TRIM(col) IS NOT NULL(因为TRIM('')还是NULL) - 通用写法(推荐):
WHERE col IS NOT NULL AND LENGTH(TRIM(col)) > 0——LENGTH(NULL)返回NULL,LENGTH(TRIM(''))在 MySQL 返回 0,在 Oracle 返回NULL,所以该表达式在两库中对空字符串和NULL都返回FALSE - 注意:
TRIM()会影响索引使用,高频查询字段慎用;若字段常含前后空格,应在写入时清洗,而非查询时补救
真正麻烦的不是语法差异,而是团队习惯——有人在 MySQL 里写了 col = '' 觉得天经地义,换到 Oracle 就静默失效。上线前务必在目标库执行实际数据验证,别只看语法没报错。


















