2014-02-12 46 views
0

是否可以使用模式名稱作爲PostgreSQL中表的外鍵?喜歡的東西:將模式名稱用作PostgreSQL表中的外鍵

create table account(
    id varchar(30) references information_schema.schemata(schema_name) 
); 

運行過程中出現上面的SQL,我得到以下錯誤:

SQL Error: 

ERROR: referenced relation "schemata" is not a table 

In block: 

create table account(
    id varchar(30) references information_schema.schemata(schema_name) 
); 

的想法是,以檢查是否帳戶的模式存在之前創建的帳戶。

+2

據我所知,你不能在外鍵中引用*任何*系統表(並且此外:'information_schema'中的所有內容都是視圖,無論如何你都不能引用) –

+0

@a_horse_with_no_name,謝謝你的提示!請張貼它作爲答案,可能它會是最好的。 –

+0

您可以使用約束觸發器創建類似外鍵的東西,但它會比實際的FK慢得多。 –

回答

3

您只能創建混凝土表FK參考 - 沒有意見,像information_schema.schemata

regress=> \dv information_schema.schemata 
       List of relations 
     Schema  | Name | Type | Owner 
--------------------+----------+------+---------- 
information_schema | schemata | view | postgres 
(1 row) 

底層pg_catalog.pg_namespace表背視圖:

regress=> select pg_get_viewdef('information_schema.schemata'); 
              pg_get_viewdef            
----------------------------------------------------------------------------------------------------- 
    SELECT (current_database())::information_schema.sql_identifier AS catalog_name,     + 
    (n.nspname)::information_schema.sql_identifier AS schema_name,         + 
    (u.rolname)::information_schema.sql_identifier AS schema_owner,        + 
    (NULL::character varying)::information_schema.sql_identifier AS default_character_set_catalog, + 
    (NULL::character varying)::information_schema.sql_identifier AS default_character_set_schema, + 
    (NULL::character varying)::information_schema.sql_identifier AS default_character_set_name, + 
    (NULL::character varying)::information_schema.character_data AS sql_path      + 
    FROM pg_namespace n,                   + 
    pg_authid u                     + 
    WHERE ((n.nspowner = u.oid) AND pg_has_role(n.nspowner, 'USAGE'::text)); 
(1 row) 

regress=> \dt pg_catalog.pg_namespace 
       List of relations 
    Schema |  Name  | Type | Owner 
------------+--------------+-------+---------- 
pg_catalog | pg_namespace | table | postgres 
(1 row) 

...也沒有因爲PostgreSQL不支持系統表的外鍵引用:

regress=> CREATE TABLE blah (x text references pg_catalog.pg_namespace(nspname)); 
ERROR: permission denied: "pg_namespace" is a system catalog 

所以......你不能。

+0

非常明確你的解釋,謝謝!你認爲創建一個觸發器來檢查這個是一個好主意嗎? –

+0

@MarcioSimao當然,但您只能創建一面,因爲您無法在系統表上創建觸發器。因此,如果引用該模式,則無法阻止某個模式被刪除,只會阻止創建引用不存在模式的行。 –