2012-08-08 67 views
3

我有一些SQL代碼的問題。PostgreSQL中的繼承和關係

序列和表格的創建,一些數據中插入:

CREATE SEQUENCE tmp_id_places START 1; 
CREATE SEQUENCE tmp_id_books START 1; 

CREATE TABLE tmp_places (
    id int PRIMARY KEY DEFAULT nextval('tmp_id_places'), 
    name text 
); 

CREATE TABLE tmp_cities (population int) INHERITS (tmp_places); 
CREATE TABLE tmp_rivers (lenght int) INHERITS (tmp_places); 

INSERT INTO tmp_cities (name, population) VALUES 
    ('Moscow', 15), 
    ('St. Petersburg', 9); 

INSERT INTO tmp_rivers (name, lenght) VALUES 
    ('Volga', 115), 
    ('Angara', 319); 

CREATE TABLE tmp_books (
    id int PRIMARY KEY DEFAULT nextval('tmp_id_books'), 
    id_place int REFERENCES tmp_places(id), 
    title text 
); 

Вut驗證碼輸入有誤:

INSERT INTO tmp_books (title, id_place) VALUES 
    ('Some book about Moscow', 1), 
    ('Another book about Angara', 4); 

tmp_books包含有關地點的信息。但我無法在其中插入數據,因爲主表tmp_places(子表中的所有數據)中沒有任何數據。

因此,這可以解決嗎?

回答

2

丹尼斯,

繼承不INSERT傳播和複製Postgres的語句。

1

在PostgreSQL中,你不應該爲父表創建一個外鍵,因爲正如你剛纔發現的那樣,這個表的行爲幾乎是一個視圖而不是一個表(因爲實際數據在它們各自的子節點中)。現在只能通過觸發器來解決。

您可以看到這種「觸發器類型」的example

4

仔細看看PostrgeSQL文檔中的this section。如果你將數據插入到子表中,那麼在子表中將發現數據只有。另一方面,插入到主表中也會在所有子表中顯示新行。所以你必須總是第一手在主表上工作。

前段時間我一直在繼承工作,也面臨同樣的問題。 我結束了以下內容:

  1. INSERT新進入tmp_places;
  2. UPDATE額外的字段,例如,在tmp_cities與他們各自的價值觀。

返回7.4倍我必須爲這些活動創建一組函數。 現在可以使用RETURNING clause of INSERT聲明和CTEs with UPDATE(也SQL Fiddle):

WITH theid AS (
    INSERT INTO tmp_places (name) VALUES ('Moscow') RETURNING id 
) 
UPDATE tmp_cities tc SET population = 15 
    FROM theid 
WHERE tc.id = theid.id; 

你也應該小心的約束,因爲不是所有的人繼承。