この質問がここに適しているのか、SO.。
これは私が起動したいスクリプトです(関数のコードはコピーされました SOに関する質問から ):
\c mydb
create or replace function truncate_tables(username in varchar) returns void as $$
declare
stmt RECORD;
statements cursor for select tablename from pg_tables where tableowner = username;
begin
for stmt in statements loop
execute 'truncate table ' || quote_ident(stmt.tablename) || ' CASCADE ;';
end loop;
end;
$$ language 'plpgsql';
次のエラーが発生します。
ERROR: syntax at or near "$1" LINE1: $1
QUERY $1
CONTEXT: SQL statement in PL/PgSQL function "truncate_tables" near line 5
私はPostgresとPL/pgSQLを初めて使用しますが、このエラーメッセージの意味がわかりません。
明示カーソルを省略してみてください。
begin;
set role dba;
create role stack;
grant stack to dba;
create schema authorization stack;
set role stack;
--
create table foo(id serial);
insert into foo default values;
create or replace function truncate_tables(username in varchar) returns void as $$
declare r record;
begin
for r in (select tablename from pg_tables where tableowner = username) loop
execute 'truncate table ' || quote_ident(r.tablename) || ' cascade';
end loop;
end;
$$ language 'plpgsql';
--
select truncate_tables('stack');
select * from foo;
/*
id
----
(0 rows)
*/
--
rollback;
この特定の例はもっと簡単です。
一度に複数のテーブルをTRUNCATE
できます。すべてのテーブル名を集約し、単一のステートメントを実行します。
_CREATE OR REPLACE FUNCTION truncate_tables(_username text)
RETURNS void AS
$func$
BEGIN
EXECUTE (
SELECT 'TRUNCATE TABLE '
|| string_agg(quote_ident(t.tablename), ', ')
|| ' CASCADE;'
FROM pg_tables t
WHERE t.tableowner = _username
AND t.schemaname = 'public'
);
END;
$func$ LANGUAGE plpgsql;
_
コール:
_SELECT truncate_tables('postgres');
_
string_agg()
にはPostgreSQL9.0以降が必要です。
8.4では、次のように置き換えることができます。
_array-to_string(array_agg(quote_ident(t.tablename)), ', ')
_
V8.3の場合は、独自の集計関数を作成します。かなり単純ですが、ループソリューションよりも単純ではありません。
PostgreSQL 9.1で多くのテーブルを一度に削除または切り捨てると、パフォーマンスが低下します。今後のバージョン9.2でのこれの修正。引用します リリースノート :
多くのテーブルが削除または切り捨てられている場合のチェックポインターのfsync-requestキューのパフォーマンスを改善します(Tom Lane)
@ CraigのSOでの関連回答 これを発見するのに役立ちました。