2014-02-14 41 views
1

運行下面的查詢:如何檢查PostgreSQL公共模式是否存在?

SELECT exists(
       SELECT schema_name 
       FROM information_schema.schemata 
       WHERE schema_name = 'public' 
      ) as schema_exists; 

我得到總是FALSE,即使公共模式的存在。

我應該如何檢查這個模式是否存在?

編輯

我使用PostgreSQL 8.4版

+0

當我在本地運行它時,它會爲我返回true(作爲布爾值)...您如何檢查返回值? – Ruslan

+0

你怎麼知道公共模式存在?我正在執行相同的查詢並變得真實! – Houari

+0

@Ruslan,我正在使用PostgreSQL 8.4。你的版本是什麼? –

回答

2

information_schema.schemata的信息取決於你和連接的作用,所以它不是真正的查詢,發現在一般模式右視圖。

doc on information_schema.schemata in 9.3說:

視圖大綱包含在 由當前啓用的角色所擁有的當前數據庫中的所有模式。

但是,從這句話來看,這並不太清楚(至少對我來說),爲什麼你看不到public

在郵件列表後,湯姆弄了一個解釋更進了一點:
http://www.postgresql.org/message-id/[email protected]

他的結論是:

就目前情況來看,非超級用戶不會看到「公共」,「pg_catalog」,甚至「information_schema」本身在這個視圖中,這似乎是愚蠢的。

這看起來完全像這個問題的問題。

底線:使用pg_namespace代替information_schema.schemata


這是在9.4版修訂,以符合哪些用戶的期望。該current doc說:

視圖大綱包含在 當前用戶訪問(通過的是所有者或者有 有些權限)當前數據庫中的所有模式。

USAGE對模式的特權現在已足以從此視圖中獲得它。

+0

非常豐富的答案,非常感謝!我將使用'pg_namespace'而不是'information_schema.schemata'。 –

0

,你寫的應該有工作該查詢嘗試這種另類:

select count(*) > 0 FROM information_schema.schemata WHERE schema_name = 'public'; 
+0

我仍然收到'FALSE' –

1

(郵寄從意見的答案)

直接引用pg_namespace表可能是一個體面的解決方法...

SELECT exists(select 1 from pg_namespace where nspname = 'public') as schema_exists; 

我不知道確切的區別是什麼,但在PostgreSQL內部知道名稱空間「返回」模式。

而且,我相信那些系統PG_ *表不保證留跨版本保持一致,但它一直在那裏,因爲至少7.3(http://www.postgresql.org/docs/7.4/static/catalog-pg-namespace.html),是有現在(9.3.1)。

2

我想你不能看到公共模式,因爲你用來測試模式存在的數據庫角色。 information_schema.schemata實際上是具有以下定義的圖:

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); 

這在documentation也有描述。

在這種情況下,您可以在psql - \d+ information_schema.schemata中使用\d+獲得information_schema中視圖的定義。

,您應該使用的information_schema.schematapg_namespace代替

+0

感謝您的解釋!你知道什麼是最好的解決方法嗎? –

+0

按照Ruslan的回答中所述,使用'pg_namespace'。 –