次のような関数があります。
BEGIN
DROP DATABASE IF EXISTS db_1;
END;
次のエラーが表示されます。
エラー: 関数またはマルチコマンド文字列から DROP DATABASE を実行することはできません。
PostgreSQL のストアド プロシージャからデータベースを削除することはできませんか? 私はplpgsqlを使用しています。
次のような関数があります。
BEGIN
DROP DATABASE IF EXISTS db_1;
END;
次のエラーが表示されます。
エラー: 関数またはマルチコマンド文字列から DROP DATABASE を実行することはできません。
PostgreSQL のストアド プロシージャからデータベースを削除することはできませんか? 私はplpgsqlを使用しています。
エラーメッセージは、これに関するマニュアルと同じくらい明確です:
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 WRAPPER
てFOREIGN 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$;