3 回答

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超6個(gè)贊
FrustratedWithFormsDesigner是正確的,PL / pgSQL可以做到這一點(diǎn)。這是腳本:
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;
這將創(chuàng)建一個(gè)存儲(chǔ)的函數(shù)(您只需執(zhí)行一次),之后就可以像下面這樣使用:
SELECT truncate_tables('MYUSER');

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超8個(gè)贊
在plpgsql中很少需要顯式游標(biāo)。使用更簡(jiǎn)單,更快的循環(huán)隱式游標(biāo)FOR:
注意:由于表名在每個(gè)數(shù)據(jù)庫(kù)中都不唯一,因此必須對(duì)表名進(jìn)行模式限定。另外,我將功能限制為默認(rèn)模式“ public”。適應(yīng)您的需求,但請(qǐng)確保排除系統(tǒng)架構(gòu)pg_*和information_schema。
這些功能要非常小心。他們破壞您的數(shù)據(jù)庫(kù)。我添加了兒童安全裝置。評(píng)論RAISE NOTICE界線和取消EXECUTE引爆炸彈的評(píng)論...
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';
單個(gè)命令,無循環(huán)
由于我們可以TRUNCATE一次創(chuàng)建多個(gè)表,因此根本不需要任何游標(biāo)或循環(huán):
在數(shù)組中傳遞表名
匯總所有表名并執(zhí)行一條語(yǔ)句。更簡(jiǎn)單,更快:
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');
細(xì)化查詢
您甚至不需要功能。在Postgres 9.0+中,您可以在DO語(yǔ)句中執(zhí)行動(dòng)態(tài)命令。在Postgres 9.5+中,語(yǔ)法甚至可以更簡(jiǎn)單:
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$;
關(guān)于之間的差異pg_class,pg_tables以及information_schema.tables:
如何檢查給定架構(gòu)中是否存在表
關(guān)于regclass和引用表名:
表名作為PostgreSQL函數(shù)參數(shù)
重復(fù)使用
使用香草結(jié)構(gòu)和所有空表創(chuàng)建一個(gè)“模板”數(shù)據(jù)庫(kù)(命名為my_template)。然后經(jīng)歷一個(gè)DROP/CREATE DATABASE循環(huán):
DROP DATABASE mydb;
CREATE DATABASE mydb TEMPLATE my_template;
這非??欤?yàn)镻ostgres在文件級(jí)別復(fù)制整個(gè)結(jié)構(gòu)。沒有并發(fā)問題或其他開銷使您慢下來。
如果并發(fā)連接使您無法刪除數(shù)據(jù)庫(kù),請(qǐng)考慮:
在其他人可能已連接的情況下強(qiáng)制下降db

TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超11個(gè)贊
如果必須執(zhí)行此操作,則只需創(chuàng)建當(dāng)前數(shù)據(jù)庫(kù)的模式sql,然后刪除并創(chuàng)建數(shù)據(jù)庫(kù),然后使用模式sql加載db。
以下是涉及的步驟:
1)創(chuàng)建數(shù)據(jù)庫(kù)的模式轉(zhuǎn)儲(chǔ)(--schema-only
)
pg_dump mydb -s > schema.sql
2)刪除數(shù)據(jù)庫(kù)
drop database mydb;
3)創(chuàng)建數(shù)據(jù)庫(kù)
create database mydb;
4)導(dǎo)入架構(gòu)
psql mydb < schema.sql
添加回答
舉報(bào)