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:是的,但你需要明確的類型轉換。我在上面添加了更多。 –