У меня есть приложение Apex, в котором мне нужно отправлять уведомление по электронной почте всем сотрудникам 5 числа каждого месяца. Так что просто ради тестирования я пытаюсь отправлять почту каждые 30 секунд. Я создал планировщик заданий для процедуры, чтобы сделать то же самое. Вот код PLSQL для этого.

create or replace procedure send_notification_employee as
cursor c_employee is select * from EMPLOYEE;
r_employee c_employee%ROWTYPE;
begin
    open c_employee;
    loop
        fetch c_employee into r_employee;
        exit when c_employee%NOTFOUND;
        APEX_MAIL.SEND(
        p_to        => r_employee.EMPLOYEE_EMAIL,
        p_from      => 'abc@gmail.com',
        p_subj      => 'Reminder : Meeting',
        p_body      => '<Some random message>');
    end loop;
    close c_employee;
end;
/

begin    
DBMS_SCHEDULER.CREATE_JOB(
    job_name => 'send_notification',
    job_type => 'stored_procedure',
    job_action => 'send_notification_employee',
    start_date => NULL,
    repeat_interval => 'FREQ=SECONDLY;INTERVAL=30',
    end_date => NULL);
end;
/

begin
DBMS_SCHEDULER.enable(
    name => 'send_notification');
end;
/

Думаю, код правильный. Единственное, в чем я не уверен, - это как запустить этот планировщик в приложении apex oracle. Должен ли я просто выполнять эти операторы в командах SQL или есть другой способ сделать это?

Также я пытался выполнить те же инструкции на вкладке «Команды SQL», но я не получаю писем как таковых. Есть ли проблема с моим кодом? Заранее спасибо.

2
Simar Singh 14 Мар 2018 в 10:38

2 ответа

Лучший ответ

Вам необходимо установить группу безопасности, если вы отправляете почту из базы данных, а не напрямую из APEX. Вы также должны использовать push_queue в конце процедуры, чтобы очистить таблицу от неотправленных писем.

create or replace procedure send_notification_employee as
cursor c_employee is select * from EMPLOYEE;
r_employee c_employee%ROWTYPE;
l_workspace number;
begin
    -- Get a valid workspace ID
    SELECT MAX(workspace_id) INTO l_workspace FROM apex_applications WHERE application_id = <valid application_id>;

    -- Set Workspace
    wwv_flow_api.set_security_group_id(l_workspace);

    open c_employee;
    loop
        fetch c_employee into r_employee;
        exit when c_employee%NOTFOUND;

        APEX_MAIL.SEND(
        p_to        => r_employee.EMPLOYEE_EMAIL,
        p_from      => 'abc@gmail.com',
        p_subj      => 'Reminder : Meeting',
        p_body      => '<Some random message>');
    end loop;
    close c_employee;

    -- Finally force send
    APEX_MAIL.PUSH_QUEUE;
end;

Re. как выполнить - зависит от того, что вы хотите сделать. Если вы просто хотите запускать его 5-го числа каждого месяца, просто установите для этого запланированное задание в базе данных, как указано выше. Если вы хотите работать на специальной основе, просто создайте задание в APEX после процесса отправки, который вызывает процедуру и выполняется через базу данных.

Кстати, если вы планируете создать много почтовых процедур, вы можете захотеть создать вспомогательную процедуру для получения идентификатора рабочей области / отправки почты и просто вызывать ее из других ваших почтовых процедур.

1
RLOG 14 Мар 2018 в 12:22

Эти запросы могут быть полезны (чтобы проверить правильность настройки):

Проверьте, установлен ли util_smtp:

select * from dba_objects where object_name like 'UTL_SMTP%'

Проверить привилегии:

select grantee , table_name , privilege from dba_tab_privs where table_name = 'UTL_SMTP'

Проверить открытые сетевые узлы, порты:

select acl , host , lower_port , upper_port from DBA_NETWORK_ACLS;

Проверьте сетевые привилегии:

select acl , principal , privilege , is_grant from  DBA_NETWORK_ACL_PRIVILEGES
0
Plirkee 14 Мар 2018 в 08:30