185

再構築する前に、PostgreSQLデータベースからすべてのデータを定期的に削除する必要があります。これをSQLで直接行うにはどうすればよいですか?

現時点では、実行する必要のあるすべてのコマンドを返すSQLステートメントを思い付くことができました。

SELECT 'TRUNCATE TABLE ' ||  tablename || ';' FROM pg_tables WHERE tableowner='MYUSER';

しかし、一度入手すると、プログラムで実行する方法がわかりません。

4

11 に答える 11

270

FrustratedWithFormsDesignerは正しいですが、PL/pgSQLはこれを行うことができます。スクリプトは次のとおりです。

CREATE OR REPLACE FUNCTION truncate_tables(username IN VARCHAR) RETURNS void AS $$
DECLARE
    statements CURSOR FOR
        SELECT tablename FROM pg_tables
        WHERE tableowner = username AND schemaname = 'public';
BEGIN
    FOR stmt IN statements LOOP
        EXECUTE 'TRUNCATE TABLE ' || quote_ident(stmt.tablename) || ' CASCADE;';
    END LOOP;
END;
$$ LANGUAGE plpgsql;

これにより、ストアド関数が作成され(これは1回だけ実行する必要があります)、後で次のように使用できます。

SELECT truncate_tables('MYUSER');
于 2010-05-13T19:02:36.367 に答える
106

plpgsqlで明示カーソルが必要になることはめったにありません。ループのより単純で高速な暗黙カーソルを使用します。FOR

注:テーブル名はデータベースごとに一意ではないため、確実にテーブル名をスキーマ修飾する必要があります。また、関数をデフォルトのスキーマ「public」に制限します。ニーズに合わせて調整しますが、システムスキーマpg_*とを必ず除外してくださいinformation_schema

これらの機能には十分注意してください。彼らはあなたのデータベースを破壊します。子供の安全装置を追加しました。RAISE NOTICE行にコメントし、コメントEXECUTEを外して爆弾を準備します...

CREATE OR REPLACE FUNCTION f_truncate_tables(_username text)
  RETURNS void AS
$func$
DECLARE
   _tbl text;
   _sch text;
BEGIN
   FOR _sch, _tbl IN 
      SELECT schemaname, tablename
      FROM   pg_tables
      WHERE  tableowner = _username
      AND  
      -- dangerous, test before you execute!
      RAISE NOTICE '%',  -- once confident, comment this line ...
      -- EXECUTE         -- ... and uncomment this one
         format('TRUNCATE TABLE %I.%I CASCADE', _sch, _tbl);
   END LOOP;
END
$func$ LANGUAGE plpgsql;

format()Postgres9.1以降が必要です。古いバージョンでは、クエリ文字列を次のように連結します。

'TRUNCATE TABLE ' || quote_ident(_sch) || '.' || quote_ident(_tbl)  || ' CASCADE';

単一コマンド、ループなし

一度に複数のテーブルを作成できるためTRUNCATE、カーソルやループはまったく必要ありません。

すべてのテーブル名を集約し、単一のステートメントを実行します。よりシンプルで高速:

CREATE OR REPLACE FUNCTION f_truncate_tables(_username text)
  RETURNS void AS
$func$
BEGIN
   -- dangerous, test before you execute!
   RAISE NOTICE '%',  -- once confident, comment this line ...
   -- EXECUTE         -- ... and uncomment this one
  (SELECT 'TRUNCATE TABLE '
       || string_agg(format('%I.%I', schemaname, tablename), ', ')
       || ' CASCADE'
   FROM   pg_tables
   WHERE  tableowner = _username
   AND    schemaname = 'public'
   );
END
$func$ LANGUAGE plpgsql;

電話:

SELECT truncate_tables('postgres');

洗練されたクエリ

関数も必要ありません。DOPostgres 9.0以降では、ステートメントで動的コマンドを実行できます。また、Postgres 9.5以降では、構文がさらに単純になる可能性があります。

DO
$func$
BEGIN
   -- dangerous, test before you execute!
   RAISE NOTICE '%',  -- once confident, comment this line ...
   -- EXECUTE         -- ... and uncomment this one
   (SELECT 'TRUNCATE TABLE ' || string_agg(oid::regclass::text, ', ') || ' CASCADE'
    FROM   pg_class
    WHERE  relkind = 'r'  -- only tables
    AND    relnamespace = 'public'::regnamespace
   );
END
$func$;

pg_classpg_tablesとの違いについてinformation_schema.tables

regclass引用されたテーブル名について:

繰り返し使用する場合

バニラ構造とすべての空のテーブルを使用して「テンプレート」データベース(名前を付けましょう)を作成します。my_template次に、DROP/CREATE DATABASEサイクルを実行します。

DROP DATABASE mydb;
CREATE DATABASE mydb TEMPLATE my_template;

Postgresは構造全体をファイルレベルでコピーするため、これは非常に高速です。同時実行の問題やその他のオーバーヘッドによって速度が低下することはありません。

