让我们在PostgreSQL中有以下内容:
CREATE TYPE struct AS (x INT, y INT);
CREATE TABLE tbl (a INT, b struct);
CREATE FUNCTION find_tbl_entry(clear BOOL) RETURNS tbl AS $$
DECLARE k tbl;
BEGIN
IF clear THEN
k.b := NULL;
END IF;
RETURN k;
END;
$$ LANGUAGE plpgsql;
也就是说,我们有一个函数返回复合类型tbl
的值,而复合类型b
的值又是复合类型struct
的属性SELECT find_tbl_entry(FALSE)
作为其属性之一。 (原始问题更有趣 - 翻译函数返回一行,其中一些属性相应地翻译;但问题归结为所呈现的代码。)
(,(,))
导致a
,即NULL b
和空结构(NULL和NULL对)作为SELECT find_tbl_entry(TRUE)
的值,有点期待。
现在,即使(,(,))
导致b
,即使NULL
属性明确设置为NULL
,结果也不是find_tbl_entry
,但它仍然是空结构。
我可以为NULL
函数在b
属性中返回k.b := NULL
做些什么?
编辑:事实证明,奇怪的是作业k.b := NULL;
RAISE NOTICE '%', k.b IS DISTINCT FROM NULL;
。扩展功能时:
NULL
它发出“NOTICE:t”。因此,似乎将NULL
分配给复合值实际上会分配具有所有属性NULL
的复合。考虑到(NULL,NULL)
值与UPDATE tbl SET b = NULL
存储在一个表中时b IS NOT DISTINCT FROM NULL
可以区分这一事实,这是非常奇怪的事实(UPDATE tbl SET b = (NULL,NULL)
会导致每行保留false
;另一方面,- parent
-- sub0
--- 0.pgm
--- 1.pgm
--- ...
-- sub1
--- 0.pgm
--- 1.pgm
--- ...
-- ...
对于该测试是parent
。
答案 0 :(得分:1)
在SQL中,当所有组件都是NULL
时,复合值(SQL标准将其称为“度数值> 1”)为NULL
,因此PostgreSQL的行为正确。
ISO / IEC 9075-2:2003,第8章,第7节,说:
8.7< null谓词>
<强>功能强>
指定空值的测试。
<强>格式强>
<null predicate> ::= <row value predicand> <null predicate part 2> <null predicate part 2> ::= IS [ NOT ] NULL
语法规则
无。
访问规则
无。
一般规则
1)让 R 为&lt;行值谓词&gt;的值。
2)案例:
a)如果 R 为空值,则“
R IS NULL
”为 True 。b)否则:
i)“
R IS NULL
”的值是案例:
1)如果 R 中每个字段的值都为空值,则 True 。
2)否则, False 。
ii)“
R IS NOT NULL
”的值是案例:
1)如果 R 中无字段的值为空值,则 True 。
2)否则, False 。
(如果您认为这很疯狂,那么您并不孤单。)
您可以验证PostgreSQL是否正确处理了这样的值:
SELECT (ROW(NULL,ROW(NULL,NULL))::tbl).b IS NULL;
?column?
----------
t
(1 row)
我理解你更喜欢读取(NULL, NULL)
的值,但是你不能用PostgreSQL来获得它。我希望对你来说这是一种安慰,它仍会表现得正确。
答案 1 :(得分:1)
有必要:
直接返回null
而不是返回指定的变量:
create or replace function find_tbl_entry()
returns tbl as $$
declare s struct;
begin
s := null;
return (1, nullif(s, (null,null)::struct));
end;
$$ language plpgsql;
select a, b, b is null from find_tbl_entry();
a | b | ?column?
---+---+----------
1 | | t
或者在功能使用时间进行比较:
select coalesce(nullif((find_tbl_entry()).b, (null,null)::struct), (1,2)::struct);
coalesce
----------
(1,2)