Plpgsql'de açık imleçlere nadiren ihtiyaç duyulur. Bir döngünün daha basit ve daha hızlı örtük imlecini kullanın FOR
:
Not: Tablo adları veritabanı başına benzersiz olmadığından, emin olmak için tablo adlarını şema nitelemelisiniz. Ayrıca, işlevi varsayılan şema 'genel' ile sınırlandırıyorum. Gereksinimlerinize uyum sağlayın, ancak sistem şemalarını pg_*
ve hariç tuttuğunuzdan emin olun information_schema
.
Be çok dikkatli bu işlevlerle. Onlar veritabanı nuke. Bir çocuk güvenlik cihazı ekledim. Comment RAISE NOTICE
hattı ve yorumsuz EXECUTE
asal bomba ...
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 veya üstünü gerektirir. Eski sürümlerde sorgu dizesini şu şekilde birleştirin:
'TRUNCATE TABLE ' || quote_ident(_sch) || '.' || quote_ident(_tbl) || ' CASCADE';
Tek komut, döngü yok
Aynı anda TRUNCATE
birden fazla tablo yapabileceğimizden, imleç veya döngüye hiç ihtiyacımız yok:
Tüm tablo adlarını toplayın ve tek bir deyim yürütün. Daha basit, daha hızlı:
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;
Aramak:
SELECT truncate_tables('postgres');
Hassaslaştırılmış sorgu
Bir işleve bile ihtiyacınız yok. Postgres 9.0 ve sonraki sürümlerinde bir DO
deyimde dinamik komutları yürütebilirsiniz . Postgres 9.5 ve sonraki sürümlerde sözdizimi daha da basit olabilir:
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$;
Arasındaki fark hakkında pg_class
, pg_tables
ve information_schema.tables
:
regclass
Tablo adları hakkında ve alıntılanan tablo adları:
Tekrarlanan kullanım için
Vanilya yapınız ve tüm boş tablolarınızla bir "şablon" veritabanı oluşturun (adını verelim my_template
). Sonra bir DROP
/CREATE DATABASE
döngüsü geçirin:
DROP DATABASE mydb;
CREATE DATABASE mydb TEMPLATE my_template;
Bu son derece hızlıdır , çünkü Postgres tüm yapıyı dosya düzeyinde kopyalar. Eşzamanlılık sorunları veya başka ek yükler sizi yavaşlatmaz.
Eşzamanlı bağlantılar DB'yi bırakmanıza engel oluyorsa şunları göz önünde bulundurun: