เคอร์เซอร์ที่ชัดเจนนั้นไม่ค่อยจำเป็นใน plpgsql ใช้เคอร์เซอร์โดยนัยที่ง่ายและเร็วกว่าของFOR
ลูป:
หมายเหตุ:เนื่องจากชื่อตารางไม่ซ้ำกันสำหรับฐานข้อมูลคุณจึงต้องตรวจสอบชื่อตารางเพื่อให้แน่ใจ นอกจากนี้ฉัน จำกัด ฟังก์ชั่นให้เป็นสคีมาเริ่มต้น 'สาธารณะ' ปรับให้เข้ากับความต้องการของคุณ แต่ต้องแน่ใจว่าจะไม่รวม schemas ระบบและ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
) กับโครงสร้างวานิลลาของคุณและตารางที่ว่างเปล่าทั้งหมด จากนั้นผ่าน a DROP
/CREATE DATABASE
cycle:
DROP DATABASE mydb;
CREATE DATABASE mydb TEMPLATE my_template;
สิ่งนี้เร็วมากเนื่องจาก Postgres จะคัดลอกโครงสร้างทั้งหมดในระดับไฟล์ ไม่มีปัญหาการทำงานพร้อมกันหรือค่าใช้จ่ายอื่น ๆ ทำให้คุณช้าลง
หากการเชื่อมต่อที่เกิดขึ้นพร้อมกันทำให้คุณไม่สามารถทิ้ง DB ได้ให้พิจารณา: