Introduction
In my previous blog post (Oracle APEX Workflows Made Easy: Build & Automate your processes today), I introduced Oracle APEX Workflows and explained how to streamline business processes by automating task routing, approvals, and notifications with minimal coding, and setting up workflows using a simple, declarative approach.
While Workflows aren’t hard to use, they can feel a bit confusing at first, especially for those new ones. Figuring out how to connect states, handle transitions, and set up notifications can take some time to get used to. But once you practice, it all makes sense, and you’ll see how powerful they are.
Most blogs and official examples introduce new Workflow features using big, complex scenarios that show the full process from start to finish. But in this post, we’ll start with a simple example focusing on the basics, making it easier to follow and understand.
We’ll build a basic vacation request workflow. When an employee submits a request, the requester and their manager receive email notifications. The manager can then approve or reject the request, and the workflow will update accordingly. This will be a great starting point before moving to more advanced setups.
Let’s jump in!
Tables and Data structure in the application
First, we will briefly examine the custom tables that will store pertinent information for the company. Then I will discuss the internal Oracle APEX views for task and workflow management.
Custom Application Tables

Custom Application Tables
NVS_DEMO_ROLES: Different roles assigned to the employees.
The default content of this table:
ROLE_ID (PK) | ROLE_NAME | Comments |
---|---|---|
1 | USER | Normal user |
2 | APPROVER | Only this role is capable of approving/rejecting any holiday request (in our application) |
3 | ADMINISTRATOR | Business Administrator |
NVS_DEMO_STATUS: Possible status of the holiday requests.
The default content of this table:
STATUS_ID (PK) | STATUS_NAME | Comments |
---|---|---|
1 | PENDING | This status will be the first one assigned to any request when this is created |
2 | APPROVED | Status of a Request Approved by an “Approver” user. |
3 | REJECTED | Status of a Request Rejected by an “Approver” user. |
4 | UNASSIGNED | When a request has been released and a manager can claim it. |
NVS_DEMO_EMPLOYEES: Employees.
The default content of this table:
EMPLOYEE_ID (PK) | ROLE_ID | EMPLOYEE_NAME | Comments | |
---|---|---|---|---|
1 | 1 | Rotev | bafajej354@shouxs.com | Normal user |
2 | 2 | Receg | ribifih@minduls.com | Holidays Approver |
3 | 3 | Kisoy | kisoy78492@andinews.com | Administrator |
NVS_DEMO_VACATION_REQUESTS: Vacation requests.
This table will be empty at the beginning, and its definition is as follows:
Column name | Data type | Comments |
---|---|---|
REQUEST_ID | NUMBER | It’s the PK of the table. It’s generated automatically by a sequence. |
EMPLOYEE_ID | NUMBER | Id of the employee who requests a holiday (FK of NVS_DEMO_EMPLOYEES) |
APPROVED_BY_ID | NUMBER | Id of the employee who approves or rejects the holiday requested (FK of NVS_DEMO_EMPLOYEES) |
START_DATE | DATE | Starting day of the holiday requested |
END_DATE | DATE | End day of the holiday requested |
STATUS | NUMBER | Id of the status of the Holiday requested. (FK of NVS_DEMO_STATUS) (It can be NULLABLE) |
REQUEST_DATE | DATE | Date when the holiday is requested. (SYSDATE) |
APPROVAL_DATE | DATE | Date when the holiday is approved or rejected (SYSDATE) |
NVS_LOG
This table will be empty at the beginning. It’ll be useful to illustrate some steps/examples of the workflows, and its definition is as follows:
Column name | Data type | Comments |
---|---|---|
LOG_TEXT | VARCHAR2 | Dynamic text will be inserted depending on the step we are implementing. |
LOG_DATE | DATE | Date where the log information is stored. |
Internal APEX views and packages
APEX_TASKS
The APEX_TASKS view in Oracle APEX forms part of the platform’s task and approval functionality. It manages tasks in workflows and approval processes, enabling users to engage with assigned tasks, establish priorities, and monitor progress.
Some of the most important columns are:
- TASK_ID: Unique identifier for the task.
- WORKFLOW_ID: Unique identifier of the workflow associated with a specific task.
- TASK_DEF_NAME: Name of the task.
- APPLICATION_ID: ID of the application.
- APPLICATION_NAME: Name of the application.
- DETAIL_PK: Used to store relevant IDs of our custom tables to link TASKS to VACATION REQUESTS easily.
- STATE: Current state of the task (e.g., Completed, Assigned, Unassigned, Expired, …).
- DUE_ON: Date when the task expires.
- PRIORITY: Task priority.
- OUTCOME: Result of the approval (Rejected, Approved).
APEX_WORKFLOW package
This package provides APIs for managing Workflows in Oracle APEX. It is part of the APEX Workflow functionality. We’ll use the GET_WORKFLOWS function to retrieve a user’s workflows depending on the given context (See more at the APEX_WORKFLOW package reference).
Later on, we will see the implementation we have done with this function to retrieve related information between the Workflow, the Human Task, and the employee’s vacation request.
Defining the Use Case: Holiday Request Workflow
The following images represent the workflows we are going to implement:

