2013-03-06 191 views
2

創建數據庫我有一個功能,看起來像這樣:刪除或存儲過程中的PostgreSQL

BEGIN 
    DROP DATABASE IF EXISTS db_1; 
END; 

,我發現了以下錯誤:

ERROR: DROP DATABASE cannot be executed from a function or multi-command string.

是沒可能砸數據庫從PostgreSQL中的存儲過程?我正在使用plpgsql。

+0

您可以從另一個數據庫 – Houari 2013-03-06 20:26:31

+1

你可以嘗試'dblink'任何分貝這一組(exept要刪除的)做到這一點,執行' DROP DATABASE如果存在db_1;'dblink'。 – 2013-03-06 22:28:18

+1

我相信錯誤信息很清楚。 – 2013-03-07 00:14:52

回答

1

你不能從程序中完成它,因爲drop database不能在事務內部執行,並且存儲過程本身被視爲事務。 (見reference

那麼dropdb呢?

+0

我正在做另一個數據庫。 sp在db_2中,我從那裏運行它。我會嘗試從postgres – Rudecles 2013-03-06 21:10:55

+0

沒有工作,同樣的錯誤 – Rudecles 2013-03-06 21:17:00

+0

這顯然不是這裏的主要問題。你看過錯誤信息嗎? – 2013-03-07 00:32:49

2

該錯誤消息是隻是A S清楚the manual在此:

DROP DATABASE cannot be executed inside a transaction block.

甲plgpsql功能是由一個事務塊自動包圍。它的長和短:你不能直接做到這一點。是否有一個特殊的原因,你不能只調用DDL命令?

DROP database $mydb; 

可以規避與附加模塊這些限制dblink@Igor建議。你需要爲每個數據庫安裝一次 - 在一個地方,你叫DBLINK功能,而不是(別的)其中之一,你在執行命令
讓你寫使用dblink_exec()這樣的功能:

CREATE OR REPLACE FUNCTION f_drop_db(text) 
    RETURNS text LANGUAGE sql AS 
$func$ 
SELECT dblink_exec('port=5432 dbname=postgres' 
        ,'DROP DATABASE ' || quote_ident($1)) 
$func$; 

quote_ident()阻止。可能的SQL注入。

電話:

SELECT f_drop_db('mydb'); 

上的成功,你看:

DROP DATABASE

連接字符串甚至可以指向同一個數據庫會話運行在一個事務塊,其中有外運行該命令。兩個後果:

  • 它不能回滾。
  • 它允許您從一個函數中通過「代理服務器」調用DROP DATABASE

您可以創建一個FOREIGN DATA WRAPPERFOREIGN SERVER存儲的連接,並簡化呼叫:

CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator; 

CREATE SERVER your_fdw_name_here FOREIGN DATA WRAPPER postgresql 
OPTIONS (hostaddr '12.34.56.78', port '5432', dbname 'postgres'); 

使用默認維護分貝postgres,這將是顯而易見的選擇。但任何分貝都是可能的。

簡化功能利用認爲:

CREATE OR REPLACE FUNCTION f_drop_db(text) 
    RETURNS text LANGUAGE sql AS 
$func$ 
SELECT dblink_exec('your_fdw_name_here', 'DROP DATABASE ' || quote_ident($1)) 
$func$;