这段代码:
CREATE TABLE bug_test ( id int,name text ); INSERT INTO bug_test VALUES (1,NULL); DO $$ DECLARE v_bug_test bug_test; BEGIN RAISE NOTICE '%: %',v_bug_test,(v_bug_test IS NULL); RAISE NOTICE '%: %',(v_bug_test IS NOT NULL); RAISE NOTICE '%: %',(NOT v_bug_test IS NULL); SELECT * INTO v_bug_test FROM bug_test WHERE id = 1; RAISE NOTICE '%: %',(NOT v_bug_test IS NULL); END $$; DROP TABLE bug_test;
给出以下输出:
(,): t (,): f (,): f (1,): f ??? (1,): t
虽然我希望得到这个输出:
(,): t <<< (1,): t
请考虑以下查询:
SELECT id,txt,txt IS NULL AS txt_is_null,NOT txt IS NULL AS not_txt_is_null,txt IS NOT NULL AS txt_is_not_null FROM (VALUES (1::integer,NULL::text) ) AS x(id,txt) ;
你得到这个:
+----+-----+-------------+-----------------+-----------------+ | id | txt | txt_is_null | not_txt_is_null | txt_is_not_null | +----+-----+-------------+-----------------+-----------------+ | 1 | | t | f | f | +----+-----+-------------+-----------------+-----------------+
我想,这就是你和我的期望.您正在检查一个COLUMN对NULL,并且您得到“txt IS NOT NULL”和“NOT txt IS NULL”是等效的.
但是,如果您进行不同的检查:
SELECT id,x IS NULL AS x_is_null,NOT x IS NULL AS not_x_is_null,x IS NOT NULL AS x_is_not_null FROM (VALUES (1,NULL) ) AS x(id,txt) ;
然后你得到
+----+-----+-----------+---------------+---------------+ | id | txt | x_is_null | not_x_is_null | x_is_not_null | +----+-----+-----------+---------------+---------------+ | 1 | | f | t | f | +----+-----+-----------+---------------+---------------+
这可能是令人惊讶的.一件事看起来合理(x IS NULL)和(NOT x IS NULL)是彼此相反的.另一件事(事实上既不是“x IS NULL”也不是“x IS NOT NULL”都是真的),看起来很奇怪.
然而,这就是PostgreSQL documentation所说的应该发生的事情:
If the expression is row-valued,then IS NULL is true when the row expression itself is null or when all the row’s fields are null,while IS NOT NULL is true when the row expression itself is non-null and all the row’s fields are non-null. Because of this behavior,IS NULL and IS NOT NULL do not always return inverse results for row-valued expressions; in particular,a row-valued expression that contains both null and non-null fields will return false for both tests. In some cases,it may be preferable to write row IS DISTINCT FROM NULL or row IS NOT DISTINCT FROM NULL,which will simply check whether the overall row value is null without any additional tests on the row fields.
我必须承认我不认为我曾经使用过针对null的行值比较,但我想如果可能存在,那么可能会有一些用例.无论如何,我认为这不常见.