五月 15, 2023
Oracle 对 ''
有一些特殊的处理,默认会转成 NULL。使得 ''
可以适合任意的数据类型。
然而对于 PostgreSQL 来说,没有做这层转换,所以 ''
并不能输入给任意类型。
Oracle 示例
SQL> CREATE TABLE a(id int, c1 varchar2(10) default '', c2 date default '');
Table created.
SQL> INSERT INTO a (id) VALUES(1);
1 row created.
SQL> SELECT * FROM a WHERE c1 IS NULL;
ID C1 C2
---------- ---------- ---------
1
SQL> SELECT * FROM a WHERE c2 IS NULL;
ID C1 C2
---------- ---------- ---------
1
然而实际上这样查询却查不到结果,是不是很让人惊讶:
SQL> SELECT * FROM a WHERE c1 = '';
no rows selected
default ''
就是说默认值为 NULL。
Oracle 内部把 ''
转换成了 NULL。(不仅时间类型,字符串 Oracle 也会这么干,所以语义上很混乱,实际上个人认为是 Oracle 的一个不严谨的地方)
PostgreSQL 示例
PostgreSQL 不做这个转换,所以非字符串类型,使用 ''
都会报错。
postgres=# SELECT ''::timestamp;
ERROR: invalid input syntax for type timestamp: ""
LINE 1: SELECT ''::timestamp;
^
为了兼容 Oracle,建议用户改 ''
为直接输入 NULL,语义上也通畅。
postgres=# CREATE TABLE a(id int, c1 varchar(10) default NULL, c2 timestamp(0) default NULL);
CREATE TABLE
postgres=# INSERT INTO a (id) VALUES (1);
INSERT 0 1
postgres=# SELECT * FROM a WHERE c1 IS NULL;
id | c1 | c2
----+----+----
1 | |
(1 row)
postgres=# SELECT * FROM a WHERE c2 IS NULL;
id | c1 | c2
----+----+----
1 | |
(1 row)
postgres=# SELECT * FROM a WHERE c1 = '';
id | c1 | c2
----+----+----
(0 rows)