Workflows definition
- Holiday request workflow
For steps 2, 3, 7a, and 7b, we’ll use an “Invoke Workflow” behaviour to illustrate and take advantage of this new feature of Version 24.2 of Oracle APEX. With the new “Invoke Workflow” activity, we’ll reuse a common workflow to break down tasks into manageable units.
This email sending could have been done directly with a “Send E-Mail” activity, but we’ll use the “Invoke Workflow” to understand its functionality.
- Secondary workflow
This is the Workflow invoked from steps 2, 3, 7a and 7b.
Step (Activity) | Brief description |
---|---|
1 | Set the status of the Vacation Request to PENDING and set the REQUEST_DATE from sysdate |
2 | Email the employee a notification of the holidays requested |
3 | Email the approver a notification of the holidays requested by the employee of step #2 |
4 | Call a Human task (“Approve/Reject Holiday Request”) so that the holiday’s request is approved or rejected by the “Approval user”. (We’ll see this definition later on) |
5 | Update the holiday request to APPROVED or REJECTED depending on the approver’s decision |
6 | It’s a “Switch” component (within the Workflows definition) that evaluates the variable defined (in our case, V_TASK_OUTCOME, as we’ll see later) to determine whether the holiday request has been approved or rejected |
7a | If the holiday request has been “APPROVED”, the app will email the employee to notify the approval |
7b | If the holiday request has been “REJECTED”, the app will email the employee to notify the rejection |
Create our Workflow
To create a new workflow:
- Select your application.
- Navigate to the Workflows page, and under Workflows and Automations, select Workflows.
- Create a new one.
- In the workflow tree, select Workflow.
- Under Identification, specify the workflow Name and the user-friendly workflow Title.
- Before defining each activity, we’ll create some parameters as inputs for the workflow. APEX passes parameters to the workflow instance when the workflow starts. A parameter applies to all versions of a workflow, and the value of a parameter does not change during the workflow runtime.
We’ll create four input parameters, which will be sent (set) from the Page that will call to our Workflow. These parameters are:
Parameter | Identification (Static ID) | Label | Parameter (Data Type) | Direction | Value | Comments |
---|---|---|---|---|---|---|
Employee ID | P_EMPLOYEE_ID | Employee ID | NUMBER | In | Switch Required: YES | The ID of the employee who requests the holiday |
Holiday Request ID | P_REQUEST_ID | Holiday Request ID | NUMBER | In | Switch Required: YES | The ID of the Holiday request is created from the corresponding page. |
Start Date | P_START_DATE | Start Date | VARCHAR2 | In | Switch Required: YES | Start date of the holidays |
End Date | P_END_DATE | End Date | VARCHAR2 | In | Switch Required: YES | The end date of the holidays |
- Now, we’ll create some variables, which will be essential for our workflow to behave correctly. These variables are inputs specific to the workflow version, and their value may change during the workflow runtime:
Variable | Identification (Static ID) | Label | Parameter (Data Type) | Value (Type) | Value (SQL Query) |
---|---|---|---|---|---|
Approval Task ID | V_APPROVAL_TASK_ID | Approval Task ID | NUMBER | null | |
Approver Email | V_APPROVER_EMAIL | Approver Email | VARCHAR2 |
SQL Query (return single value) |
|
Approver Name | V_APPROVER_NAME | Approver Name | VARCHAR2 |
SQL Query (return single value) |
Copy to Clipboard |
Approver ID | V_APPROVER_ID | Approver ID | NUMBER |
SQL Query (return single value) |
Copy to Clipboard |
Employee Email | V_EMPLOYEE_EMAIL | Employee Email | VARCHAR2 |
SQL Query (return single value) |
Copy to Clipboard |
Employee Name | V_EMPLOYEE_NAME | Employee Name | VARCHAR2 |
SQL Query (return single value) |
Copy to Clipboard |
Holidays Task Outcome | V_TASK_OUTCOME | Holidays Task Outcome | VARCHAR2 |
null |
Later on, we will see that the ID of the newly created task instance will be stored in the variable V_APPROVAL_TASK_ID, so we could use it if necessary.
Now, let’s start creating the different activities:
Activity 1 (Holiday Request to PENDING)
- Identification
- Name: Holiday Request to PENDING
- Type: Execute Code
- Source
- Location: Local Database
- Language: PL/SQL
- PL/SQL Code:
Activity 2 (Notify Employee)
Before continuing with this step, we will create the “secondary” workflow to send notification emails to employees and approvers:
- Repeat sections 1 to 4 of the “Create our Workflow”.
- Under Identification, specify the workflow Name “Send Email to Users” and the user-friendly workflow Title.
- As we did with the Main workflow, we’ll create some parameters as inputs for the workflow:
Parameter | Identification (Static ID) | Label | Parameter (Data Type) | Direction | Value | Comments |
---|---|---|---|---|---|---|
Email address | P_EMAIL_ADDRESS | Email address | VARCHAR2 | In | Switch Required: YES | The email address destination |
Email body | P_EMAIL_BODY | Email body | VARCHAR2 | In | Switch Required: YES | Message content |
Email subject | P_EMAIL_SUBJECT | Email subject | VARCHAR2 | In | Switch Required: YES | The subject of the email |
Now, let’s jump to define the 3 activities of this workflow:
1st activity: Registrer operation in Logs:
- Set the following properties:
- Identification
- Name: Holiday Request to PENDING
- Type: Execute Code
- Source
- Location: Local Database
- Language: PL/SQL
- PL/SQL Code:
- Identification
2nd activity: Send email:
- Select the option “Send E-Mail” and set the following properties to the activity:
- Identification
- Name: Send email
- Type: Send E-Mail
- Settings
- From: &APP_EMAIL.
- To: &P_EMAIL_ADDRESS.
- Subject: &P_EMAIL_SUBJECT.
- Body Plain Text: &P_EMAIL_BODY.
- Identification
3rd activity: Register another operation in Logs:
- Set the following properties:
- Identification
- Name: Register EMAIL sent successfully
- Type: Execute Code
- Source
- Location: Local Database
- Language: PL/SQL
- PL/SQL Code:
- Identification
Now, we can continue with the main workflow and create a new activity to “Invoke the workflow” developed previously:
Set the following properties:
- Identification
- Name: Notify Employee
- Type: Invoke Workflow
- Settings
- Definition: Send Email to Users.
- Wait for Completion: Set to ACTIVE this switch.
Set the following parameters that will be used by the workflow invoked:
Parameter | Value (Type) | Static Value |
---|---|---|
Email address | Static Value | &V_EMPLOYEE_EMAIL. |
Email body | Static Value | Dear &V_EMPLOYEE_NAME.,
Your request has been registered into the system and will be processed ASAP! 🙂 |
Email subject | Static Value | Holidays approval |
Activity 3 (Notify Approver)
This activity is similar to Activity 2, but sets the following properties:
- Identification
- Name: Notify Approver
- Type: Invoke Workflow
- Settings
- Definition: Send Email to Users.
- Wait for Completion: Set to ACTIVE this switch.
Set the following parameters that will be used by the workflow invoked:
Parameter | Value (Type) | Static Value |
---|---|---|
Email address | Static Value | &V_APPROVER_EMAIL. |
Email body | Static Value |
Dear &V_APPROVER_NAME., Review those holidays ASAP to plan the workload. Regards. |
Email subject | Static Value | Holidays approval |
Activity 4 (Approve/Reject Holiday Request)
This activity is a “Human Task”, so we must create a task before. To do that, we must go to Share Components \ Task Definitions, and “Create” a new one:
Task Definition
Name | Value | Comment |
---|---|---|
Name | Holidays Approval | |
Static ID | HOLIDAYS_APPROVAL | |
Settings | Value | Comment |
Type | Approval Task | |
Subject | Employee &EMPLOYEE_NAME. requested holidays between &START_DATE. – &END_DATE. | |
Action Source | SQL Query | |
Action | Copy to Clipboard |
Our REQUEST_ID (Table NVS_DEMO_VACATION_REQUESTS) will be linked to the internal :APEX$TASK_PK assigned to the created task.
(To see more details: Substitution Strings and Bind Variables for Tasks) |
Participants | |||
---|---|---|---|
Participant Type | Value Type | Value | Comment |
Potential Owner | SQL Query |
Copy to Clipboard |
We only assign as possible “Potential Owner” of the task, those users with APPROVER roles. |
Business Administrator | SQL Query | Copy to Clipboard |
We only assign as possible “Business Administrator” of the task, those users with ADMINISTRATOR roles. |
We save the changes and then, edit again the task definition to add 2 actions:
Name | Action type | On Event | Code |
---|---|---|---|
Claim request | Execute Code |
Claim |
Location: Local Database
Language: PL/SQL Copy to Clipboard |
Release request | Execute Code | Release | Location: Local Database
Language: PL/SQL Copy to Clipboard |
Now, we can set the properties to the activity 4 as follows:
- Identification
- Name: Approve/Reject Holiday Request.
- Type: Human Task – Create
- Settings
- Definition: Holidays Approval
- Initiator Can Complete: No
- Task ID Item: V_APPROVAL_TASK_ID (This variable or page item will hold the ID of the newly created task in the system).
- Details Primary Key Item: P_REQUEST_ID
This field is very important since it will point to the internal Primary key of the TASK created. The P_REQUEST_ID value will be stored in the DETAIL_PK column of the APEX_TASKS view. This way, we can obtain all the information we need regarding the task (State, Outcome, Actual Owner, Workflow ID, …):

