Cuando necesitamos enviar correos desde Oracle APEX, tenemos la posibilidad de usar el paquete APEX_MAIL o el paquete UTL_MAIL de la base de datos para la creación del proceso de envío de correos, sin embargo, al momento de llamar una función para enviar correos usando APEX_MAIL desde un job o una sesión fuera de las sesiones de Oracle APEX, tendremos el siguiente error: ORA-20001: This procedure must be invoked from within an application session.
¿Porqué se da el error?
El paquete APEX_MAIL debe ser llamado utilizando una sesión de Oracle APEX, es por ello que si lo llamamos usando PL/SQL fuera de una sesión de APEX o desde un job de base de datos, la función no se ejecutará.
Nota: Si desea aprender a configurar un servidor de correos en Oracle APEX, puede seguir la siguiente documentación:
https://oracle-max.com/configurando-un-servidor-de-correos-en-una-instancia-oracle-apex-19-usando-postfix/
Solución:
Para llamar el proceso y usarlo desde un job o PL/SQL, basta con decirle a la función desde cuál workspace se deberá ejecutar, para ello debemos añadirle al proceso de envío de correo las siguientes líneas:
l_workspace_id := apex_util.find_security_group_id (p_workspace => p_id_workspace); apex_util.set_security_group_id (p_security_group_id => l_workspace_id);
De esta manera nuestro proceso para enviar correos se verá de la siguiente manera, se añadieron las líneas 11, 15 y 16:
create or replace FUNCTION "ENVIO_CORREO" ( p_to IN VARCHAR2, p_subj IN NVARCHAR2, p_body IN NVARCHAR2, p_id_workspace IN VARCHAR2 ) return VARCHAR2 is respuesta varchar2(20); l_workspace_id number := null; pragma autonomous_transaction; BEGIN l_workspace_id := apex_util.find_security_group_id (p_workspace => p_id_workspace); apex_util.set_security_group_id (p_security_group_id => l_workspace_id); apex_mail.send( p_from => 'oracle.max.consultor@gmail.com', p_to => p_to, p_subj => p_subj, p_body => p_body, p_body_html => p_body ); APEX_MAIL.PUSH_QUEUE('localhost',25); --Libera la cola de correos de Apex respuesta := 'Correo Enviado'; return respuesta; END;
¿Cómo conseguimos el id de nuestros workspaces?:
Para saber cuál id tiene cada workspace, se debe ejecutar el siguiente select:
select WORKSPACE_ID, WORKSPACE from apex_workspaces;

Ahora solo debemos elegir el id del workspace que queramos usar para el envío de correos y enviarle ese id por parámetro al proceso, en mi caso el id es: 2300461183311886
ENVIO_CORREO('oracle.max.consultor@gmail.com','Correo de prueba','Prueba de envío','2300461183311886');
De esta manera podemos llamar la función de envío de correos sin la necesidad de estar en una sesión de Oracle APEX.