Oracle APEX Page Processes: Doing the Work

A guide to Oracle APEX page processes, covering execution points, Execute Code, Invoke API, file downloads, and background execution chains.

Items gather values and validations check them. Processes are where an application actually does something: saving a form, calling a PL/SQL API, sending a file to the browser, or queuing a long job so nobody has to sit watching a spinner.

You have already used processes without writing any, because every form and editable grid wizard generates them. This guide covers processes in general, then builds four worth knowing: bulk approval from a report's selected rows, an API call with no code at all, a file download, and a background execution chain.

Where Processes Run

Every process has a point in the page's life, and choosing it correctly solves problems that otherwise look like bugs.

PointRuns
New SessionOnce, when a session is created
Before HeaderBefore anything is sent to the browser, so it can still redirect or send a file instead of the page
After Header through After FooterAt the matching stage of rendering
After SubmitOn submit, before validations
ProcessingAfter validations succeed. The default, and where most processes belong
Ajax CallbackOnly when JavaScript on the page calls the process by name
The processing tree of a page in Oracle APEX Page Designer
The Processing tab shows submit-time work in execution order.

Within a point, processes run in sequence order, and most carry a server-side condition, usually When Button Pressed, so a process only fires for the button that means it. A few settings apply to all of them: Run Process decides between once per page visit and once per session, Success Message appears afterwards and can contain substitutions, and Error Message replaces the database's own wording when something fails.

One rule about transactions is worth stating plainly. APEX commits when page processing finishes without error, and rolls back when a process raises one. Do not commit inside your own processes unless the work genuinely must survive a later failure, because a stray commit turns an all-or-nothing save into a half-finished one.

Process Types

TypeDoes
Execute CodeRuns PL/SQL, or JavaScript in the database
Invoke APICalls a PL/SQL procedure or function, or a REST source operation
DownloadSends one file, or several as a ZIP, to the browser
Execution ChainGroups processes, optionally running them in the background
Form and Grid row processingFetches and saves rows for form regions and editable grids
Close Dialog, Clear Session State, Reset Pagination, User PreferencesDeclarative housekeeping
Send E-Mail, Send Push NotificationMessaging, queued and sent in the background
Data Loading, Print ReportLoads files into tables, prints regions and report queries
Human Task, Workflow, Generate Text With AIApprovals, workflows, and generative AI

Execute Code: Acting on Selected Rows

Execute Code is the general-purpose type for when nothing declarative fits. A good demonstration is turning an interactive report's row selection into a bulk action, because it involves three pieces that must line up.

Pointing a row selector at a page item in Oracle APEX
The row selector writes selected keys into a page item.

First the selection has to reach the server. Create a hidden item and set the row selector column's Current Selection Page Item to it. As the user ticks rows, the keys are written into that item separated by colons.

Switching off Value Protected on a hidden item in Oracle APEX
An item the browser is meant to change cannot be value protected.

Then switch off Value Protected on that item, and understand why. Hidden items are protected by default: APEX checksums the value it rendered and rejects a submit where the value changed, which is what stops somebody editing a primary key in the browser. An item the page is designed to change client-side must have that protection off, which is precisely why the session state protection violation error appears if you forget.

Switching it off shifts responsibility to you. The value now arrives untrusted, so the code that consumes it must validate rather than assume.

An Execute Code process approving selected records in Oracle APEX
An Execute Code process, conditional on the button pressed.
for r in (
    select column_value as order_id
      from apex_string.split(:P8_SELECTED_ORDERS, ':')
) loop
    orb_sales.approve_order(p_order_id => r.order_id);
end loop;

apex_string.split turns the colon-separated list into rows, and each order goes through a package procedure that checks the order's current status and refuses anything that is not awaiting approval. That check is what makes the unprotected item safe: even a forged list cannot approve something that is not eligible.

Confirming a bulk approval in an Oracle APEX report
Requires Confirmation on the button, before anything runs.
A success message after approving selected records in Oracle APEX
The success message, and the rows gone from the pending list.

Execute Code in JavaScript

Set the language to JavaScript MLE and the same process runs JavaScript inside the database on Oracle AI Database 26ai. An apex object provides access to session state through apex.env and to SQL through apex.conn, with query rows returned as objects whose properties are the uppercase column names.

const ids = (apex.env.P8_SELECTED_ORDERS || '').split(':').filter(Boolean);
for (const id of ids) {
    apex.conn.execute(
        'begin orb_sales.approve_order(p_order_id => :id); end;',
        { id: Number(id) });
}

This suits teams who know JavaScript better than PL/SQL, and work JavaScript libraries do well, such as text parsing. For data work inside the database, PL/SQL remains the more natural fit.

Execute Code for Grid Rows

Give an Execute Code process an Editable Region and it runs once per changed row of that grid, with column names available as bind variables. A special bind variable tells you whether the row was created, updated, or deleted, which is how you replace automatic row processing with your own logic when a grid must save through an API.

Invoke API: Calling a Procedure Without Code

An Invoke API process calling a PL/SQL package procedure in Oracle APEX
Choose a package and procedure, and APEX does the rest.

When a process does nothing but call a procedure, Invoke API calls it declaratively. Choose the package and procedure, and APEX lists the parameters as child nodes.

