1

空值与行类型之间是否存在任何差异,其中所有列都为空? Postgres查询似乎能够区分它们(显示空列而不是空白),我想知道是否有任何我应该知道的事情。例如具有全空列的空复合类型和复合类型之间的区别

CREATE TYPE node AS (
    rank integer 
, id integer 
); 

CREATE TABLE hierarchy (
    node node 
); 

INSERT INTO hierarchy (node) VALUES (null); 
INSERT INTO hierarchy (node) VALUES ((null, null)); 

SELECT *, node IS NULL AS check_null FROM hierarchy; 
node | check_null 
------+------------ 
     | t 
(,) | t 
+0

检查您的数据库设计,因为所有列为NULL的行在关系模型中没有意义。您始终需要一个唯一的主键来标识表中的每一行。一行可以有一些NULL字段,但行的主键永远不应该是NULL。 – aicastell

+0

@aicastell将问题中的rowtype读取为复合类型。 –

+1

你的问题有许多语法错误(和语义错误,f.ex.节点既是复合类型又是表名)。你确定你跑了吗? http://rextester.com/ZMOO91035 – pozs

回答

3

是否有一个空值和行类型,所有的字段为空之间有什么区别?

NULL:node仍有别于(null, null)::node

SELECT null::node IS DISTINCT FROM (null, null)::node AS dist; 
dist 
---- 
t 

我同意这是混乱的。和the manual might be sharpened here,太:

对于非NULL输入,IS DISTINCT FROM是一样的<>操作。 但是,如果两个输入均为空,则返回false,并且如果只有一个输入为空,则返回true。

在上面的演示中,结果稍微不正确。即使有一个暗示进一步下跌:

如果expression是行值,然后IS NULL当行 表达式本身为空或当所有行的字段为空也是如此。

因此,我们有不同的情况,即行值是零:

  1. 表达式本身无效。
  2. 所有行的字段为空。

应该指出的是,这两种情况下仍然被认为不同,与IS DISTINCT FROM比较。可能值得文档缺陷报告...

什么我应该知道的?

是的。无论DISTINCT进场时,这两个变种被认为是,那么,不同的:

SELECT DISTINCT * FROM hierarchy; 
node1 
------ 
(,) 

(2 rows) 

注意第2隐形行,因为PSQL显示为空值这个样子。

要停止(,)情况发生?

解决您的评论:

CREATE TABLE hierarchy (
    node node CHECK (node IS DISTINCT FROM (null, null)::node) 
); 

注意两件事情:

  1. 的显式类型转换(null, null)::node是必要的。
  2. 简单的NULL值仍然是允许的,只有具有所有null值的行违反约束。
+0

我这样停止发生'(,)'的情况下,我不得不添加一个'CHECK(node1 IS DISTINCT FROM(null,null))'约束吗? – dbeacham

+0

@dbeacham:是的,但你需要明确的类型转换。我在上面添加了更多。 –