#

Διαγραφή εγγραφής 5 λεπτά μετά την εισαγωγή της

Για να διαγραφεί αυτόματα μια εγγραφή ακριβώς 5 λεπτά μετά την εισαγωγή της (και όχι απλώς να «καθαρίζετε» περιοδικά τις παλιές εγγραφές), μπορείτε να δημιουργήσετε ένα trigger που, σε κάθε νέα εγγραφή, θα φτιάχνει ένα scheduler job το οποίο θα εκτελεστεί 5 λεπτά αργότερα για να τη διαγράψει.

Προσοχή: Αυτή η μέθοδος δεν ενδείκνυται αν το σύστημα δέχεται πολλά inserts, διότι θα δημιουργούνται πάρα πολλά scheduler jobs. Σε τέτοια περίπτωση, είναι συνήθως καλύτερο να έχετε ένα job που τρέχει ανά μικρό διάστημα (π.χ. 1 λεπτό) και διαγράφει ό,τι έχει συμπληρώσει 5 λεπτά. Ωστόσο, αν επιμένετε να διαγράφεται «ακριβώς» στα 5 λεπτά, ακολουθεί η λύση με trigger.

Παράδειγμα με Trigger & Scheduler Job

Έστω ότι:

  • Ο πίνακας ονομάζεται MY_TABLE.

  • Έχει ένα primary key πεδίο, π.χ. ID.

  • Έχει και στήλη DATE_TIME (τύπου TIMESTAMP) που γεμίζει από SYSTIMESTAMP.

Μπορείτε να φτιάξετε ένα trigger ως εξής:

sql
 
CREATE OR REPLACE TRIGGER my_table_delete_in_5 AFTER INSERT ON my_table FOR EACH ROW DECLARE  l_job_name VARCHAR2(128); BEGIN  -- Δημιουργούμε ένα μοναδικό όνομα job για την κάθε εγγραφή,  -- π.χ. "MY_TABLE_DEL_20230403123000000_12345"  l_job_name := 'MY_TABLE_DEL_'               || TO_CHAR(SYSTIMESTAMP, 'YYYYMMDDHH24MISSFF3')               || '_'               || :NEW.id;  -- αν το ID είναι αριθμός  -- Δημιουργούμε το scheduler job  DBMS_SCHEDULER.CREATE_JOB(    job_name        => l_job_name,    job_type        => 'PLSQL_BLOCK',    job_action      => 'BEGIN ' ||                       '  DELETE FROM my_table WHERE id = ' || :NEW.id || '; ' ||                       'END;',    -- ακριβώς 5 λεπτά μετά το insertion    start_date      => SYSTIMESTAMP + INTERVAL '5' MINUTE,    enabled         => TRUE,    auto_drop       => TRUE  ); END; / 

Τι κάνει αυτό το trigger:

  1. Μετά από κάθε INSERT σε MY_TABLE, δημιουργείται δυναμικά ένα νέο Scheduled Job (με διακριτικό όνομα).

  2. Το job έχει ως job_action ένα απλό μπλοκ PLSQL που διαγράφει την εγγραφή της οποίας το ID ταυτίζεται με το :NEW.id.

  3. Το job έχει start_date = SYSTIMESTAMP + 5 λεπτά, άρα θα εκτελεστεί ακριβώς μετά από 5 λεπτά.

  4. Μόλις εκτελεστεί, θα διαγράψει την εγγραφή και στη συνέχεια, επειδή έχουμε auto_drop => TRUE, το ίδιο το job θα διαγραφεί αυτόματα από τον scheduler.

Προβληματισμοί/Σημειώσεις:

  • Πολλά inserts: Αν η εφαρμογή κάνει εκατοντάδες ή χιλιάδες inserts το λεπτό, αυτό σημαίνει πως θα δημιουργούνται ισάριθμα jobs, κάτι που μπορεί να προκαλέσει επιβάρυνση στη βάση. Σε τέτοιες περιπτώσεις, είναι συνήθως πιο αποδοτικό να υπάρχει μόνο ένα προγραμματισμένο job (π.χ. κάθε λεπτό) που διαγράφει όσες εγγραφές έκλεισαν 5 λεπτά από την καταχώρισή τους.

  • Παραχώρηση δικαιωμάτων: Χρειάζεστε τα κατάλληλα δικαιώματα για να καλέσετε DBMS_SCHEDULER μέσα σε trigger. Ελέγξτε αν ο χρήστης/σχέδιο (schema) έχει το κατάλληλο privilege (π.χ. EXECUTE στο DBMS_SCHEDULER, CREATE JOB privileges, κ.λπ.).

  • Πολυπλοκότητα: Εάν μια εγγραφή διαγραφεί πριν εκτελεστεί το job (π.χ. κάποιος την διέγραψε χειροκίνητα), τότε το job δεν θα βρει τίποτα να διαγράψει. Αυτό δεν είναι πρόβλημα—απλώς δεν θα συμβεί κάποια διαγραφή.

  • ID τύπου varchar: Αν το ID είναι string, θα χρειαστεί να προσθέσετε quotes στο job_action, π.χ.

    sql
     
    job_action => 'BEGIN DELETE FROM my_table WHERE id = ''' || :NEW.id || '''; END;' 

    ώστε να είναι έγκυρη η SQL εντολή.

Με αυτή τη ρύθμιση, η εγγραφή θα σβήνεται ακριβώς 5 λεπτά μετά την εισαγωγή της.