มีวิธีที่ดีในการเรียกใช้ทริกเกอร์สำหรับแต่ละระเบียนในตาราง postgres หรือไม่?


22

ฉันมีระบบที่ฉันไม่สามารถควบคุมการออกแบบของบางตาราง (ทำซ้ำผ่าน Slony-I) และดังนั้นฉันจึงมีชุดของสิ่งที่เราอ้างถึงเป็น 'shadow tables' ซึ่งฉันดึงข้อมูลบางส่วนออกจากตารางที่จำลองแบบแล้ว และเก็บไว้ในแบบฟอร์มการประมวลผลที่ฉันต้องการในขณะที่แยกระเบียนที่ฉันต้องการละเว้น

ตอนนี้หลังจากตั้งค่าแบบจำลองใหม่ฉันเรียกใช้การอัปเดตและตั้งค่ากลับเป็นของตัวเอง (เช่นUPDATE tablename SET field=field) เพื่อบังคับให้ทริกเกอร์ทำงาน แต่ตารางบางตารางมีระเบียนนับล้านและเติบโตและใช้เวลา 30 นาที . (แล้วมีวัคซีนด้วย)

มีวิธีที่ดีกว่าในการทริกเกอร์มันหรือวิธีเขียนฟังก์ชั่นบางอย่างเพื่อให้ทำงานกับอินพุตที่ส่งผ่านหรือNEWขึ้นอยู่กับบริบทการโทร? ฉันลังเลที่จะเก็บฟังก์ชั่นที่แตกต่างกันสองอย่างเอาไว้เพราะฉันเห็นหลายครั้งที่มีการอัปเดต


ฉันรู้วิธีเรียกใช้ทริกเกอร์ ... ฉันถามว่ามีวิธีที่ดีหรือไม่
โจ

คำตอบ:


19

มันสามารถทำได้โดยใช้แม่แบบต่อไปนี้:

CREATE TABLE tablename ( ... );

/* for direct invocation */
CREATE FUNCTION propagate_data(newrow tablename) RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
    INSERT INTO other_table VALUES (newrow.a, newrow.b, ...);
END:
$$;

/* trigger function wrapper */
CREATE FUNCTION propagate_data_trg() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
    PERFORM propagate_data(NEW);
END;
$$;

CREATE TRIGGER propagate_data AFTER INSERT ON tablename FOR EACH ROW
    EXECUTE PROCEDURE propagate_data_trg();

Doh ... ฉันกำลังคิดถึงมันอยู่ข้างหลัง (พยายามทำให้ฟังก์ชั่นทริกเกอร์เรียกได้ว่าเป็นขั้นตอนไม่ใช่วีซ่าในทางกลับกัน)
Joe

1
เมื่อฉันทำมันฉันรู้ว่า 'row' เป็นคำที่สงวนไว้ดังนั้นฉันจึงแก้ไขตัวอย่างเพื่อให้ผู้อื่นไม่ใช้การดีบักนาน
โจ

1
ฉันน่าจะติดตามมาหลายปีแล้ว ฉันใช้เวลาสั้น ๆ ก่อนที่ฉันจะจัดการทุกอย่างในระบบของฉัน ... และวิธีนี้ใช้งานได้ แต่การแสดงนั้นยอดเยี่ยมมาก (เปลี่ยนจาก 30 นาทีเป็นมากกว่าหนึ่งวันเพื่อให้เสร็จสมบูรณ์)
Joe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.