PL/SQL operating system call I'm trying to lauch a system call from Oracle Apex, directly or indirectly. It seems to only accept PL/SQL procedures, so I iterated towards this:

begin

  :p3_request_id := sequence.nextval;

  insert into request (id, user, target, operator)
  values (:p3_request_id, :p3_user_id, :p3_target_id, :app_user);

  -- part that doesn't work:
  host('/home/oracle/scripts/dbq/fork.py ' || :p3_request_id);

end;


Unfortunately:

ORA-06550: line 9, column 3: PLS-00201: identifier 'HOST' must be declared
ORA-06550: line 9, column 3: PL/SQL: Statement ignored


Upon further research, I've come to discover that for this to work I must declare this procedure and run a background daemon script... This seems rather convoluted and fragile (one more process to worry about, monitor, etc.). Is there any other way to launch a system process?
Technically, you could create a Java stored procedure or a dbms_scheduler external job that you invoke from your APEX process.  Doing so, however, would almost certainly be a mistake.

First, you'd have the issue of concurrency.  If you did invoke your Python script from within your APEX process, for example, that process would start immediately and would not wait for your transaction to complete.  Assuming you made a synchronous call, when your script ran and accessed the database, the row you inserted into the request table would not be visible because your transaction would not have committed yet.  If you made an asynchronous call, the row might or might not be visible because the transaction may or may not have been committed yet.  Additionally, your APEX process might encounter an error later on in some other page process that would cause the transaction to be rolled back which would also cause the script not to be able to see the row.  Breaking up the transaction so that you commit before calling your script would ensure that the row was visible but would probably create a number of other data consistency and data quality issues in your application.

It would almost always make more sense to implement some sort of queuing mechanism instead.  Whether you use Oracle AQ or whether you just write into the request table and have separate job that reads from the table and runs your Python code is less important than the existence of some sort of queue.  That decouples the two pieces of code-- the code that writes requests can have proper transactional boundaries while the code that reads requests doesn't have to worry about trying to process requests that haven't been committed yet or that may have been rolled back.  That is not convoluted and fragile-- that is a much more robust approach.  Yes, you potentially need to monitor the job that is processing requests (you may be able to rely on existing monitoring of the Oracle alert log or of the log of whatever scheduling tool you already use).  But that's generally much easier than trying to debug why some requests didn't get processed or why the external script keeps failing to find rows.