DROP FUNCTION secara otomatis saat DROP TABLE di POSTGRESQL 11.7

Saya mencoba, entah bagaimana, memicu penurunan fungsi otomatis ketika sebuah tabel dihilangkan dan saya tidak tahu bagaimana melakukannya.

TL;DR: Apakah ada cara untuk memicu penurunan fungsi ketika tabel tertentu dihilangkan? (POSTGRESQL 11.7)


Penjelasan mendetail

Saya akan mencoba menjelaskan masalah saya menggunakan kasus penggunaan yang disederhanakan dengan nama tiruan.

  1. Saya memiliki tiga tabel: sensor1, sensor2 dan sumSensors;

  2. FUNCTION (sumdata) dibuat untuk INSERT data pada tabel sumSensors. Di dalam fungsi ini saya akan mengambil data dari tabel sensor1 dan sensor2 dan memasukkan jumlahnya ke dalam tabel sumSensors;

  3. Pemicu dibuat untuk setiap tabel sensor seperti ini:

    BUAT PEMICU trig1 SETELAH MASUKKAN PADA sensor1 UNTUK SETIAP BARIS JALANKAN FUNGSI sumdata();

  4. Sekarang, ketika baris baru disisipkan pada tabel sensor1 ATAU sensor2, fungsinya sumdata akan dieksekusi dan memasukkan jumlah nilai terakhir dari keduanya pada tabel sumSensors

Jika saya ingin DROP FUNTION sumdata CASCADE;, pemicunya akan otomatis dihapus dari tabel sensor1 dan sensor2. Sampai sekarang semuanya baik-baik saja! Tapi bukan itu yang saya inginkan.


Masalah saya adalah:

T: Bagaimana jika saya DROP TABLE sumSensors CASCADE;? Apa yang akan terjadi pada fungsi yang dimaksudkan untuk disisipkan pada tabel ini?

A: Seperti yang diharapkan, karena tidak ada hubungan antara tabel sumSensors dan fungsi sumdata, fungsi tersebut tidak akan dihapus (masih ada)! Hal yang sama terjadi pada pemicu yang menggunakannya (masih ada). Artinya ketika baris baru disisipkan pada tabel sensor, fungsi sumdata akan dieksekusi dan rusak, sehingga menyebabkan kegagalan (bahkan INSERT yang memicu eksekusi fungsi tidak akan benar-benar disisipkan).

Apakah ada cara untuk memicu penurunan fungsi ketika tabel tertentu dihilangkan?

Terima kasih sebelumnya


person NelsonC    schedule 15.04.2020    source sumber


Jawaban (1)


Tidak ada pelacakan ketergantungan untuk fungsi di PostgreSQL (mulai versi 12).

Anda dapat menggunakan pemicu peristiwa untuk mempertahankan dependensinya sendiri.

Contoh selengkapnya berikut ini.

Informasi lebih lanjut: dokumentasi fitur pemicu peristiwa, fungsi dukungan.

BEGIN;

CREATE TABLE _testtable ( id serial primary key, payload text );

INSERT INTO _testtable (payload) VALUES ('Test data');

CREATE FUNCTION _testfunc(integer) RETURNS integer
LANGUAGE SQL AS $$ SELECT $1 + count(*)::integer FROM _testtable; $$;

SELECT _testfunc(100);

CREATE FUNCTION trg_drop_dependent_functions()
RETURNS event_trigger 
LANGUAGE plpgsql AS $$
DECLARE
    _dropped record;
BEGIN
    FOR _dropped IN
        SELECT schema_name, object_name
        FROM pg_catalog.pg_event_trigger_dropped_objects()
        WHERE object_type = 'table'
    LOOP
        IF _dropped.schema_name = 'public' AND _dropped.object_name = '_testtable' THEN
            EXECUTE 'DROP FUNCTION IF EXISTS _testfunc(integer)';
        END IF;
    END LOOP;
END;
$$;

CREATE EVENT TRIGGER trg_drop_dependent_functions ON sql_drop
EXECUTE FUNCTION trg_drop_dependent_functions();

DROP TABLE _testtable;

ROLLBACK;
person filiprem    schedule 16.04.2020
comment
Luar biasa, itu menyelesaikan masalah saya. Terima kasih banyak @filiprem, sejujurnya! - person NelsonC; 16.04.2020