Det skulle i allmänhet vara en dålig idé att försöka skicka ett e-postmeddelande i en trigger.
- Om systemet inte kan skicka e-postmeddelandet (till exempel på grund av att SMTP-servern är tillfälligt nere), kommer utlösaren att misslyckas och utlösningssatsen misslyckas och rullas tillbaka. Det är mycket sällsynt att du verkligen vill stoppa den underliggande transaktionen bara för att du inte kunde skicka ett e-postmeddelande.
- Att skicka ett e-postmeddelande är inte transaktionsfritt. Det betyder att du kommer att skicka e-postmeddelanden för ändringar som aldrig blir genomförda. Och du kommer att skicka e-post flera gånger eftersom Oracle väljer att återställa och köra om hela eller delar av en
INSERT
uttalande för att bibehålla skrivkonsistens.
Du kommer generellt sett att vara mycket bättre betjänad av ett databasjobb som med jämna mellanrum letar efter rader som måste ha ett e-postmeddelande skickat, skickar e-postmeddelanden och sedan uppdaterar tabellen. Du kan använda antingen den äldre DBMS_JOB
paketet eller det nyare och mer sofistikerade DBMS_SCHEDULER
paket. Något i stil med
CREATE OR REPLACE PROCEDURE process_issues
AS
BEGIN
FOR i IN (SELECT *
FROM your_table_name
WHERE issue_added = 1
AND email_sent = 0)
LOOP
send_email( i.issue_id );
UPDATE your_table_name
SET email_sent = 1
WHERE issue_id = i.issue_id;
END LOOP;
END;
som sedan är schemalagd att köras, säg, var 5:e minut (du kan också använda DBMS_SCHEDULER
paket)
DECLARE
l_jobno PLS_INTEGER:
BEGIN
dbms_job.submit( l_jobno,
'BEGIN process_issues; END;',
sysdate + interval '5' minute,
'sysdate + interval ''5'' minute' );
commit;
END;
Du kan använda UTL_MAIL-paketet
för att implementera send_email
procedur. Du behöver förmodligen bara ringa UTL_MAIL.SEND
med lämpliga parametrar (förutsatt att du har konfigurerat din SMTP_OUT_SERVER
parametern och din användare har fått lämplig åtkomst till UTL_MAIL
paket och till en ACL som låter dig kommunicera med den SMTP-servern).