web-dev-qa-db-ja.com

postgresで同じプレフィックスを共有するすべてのテーブルを削除します

1つのSQLコマンド/クエリを使用して、同じプレフィックス( 'supenh_agk')を共有するすべてのテーブルを同じデータベースから削除したいと思います。

16
Roy

oneコマンドでこれを行うには、 EXECUTE ステートメント(または関数)にDOを含む動的SQLが必要です。

_DO
$do$
DECLARE
   _tbl text;
BEGIN
FOR _tbl  IN
    SELECT quote_ident(table_schema) || '.'
        || quote_ident(table_name)      -- escape identifier and schema-qualify!
    FROM   information_schema.tables
    WHERE  table_name LIKE 'prefix' || '%'  -- your table name prefix
    AND    table_schema NOT LIKE 'pg\_%'    -- exclude system schemas
LOOP
   RAISE NOTICE '%',
-- EXECUTE
  'DROP TABLE ' || _tbl;  -- see below
END LOOP;
END
$do$;
_

これには、現在のユーザーがアクセスできるallスキーマのテーブルが含まれます。安全のためにシステムスキーマを除外しました。

識別子を適切にエスケープしないと、二重引用符が必要な非標準の 識別子 に対してコードが失敗します。
さらに、SQLインジェクションを許可するリスクがあります。すべてのユーザー入力は、動的コードでサニタイズする必要があります。これには、ユーザーによって提供される可能性のある識別子が含まれます。

潜在的に危険です!これらのテーブルはすべて永久に削除されます。セーフティボックスを内蔵しました。実際に実行する前に、生成されたステートメントを調べてください。コメントRAISEをコメントし、EXECUTEのコメントを解除します。

他のオブジェクト(ビューなど)がテーブルに依存している場合は、代わりに有益なエラーメッセージが表示され、トランザクション全体がキャンセルされます。すべての扶養家族も死ぬ可能性があると確信している場合は、追加 CASCADE

_  'DROP TABLE ' || _tbl || ' CASCADE;
_

密接に関連している:

あるいはカタログテーブルに基づいて構築することもできます _pg_class_ これはのoidも提供しますテーブルと高速です:

_...
FOR _tbl  IN
    SELECT c.oid::regclass::text  -- escape identifier and schema-qualify!
    FROM   pg_catalog.pg_class c
    JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
    WHERE  n.nspname NOT LIKE 'pg\_%'     -- exclude system schemas
    AND    c.relname LIKE 'prefix' || '%' -- your table name prefix
    AND    c.relkind = 'r'                -- only tables
...
_

システムカタログまたは情報スキーマ?

_c.oid::regclass_はSQLインジェクションに対してどのように防御しますか?

またはすべてを単一のDROPコマンドで実行します。もう少し効率的である必要があります:

_DO
$do$
BEGIN
   RAISE NOTICE '%', (
-- EXECUTE (
   SELECT 'DROP TABLE ' || string_agg(format('%I.%I', schemaname, tablename), ', ')
   --  || ' CASCADE' -- optional
   FROM   pg_catalog.pg_tables t
   WHERE  schemaname NOT LIKE 'pg\_%'     -- exclude system schemas
   AND    tablename LIKE 'prefix' || '%'  -- your table name prefix
   );
END
$do$;
_

関連:

最後の例では、便利なフィッティングシステムカタログ_pg_tables_を使用しています。そして、便宜上format()。見る:

27

プレフィックスが「sales_」であるとします。

ステップ1:そのプレフィックスを持つすべてのテーブル名を取得します

SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'sales_%';

ステップ2: [CSVとしてダウンロード]ボタンをクリックします。

ステップ3:ファイルをエディターで開き、"sales _、salesに、"をスペースに置き換えます

ステップ4:DROP TABLE sales_regist, sales_name, sales_info, sales_somthing;

7
Ryan Augustine

これはSQLサーバーコマンドです。これを試すことができますか、postgresで機能するかどうか。このクエリは、削除用のSQLスクリプトを生成します

SELECT 'DROP TABLE "' || TABLE_NAME || '"' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

[編集]

begin
    for arow in
      SELECT 'DROP TABLE "' || TABLE_NAME || '"' as col1
      FROM INFORMATION_SCHEMA.TABLES 
      WHERE TABLE_NAME LIKE '[prefix]%'
    LOOP
   --RAISE NOTICE '%',    
    EXECUTE 'DROP TABLE ' || arow ;
END LOOP;
  end;
3