NVS_DEMO_VACATION_REQUESTS.REQUEST_ID linked to APEX_TASKS.DETAIL_PK
- Outcome: V_TASK_OUTCOME
- This variable stores the task’s outcome, indicating whether it has been Approved or Rejected. It applies solely when the task is used as a Workflow activity.
- Advanced
- Static ID: ApproveRequest
Let’s continue creating the rest of the activities:
Activity 5 (Update Holidays Request)
Once the approver has approved or rejected the Holiday request, we are going to update the user’s request by creating the following activity:
- Identification
- Name: Update Holidays Request
- Type: Execute Code
- Source
- Location: Local Database.
- Language: PL/SQL
- PL/SQL Code:
Activity 6 (Switch Approved?)
Now we need to evaluate the variable V_TASK_OUTCOME to determine if the holiday request has been APPROVED or REJECTED by the owner (approver). To do this, create the following activity:
- Identification
- Name: Approved?
- Type: Switch
- Switch
- Type: Check Workflow Variable.
- Compare
- Compare Variable: V_TASK_OUTCOME
Activities 7a and 7b
Next, we’ll add two “Invoke Workflow” activities for both cases APPROVED and REJECTED to email the holiday requester to notify the approval or rejection of the request.
Both “Invoke Workflows” are very similar, but changing some values:
- Identification
- Name:
- Name (for Activity 7a): Approval Notification Email to Employee (Holidays APPROVED)
- Name (for Activity 7b): Rejection Notification Email to Employee (Holidays REJECTED)
- Type: Invoke Workflow
- Name:
- Settings
- Definition: Send Email to Users
- Wait for Completion: Set to ACTIVE this switch.
Set the following parameters that will be used by the workflow invoked:
Parameter | Value (Type) | Static Value (For Approval – Activity 7a) | Static Value (For Rejection – Activity 7b) |
---|---|---|---|
Email address | Static Value | &V_APPROVER_EMAIL. | &V_APPROVER_EMAIL. |
Email body | Static Value | Dear &V_EMPLOYEE_NAME., Congratulations! Your requested holidays from &P_START_DATE. to &P_END_DATE. was successfully approved. Have a good time! 😉 |
Dear &V_EMPLOYEE_NAME., Sorry, your requested holidays from &P_START_DATE. to &P_END_DATE. was rejected. Contact the HHRR department for more details. Regards. |
Email subject | Static Value | Holidays approved | Holidays rejected 🙁 |
To connect the Switch “Approved?” to Activities 7a and 7b, you must connect them by adding two operators:
- “is equal to” APPROVED, for the Approval Notification Email to Employee (Holidays APPROVED).
- “is not equal to” APPROVED, for the Rejection Notification Email to Employee (Holidays REJECTED).
Call to our Workflow from Holidays Requests form
The user logged in to the application will apply for holidays, and one row will be added to the NVS_DEMO_VACATION_REQUESTS table, without specifying any STATUS, so this column will be empty (NULL value) after the new request is saved.

