5

次のような関数があります。

BEGIN
  DROP DATABASE IF EXISTS db_1;
END;

次のエラーが表示されます。

エラー: 関数またはマルチコマンド文字列から DROP DATABASE を実行することはできません。

PostgreSQL のストアド プロシージャからデータベースを削除することはできませんか? 私はplpgsqlを使用しています。

4

2 に答える 2

4

エラーメッセージは、これに関するマニュアルと同じくらい明確です:

DROP DATABASEトランザクション ブロック内では実行できません。

plgpsql 関数は、自動的にトランザクション ブロックに囲まれます。一長一短:あなたはそれをすることはできません - 直接。DDL コマンドを呼び出すことができない特定の理由はありますか?

DROP database $mydb;

@Igorが提案したように、追加のモジュールdblinkを使用してこれらの制限を回避できます。コマンドを実行する(他の)データベースではなく、dblink関数を呼び出すデータベースごとに1回インストールする必要があります。次のよう に使用して関数を作成できます。
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');

成功すると、次のように表示されます。

データベースをドロップ

接続文字列は、セッションが実行されているのと同じデータベースを指すことさえあります。コマンドはトランザクション ブロックの外側で実行され、次の 2 つの結果があります。

  • ロールバックすることはできません。
  • 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');

デフォルトのメンテナンス db を使用します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$;
于 2013-03-07T00:31:52.110 に答える
1

drop databaseトランザクション内で実行することはできず、ストアド プロシージャはトランザクション自体と見なされるため、プロシージャから実行することはできません。(参照参照

dropdbはどうですか?

于 2013-03-06T20:27:45.797 に答える