同時接続によってDBをドロップできない場合は、次のことを検討してください。

于 2012-08-22T22:01:34.370 に答える
44

これを行う必要がある場合は、現在のデータベースのスキーマSQLを作成し、次にデータベースを削除して作成し、データベースにスキーマSQLをロードします。

関係する手順は次のとおりです。

1)データベースのスキーマダンプを作成します(--schema-only

pg_dump mydb -s > schema.sql

2)データベースを削除します

drop database mydb;

3)データベースを作成する

create database mydb;

4)スキーマのインポート

psql mydb < schema.sql

于 2014-08-05T10:21:54.033 に答える
11

次のクエリを実行するだけです。

DO $$ DECLARE
    r RECORD;
BEGIN
    FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
        EXECUTE 'TRUNCATE TABLE ' || quote_ident(r.tablename) || '';
    END LOOP;
END $$;
于 2020-08-03T09:53:57.757 に答える
10

この場合、テンプレートとして使用する空のデータベースを用意し、更新する必要がある場合は、既存のデータベースを削除して、テンプレートから新しいデータベースを作成することをお勧めします。

于 2010-05-13T20:35:44.020 に答える
5

みんなより良い、きれいな方法は次のとおりです:

1)データベースのスキーマダンプを作成します(--schemaのみ)pg_dump mydb -s> schema.sql

2)データベースのドロップデータベースmydbのドロップ;

3)データベースの作成データベースmydbの作成;

4)スキーマのインポートpsql mydb <schema.sql

それは私のために働きます!

良い1日を。ハイラムウォーカー

于 2018-06-05T15:01:10.537 に答える
3

動的SQLを使用して、各ステートメントを順番に実行できますか?これを行うには、おそらくPL/pgSQLスクリプトを作成する必要があります。

http://www.postgresql.org/docs/8.3/static/plpgsql-statements.html(セクション38.5.4。動的コマンドの実行)

于 2010-05-13T18:06:00.837 に答える
3

クリーニングAUTO_INCREMENTバージョン:

CREATE OR REPLACE FUNCTION truncate_tables(username IN VARCHAR) RETURNS void AS $$
DECLARE
    statements CURSOR FOR
        SELECT tablename FROM pg_tables
        WHERE tableowner = username AND schemaname = 'public';
BEGIN
    FOR stmt IN statements LOOP
        EXECUTE 'TRUNCATE TABLE ' || quote_ident(stmt.tablename) || ' CASCADE;';

        IF EXISTS (
            SELECT column_name 
            FROM information_schema.columns 
            WHERE table_name=quote_ident(stmt.tablename) and column_name='id'
        ) THEN
           EXECUTE 'ALTER SEQUENCE ' || quote_ident(stmt.tablename) || '_id_seq RESTART WITH 1';
        END IF;

    END LOOP;
END;
$$ LANGUAGE plpgsql;
于 2017-08-17T19:42:17.710 に答える
2

これはbashでも実行できます。

#!/bin/bash
PGPASSWORD='' psql -h 127.0.0.1 -Upostgres sng --tuples-only --command "SELECT 'TRUNCATE TABLE ' || schemaname || '.' ||  tablename || ';' FROM pg_tables WHERE schemaname in ('cms_test', 'ids_test', 'logs_test', 'sps_test');" | 
tr "\\n" " " | 
xargs -I{} psql -h 127.0.0.1 -Upostgres sng --command "{}"

スキーマに一致するように、スキーマ名、パスワード、およびユーザー名を調整する必要があります。

于 2013-04-09T13:56:53.040 に答える
2

psqlを使用できる場合は、 \gexecmetaコマンドを使用してクエリ出力を実行できます。

SELECT
    format('TRUNCATE TABLE %I.%I', ns.nspname, c.relname)
  FROM pg_namespace ns 
  JOIN pg_class c ON ns.oid = c.relnamespace
  JOIN pg_roles r ON r.oid = c.relowner
  WHERE
    ns.nspname = 'table schema' AND                               -- add table schema criteria 
    r.rolname = 'table owner' AND                                 -- add table owner criteria
    ns.nspname NOT IN ('pg_catalog', 'information_schema') AND    -- exclude system schemas
    c.relkind = 'r' AND                                           -- tables only
    has_table_privilege(c.oid, 'TRUNCATE')                        -- check current user has truncate privilege
  \gexec 

\gexecバージョン9.6に導入されていることに注意してください

于 2020-03-17T12:23:15.540 に答える
1

データを削除し、 pgAdminでテーブル構造を保持するには、次の操作を実行できます。

  • [データベース]->[バックアップ]を右クリックし、[スキーマのみ]を選択します
  • データベースを削除します
  • 新しいデータベースを作成し、前者のように名前を付けます
  • 新しいデータベースを右クリック->復元->バックアップを選択し、[スキーマのみ]を選択します
于 2017-03-29T12:09:33.483 に答える