2014-02-17 78 views
0

您好我想創建一個在像pg_catalog創建一個表函數:postgresql:如何用函數修改pg_catalog?

CREATE OR REPLACE FUNCTION foo() RETURNS void AS $$ 
DECLARE 

BEGIN 
EXECUTE 'CREATE TABLE pg_catalog.tab(a integer)'; 
     RETURN; 

END; 
$$ LANGUAGE plpgsql; 

錯誤:拒絕打造「pg_catalog.tab」權限
詳細信息:系統目錄修改目前禁止。

編輯我的問題,爲增加更多的細節:

房地產我想創建一個表時被丟棄的啓動功能。我認爲唯一的辦法就是創建表pg_catalog.tables觸發器:

CREATE OR REPLACE FUNCTION a() RETURNS void AS $$ 
DECLARE 
BEGIN 

    EXECUTE 'CREATE TRIGGER "tt_drop" BEFORE DELETE ON pg_catalog.pg_tables EXECUTE PROCEDURE public.b()'; 
    RETURN; 

END; 
$$ LANGUAGE plpgsql; 

,在b我想要做刪除表的一些操作也被刪除之前的功能...

回答

4

這禁止實際使用,主要是出於安全原因 - pg_catalog始終處於搜索路徑上,沒有人可以改變它,因爲PostgreSQL團隊預計pg_catalog中的函數不會被自定義函數覆蓋。

存在一些非常難看的技巧,但我不建議使用它。

有點不那麼醜陋,但仍然非常醜陋是將Postgres切換到單一模式 - 任何安全機制都關閉 - 但存在數據庫損壞的高風險。所以只有完全瞭解Postgres內部人員才能使用它。

回覆更新的問題:

不能創建系統表上的觸發器。但有event triggers,它可能是你想要的(由PostgreSQL 9.3支持)。

CREATE FUNCTION test_event_trigger_for_drops() 
     RETURNS event_trigger LANGUAGE plpgsql AS $$ 
DECLARE 
    obj record; 
BEGIN 
    FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() 
    LOOP 
     RAISE NOTICE '% dropped object: % %.% %', 
        tg_tag, 
        obj.object_type, 
        obj.schema_name, 
        obj.object_name, 
        obj.object_identity; 
    END LOOP; 
END 
$$; 

CREATE EVENT TRIGGER test_event_trigger_for_drops 
    ON sql_drop 
    EXECUTE PROCEDURE test_event_trigger_for_drops(); 

postgres=# DROP TABLE obce CASCADE; 
NOTICE: drop cascades to materialized view obce_stredocesky_kraj 
NOTICE: DROP TABLE dropped object: table public.obce public.obce 
NOTICE: DROP TABLE dropped object: index public.obce_okres_id_idx public.obce_okres_id_idx 
NOTICE: DROP TABLE dropped object: table constraint public.<NULL> obce_okres_id_fk on public.obce 
NOTICE: DROP TABLE dropped object: trigger <NULL>.<NULL> "RI_ConstraintTrigger_a_46471" on public.okresy 
NOTICE: DROP TABLE dropped object: trigger <NULL>.<NULL> "RI_ConstraintTrigger_a_46472" on public.okresy 
NOTICE: DROP TABLE dropped object: trigger <NULL>.<NULL> "RI_ConstraintTrigger_c_46473" on public.obce 
NOTICE: DROP TABLE dropped object: trigger <NULL>.<NULL> "RI_ConstraintTrigger_c_46474" on public.obce 
NOTICE: DROP TABLE dropped object: sequence public.obce_id_seq public.obce_id_seq 
NOTICE: DROP TABLE dropped object: type public.obce_id_seq public.obce_id_seq 
NOTICE: DROP TABLE dropped object: default value <NULL>.<NULL> for public.obce.id 
NOTICE: DROP TABLE dropped object: table constraint public.<NULL> _obce_pkey on public.obce 
NOTICE: DROP TABLE dropped object: index public._obce_pkey public._obce_pkey 
NOTICE: DROP TABLE dropped object: materialized view public.obce_stredocesky_kraj public.obce_stredocesky_kraj 
NOTICE: DROP TABLE dropped object: index public.obce_stredocesky_kraj_nazev_idx public.obce_stredocesky_kraj_nazev_idx 
NOTICE: DROP TABLE dropped object: type public.obce_stredocesky_kraj public.obce_stredocesky_kraj 
NOTICE: DROP TABLE dropped object: type public._obce_stredocesky_kraj public.obce_stredocesky_kraj[] 
NOTICE: DROP TABLE dropped object: rule <NULL>.<NULL> "_RETURN" on public.obce_stredocesky_kraj 
NOTICE: DROP TABLE dropped object: type public.obce public.obce 
NOTICE: DROP TABLE dropped object: type public._obce public.obce[] 
DROP TABLE 

看到

+0

感謝很有意思,但我需要刪除的表的名稱,現在不支持TG_OBJECTNAME!將來我會修改我的函數usign事件觸發器。現在我發現allow_system_table_mods = on可以添加到postgres.conf中,但是您如何告訴我這不是一種正確的模式:-(如果我只在創建觸發器後激活該觸發器並使其失效,那麼觸發器的工作原理是什麼? –

+0

@ user3297525 :刪除的表名是已知的 - 查看更新的回覆 –

+0

確定但是刪除的表不能移動到另一個模式(alter table t set schema s),因爲表t對於postgres現在不存在。 drop操作? –