回答:
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;
これは、後で次のように使用できるストアド関数を作成します(これは一度だけ実行する必要があります)。
SELECT truncate_tables('MYUSER');
DECLARE r RECORD;
その後forループ: FOR r IN SELECT tablename FROM pg_tables LOOP
明示的なカーソルが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 schemaname = 'public'
LOOP
RAISE NOTICE '%',
-- EXECUTE -- dangerous, test before you execute!
format('TRUNCATE TABLE %I.%I CASCADE', _sch, _tbl);
END LOOP;
END
$func$ LANGUAGE plpgsql;
format()
Postgres 9.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
RAISE NOTICE '%',
-- EXECUTE -- dangerous, test before you execute!
(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');
関数も必要ありません。Postgres 9.0以降では、DO
ステートメント内で動的コマンドを実行できます。また、Postgres 9.5以降では、構文がさらにシンプルになります。
DO
$func$
BEGIN
RAISE NOTICE '%',
-- EXECUTE
(SELECT 'TRUNCATE TABLE ' || string_agg(oid::regclass::text, ', ') || ' CASCADE'
FROM pg_class
WHERE relkind = 'r' -- only tables
AND relnamespace = 'public'::regnamespace
);
END
$func$;
違いについてpg_class
、pg_tables
そしてinformation_schema.tables
:
regclass
引用されたテーブル名について:
バニラ構造とすべての空のテーブルを使用して、「テンプレート」データベース(名前を付けましょうmy_template
)を作成します。次に、DROP
/CREATE DATABASE
サイクルを実行します。
DROP DATABASE mydb;
CREATE DATABASE mydb TEMPLATE my_template;
Postgresは構造全体をファイルレベルでコピーするため、これは非常に高速です。同時実行の問題やその他のオーバーヘッドにより、速度が低下することはありません。
同時接続によってDBをドロップできない場合は、以下を検討してください。
DROP DATABASE mydb
明らかにを除く)。スキーマとデータベースを混同していますか?
DO
(他のSQL文のような)コマンドは、現在のデータベースで実行され、排他的。Postgresは同じトランザクションで他のデータベースにアクセスする方法がありません。そのためには、dblinkまたはFDWを使用する必要があります。しかし、それはありませんあなたが追加しない限り-現在のデータベース内のすべてのスキーマに影響を与えWHERE t.schemaname = 'public'
、この特定のケースではある特定のスキーマへの影響を制限します。
これを行う必要がある場合は、現在のdbのスキーマsqlを作成してから、dbをドロップして作成し、スキーマsqlでdbをロードします。
以下は関連するステップです:
1)データベースのスキーマダンプを作成します(--schema-only
)
pg_dump mydb -s > schema.sql
2)データベースを削除する
drop database mydb;
3)データベースを作成する
create database mydb;
4)スキーマのインポート
psql mydb < schema.sql
動的SQLを使用して各ステートメントを順番に実行できますか?これを行うには、おそらくPL / pgSQLスクリプトを記述する必要があります。
http://www.postgresql.org/docs/8.3/static/plpgsql-statements.html(セクション38.5.4。動的コマンドの実行)
あなたは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 "{}"
スキーマに一致するように、スキーマ名、パスワード、およびユーザー名を調整する必要があります。
クリーニング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;
あなたが使用できる場合はpsqlを、あなたは使用することができ\gexec
、クエリの出力を実行するためのメタコマンドを。
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で導入されたことに注意してください。
データを削除し、pgAdminのテーブル構造を維持するには、次のようにします。