在 SQL 开发中,NULL 和空字符串('')的处理是高频踩坑点。不同数据库对两者的定义、存储方式及约束支持存在显著差异,若不明确这些区别,容易导致数据查询异常、约束冲突等问题。本文基于 ANSI SQL-92 规范,结合 Oracle、PostgreSQL、SQL Server 的特性,详解三者在 NULL 与空字符串处理上的核心差异及实操注意事项。
根据 ANSI SQL-92 规范,NULL 和空字符串是完全不同的概念:
- NULL:表示 “缺失的值” 或 “未知的值”,不对应任何具体数据(既非空串,也非数字 0),所有数据类型的 NULL 定义统一。
- 空字符串(
''):属于明确的字符串类型值,长度为 0,仅适用于字符类数据类型(如 VARCHAR、TEXT)。
三者的核心差异集中在 “是否区分两者”“存储需求”“唯一性约束处理” 三个维度,具体如下:
- Oracle 的 “合并处理” 特性:Oracle 是唯一不区分 NULL 和空字符串的数据库,插入
''会自动转为 NULL,查询时无法通过column = ''筛选空串,需用IS NULL判断。
- PostgreSQL 的版本特性:15 版本前对 NULL 的唯一性约束逻辑与 Oracle 一致(允许多个 NULL),15 版本新增
UNIQUE NULLS NOT DISTINCT语法,可将 NULL 视为重复值限制插入数量。
- SQL Server 的 “严格区分” 特性:NULL 和空字符串完全独立,不仅存储分离,唯一性约束也分别生效(1 个 NULL + 1 个空字符串可共存,但无法插入第二个 NULL 或第二个空字符串)。
CREATE TABLE pg_test (col TEXT);
CREATE TABLE mssql_test (col VARCHAR(20));
CREATE TABLE oracle_unique_test (col VARCHAR2(20) UNIQUE);
CREATE TABLE mssql_unique_test (col VARCHAR(20) UNIQUE);
- 查询时避免用
=判断 NULL:所有数据库中col = NULL的结果均为 NULL(不成立),需用col IS NULL查询 NULL 值,用col = ''查询空字符串(PostgreSQL/SQL Server)。
- Oracle 中统一用
IS NULL判断空值:因 Oracle 将空字符串转为 NULL,无需区分''和 NULL,直接用col IS NULL即可筛选所有 “空值” 场景。
- PostgreSQL 15 + 注意约束语法:若需限制 NULL 的唯一性,使用
UNIQUE NULLS NOT DISTINCT;若需兼容旧版本,避免依赖多 NULL 插入逻辑。
- 数据迁移时的兼容性处理:
- 从 Oracle 迁移到 PostgreSQL/SQL Server:需将原表中
''替换为 NULL(或明确保留空字符串),避免约束冲突。
- 从 PostgreSQL/SQL Server 迁移到 Oracle:无需额外处理,Oracle 会自动兼容两者的存储逻辑。
三大数据库对 NULL 和空字符串的处理核心差异源于 “是否区分两者”:Oracle 为简化逻辑合并处理,PostgreSQL 和 SQL Server 则严格遵循 ANSI 规范分离处理。开发中需重点关注:
- 存储需求:仅 Oracle 的 NULL(含空字符串)占用 1 字节,其余两者的 NULL 不占存储。
- 约束规则:唯一性约束对 NULL 和空字符串的限制逻辑因数据库而异,尤其注意 PostgreSQL 15 + 的版本特性。
- 查询语法:统一使用
IS NULL判断 NULL 值,避免=运算符导致的逻辑错误。
明确这些差异后,可有效避免跨数据库开发、数据迁移中的常见问题,确保 SQL 逻辑的一致性和准确性。