Mapping a procedure parameter to a page item in Oracle APEX
Parameters map to items by name, ignoring prefixes.

APEX matches parameters to page items by name, ignoring the usual prefixes, so a parameter named for an order ID finds the matching item without help. Where names differ, a parameter's value can come from an item, a static value, a query, an expression, a function body, or a preference, and a function's result can be stored into an item.

Sequence matters more here than anywhere else on the page. Put the API call after the form's save and after the grid's save, and the procedure sees the values the user is looking at. Put it first and it works on yesterday's data.

A Submit Order button on an Oracle APEX form
A conditional button, shown only for new records.
A success message after invoking an API in Oracle APEX
The branch carries the success message to the next page.

Invoke API is more than a shortcut for lazy typing. The process records which procedure it calls and with what, so it reads clearly in Page Designer and shows up in dependency reports, where the same call buried in a code block would not. Set the type to REST Source instead and the same process calls a remote operation.

Download: Sending a File Instead of a Page

A button redirecting to its own page with a request in Oracle APEX
The button redirects to the same page, setting a request.

A Download process sends a file rather than a page, which means it must run Before Header, before any markup has gone out. That in turn means it cannot be triggered by a submit. Instead, a button redirects to the same page with a request set, and the process runs when it sees that request.

A Download process configuration in Oracle APEX
The query returns content, filename, and MIME type, in that order.
-- Columns: file content, file name, MIME type
select product_image, image_filename, image_mime_type
  from orb_products
 where product_id = :P12_PRODUCT_ID

Column order is the contract: content first, then filename, then MIME type. Give the process a low sequence so it runs before the form initializes, and condition it on the request.

A download button in an Oracle APEX drawer page
The file downloads and the page stays exactly as it was.

View File As decides between saving the file and opening it in the browser, which matters for PDFs. Switch on Multiple Files and a query returning several rows is packed into a ZIP. For files listed in a report, a Download BLOB column needs no process at all.

Execution Chains and Background Work

An execution chain configured to run in the background in Oracle APEX
Run in Background returns the page immediately.

An Execution Chain is a process containing other processes, sharing one condition. Its real purpose is background execution: APEX queues the chain, returns the page at once, and the database works through it in a separate session. A recalculation that takes two minutes stops being a two-minute stare at a spinner.

An execution chain and its child process in Page Designer
Child processes sit beneath the chain in the tree.
declare
    l_total pls_integer;
    l_done  pls_integer := 0;
begin
    select count(*) into l_total from orb_orders;
    for o in (select order_id from orb_orders) loop
        orb_sales.recalc_order_total(p_order_id => o.order_id);
        l_done := l_done + 1;
        if mod(l_done, 100) = 0 or l_done = l_total then
            apex_background_process.set_progress(
                p_totalwork => l_total,
                p_sofar     => l_done);
        end if;
    end loop;
end;
A success message confirming background work was queued in Oracle APEX
The message appears while the work is still running.

Reporting progress every hundred rows rather than every row keeps the bookkeeping cheap while still giving the user something to watch. A dictionary view exposes every execution with its status and progress, so a region on the page can poll it.

The settings around background execution are mostly about not letting users hurt themselves. Serialize runs executions one after another instead of in parallel, which a job touching every row certainly needs. Executions Limit caps how many a session may queue. Return ID into Item lets the page follow a specific run, Context Value Item identifies what a run is working on, and Submit Immediately queues the work outside the current transaction so it survives a rollback.

One thing about background execution surprises everybody once: APEX clones the session to run the chain. The background processes see session state as it was when the chain was queued, and any item values they change never come back. Write results to tables and read them from there, because setting an item in a background process is writing to a copy that is about to be discarded.

The Declarative Helpers

The remaining types save you from writing code for common jobs. Close Dialog shuts a modal page and returns values to its parent. Clear Session State empties items, pages, or the whole session declaratively. Reset Pagination sends reports back to page one, and User Preferences stores settings that outlive the session. Send E-Mail and Send Push Notification handle messaging, queued by default. Data Loading imports a CSV, spreadsheet, XML, or JSON file into a table, and Print Report produces PDFs from a region or report query. Human Task and Workflow drive approvals, and Generate Text With AI sends a prompt to a configured AI service and stores the answer in an item.

Conclusion

Processes are where an APEX page stops describing data and starts changing it, and nearly everything about them comes down to two choices: the point at which they run and the condition that fires them. Execute Code covers whatever has no declarative equivalent, in PL/SQL or in-database JavaScript, and it is what turns a row selection into a bulk action, provided you switch off value protection on the item carrying the selection and then treat that value as untrusted in the code that consumes it. Invoke API calls a procedure with no code at all and stays visible to dependency reports, as long as its sequence puts it after the saves whose data it depends on. Download sends a file instead of a page, which is why it runs Before Header and is triggered by a request rather than a submit. Execution chains group work and, run in the background, hand the page straight back to the user, reporting progress through a dictionary view while remembering that the cloned session's item changes never return. Let APEX own the commit, put the business rules in packages the processes call, and each page ends up with a handful of small, readable processes instead of one enormous block of code.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE and software veteran with 25+ years of experience, passionate about AI and IT innovation.

guest

0 Comments
Oldest
Newest Most Voted
00