在正常情况下,将NULL
值与任何其他值进行比较会产生另一个NULL
值。
SELECT NULL = NULL;
返回NULL
在比较任意行时(大多数情况下)这是正确的,如the documentation, 9.23.5. Row Constructor Comparison:
中所述SELECT ROW(1, NULL, 'baz text') = ROW(1, NULL, 'baz text');
返回NULL
但是,在比较定义良好的复合类型时,NULL
值被视为相等。
CREATE TYPE test_type AS (
foo INTEGER,
bar BIGINT,
baz TEXT
);
SELECT (1, NULL, 'baz text')::test_type = (1, NULL, 'baz text')::test_type;
返回TRUE
这种行为似乎没有记录(我查看并发现没有对行为的引用)。
我想使用此行为来实现某些业务规则,并希望确保安全。
答案 0 :(得分:4)
我在official documentation中找到了这个: [...]在比较两个复合类型值的其他上下文中,两个NULL字段值被认为是相等的,并且认为NULL大于a非NULL。这对于复合类型具有一致的排序和索引行为是必要的。。我认为这可以解决你的问题。
答案 1 :(得分:0)
插图(抱歉,我不能在评论中这样做,需要格式化):
CREATE TYPE test_type AS (
foo INTEGER
, bar BIGINT
, baz TEXT
);
-- plain table with three fields
CREATE TABLE test_table0 (
foo INTEGER
, bar BIGINT
, baz TEXT
);
-- the same, but with a composite type
CREATE TABLE test_table1 (
tt test_type
);
INSERT INTO test_table0 (foo,bar,baz)
VALUES (1, NULL, 'baz text');
INSERT INTO test_table1 (tt)
VALUES( (1, NULL, 'baz text')::test_type) ;
-- union needs a "whole row" -compare
SELECT * FROM test_table0
UNION
SELECT * FROM test_table0
;
-- union needs a "whole row" -compare
-- and type needs a whole "composite" compare
SELECT * FROM test_table1
UNION
SELECT * FROM test_table1
;
结果:
CREATE TYPE
CREATE TABLE
CREATE TABLE
INSERT 0 1
INSERT 0 1
foo | bar | baz
-----+-----+----------
1 | | baz text
(1 row)
tt
-----------------
(1,,"baz text")
(1 row)