Holidays Request
This action is carried out by running a “Form – Automatic Row Processing (DML)” process on our Form page when the user (Requester) submits the form.
After this process, we must “Start” the workflow created above so that all the Business Process is launched, this way, the Approval user can approve or reject the holiday requested by the user.

Start Workflow
You must set the corresponding items from the page to the parameters Employee ID, End Date, Holiday Request ID and Start Date of the Workflow.
At this point, we can create a report so that the Approver can review all the current requests and approve/reject them. This report makes a join with the following tables/views:
- NVS_DEMO_VACATION_REQUESTS
- APEX_TASKS
- APEX_WORKFLOW.GET_WORKFLOWS

Holidays Requests Report
The query of this report is:
As you can see, I’ve shown a lot of columns. Most of them may not make sense to show in a real case, but I wanted to illustrate a bit the amount of information available to manage.
I’ve created a couple of links in this report:
- Request ID: By clicking on this ID, the approver can access the details of the Holiday request so that they can approve or reject it:

Holiday Request Form
To Approve or Reject the request, we’ll create two processes on the Form page:
Approve:

Approval Task definition
Reject:

Reject Task definition
In both processes, the Task ID Item will point to the APEX task.
- Workflow ID: By clicking on this ID, the user can see the current state of the Holiday request in a diagram representation.
Following, we can see two diagrams. The left one means the Holiday request is still PENDING approval or rejection, and the right one reflects that the holiday request has already been APPROVED.

Different states of the same Workflow
Conclusion
With this practical vacation request example, we have covered the fundamental concepts of Workflows in Oracle APEX 24.2, from task creation to automating notifications and approvals. While Workflows may seem complex at first, APEX’s declarative approach makes it easy to define efficient and scalable processes with minimal development effort.
This simple workflow sets the foundation for implementing more advanced business process management scenarios. As you explore additional features, such as integrating external data or customizing notifications, you’ll see how Workflows can significantly enhance operational efficiency in your organization.
If you need assistance with implementing Workflows in APEX, feel free to contact us. We’re here to help you automate and optimize your processes!
Leave A Comment