Skip to Main Content

New

Centralized Master Validation Framework in Oracle APEX

Published on 30 Dec 2025 by CHATURVEDINIDHI26@GMAIL.COM


   Centralized Master Validation Framework in Oracle APEX  

Centralized Validation Framework in Oracle APEX

In enterprise Oracle APEX applications, validation plays a critical role in data quality and user experience. A professional validation framework should:

     
  • Show errors exactly below the related item
  •  
  • Display errors in the notification area
  •  
  • Allow users to click an error and jump to the field
  •  
  • Be reusable across multiple pages

This article explains how to build and use a centralized validation package in Oracle APEX that fulfils all these requirements.

1. Why Centralized Validation Is Required

Creating validations individually on every page leads to duplicate logic, inconsistent messages, and high maintenance cost.

A centralized PL/SQL package:

     
  • Ensures consistent validation rules
  •  
  • Reduces page-level complexity
  •  
  • Makes changes easier and safer
  •  
  • Improves long-term maintainability

2. Validation Package Specification

The package exposes two core functionalities:

     
  • Mandatory field validation (generic)
  •  
  • Identity validation (Email, Phone, PAN, GSTIN)

Package Specification

  
CREATE OR REPLACE PACKAGE validation\_master\_pkg AS

 PROCEDURE validate\_identity (  
   p\_email          IN VARCHAR2 DEFAULT NULL,  
   p\_phone          IN VARCHAR2 DEFAULT NULL,  
   p\_pan            IN VARCHAR2 DEFAULT NULL,  
   p\_gstin          IN VARCHAR2 DEFAULT NULL,  
   p\_email\_required IN BOOLEAN  DEFAULT FALSE,  
   p\_phone\_required IN BOOLEAN  DEFAULT FALSE,  
   p\_pan\_required   IN BOOLEAN  DEFAULT FALSE,  
   p\_gstin\_required IN BOOLEAN  DEFAULT FALSE  
 );

 PROCEDURE validate\_mandatory (  
   p\_value     IN VARCHAR2,  
   p\_item\_name IN VARCHAR2,  
   p\_label     IN VARCHAR2  
 );

END validation\_master\_pkg;  
/  

3. Validation Package Body (Complete Working Code)

Package Body

  
CREATE OR REPLACE PACKAGE BODY validation\_master\_pkg AS

 PROCEDURE validate\_identity (  
   p\_email          IN VARCHAR2 DEFAULT NULL,  
   p\_phone          IN VARCHAR2 DEFAULT NULL,  
   p\_pan            IN VARCHAR2 DEFAULT NULL,  
   p\_gstin          IN VARCHAR2 DEFAULT NULL,  
   p\_email\_required IN BOOLEAN  DEFAULT FALSE,  
   p\_phone\_required IN BOOLEAN  DEFAULT FALSE,  
   p\_pan\_required   IN BOOLEAN  DEFAULT FALSE,  
   p\_gstin\_required IN BOOLEAN  DEFAULT FALSE  
 ) IS  
 BEGIN

   IF p\_email\_required AND p\_email IS NULL THEN  
     apex\_error.add\_error(  
       p\_message          => '<a href="#P\_EMAIL">Email is required</a>',  
       p\_display\_location => apex\_error.c\_inline\_with\_field\_and\_notif,  
       p\_page\_item\_name   => 'P\_EMAIL'  
     );  
   ELSIF p\_email IS NOT NULL  
     AND NOT REGEXP\_LIKE(  
       p\_email,  
       '^\[A-Za-z0-9.\_%+-\]+@\[A-Za-z0-9.-\]+\\.\[A-Za-z\]{2,}$'  
     ) THEN  
     apex\_error.add\_error(  
       p\_message          => '<a href="#P\_EMAIL">Invalid Email format</a>',  
       p\_display\_location => apex\_error.c\_inline\_with\_field\_and\_notif,  
       p\_page\_item\_name   => 'P\_EMAIL'  
     );  
   END IF;

   IF p\_phone\_required AND p\_phone IS NULL THEN  
     apex\_error.add\_error(  
       p\_message          => '<a href="#P\_PHONE">Phone number is required</a>',  
       p\_display\_location => apex\_error.c\_inline\_with\_field\_and\_notif,  
       p\_page\_item\_name   => 'P\_PHONE'  
     );  
   ELSIF p\_phone IS NOT NULL  
     AND NOT REGEXP\_LIKE(p\_phone, '^\[6-9\]\[0-9\]{9}$') THEN  
     apex\_error.add\_error(  
       p\_message          => '<a href="#P\_PHONE">Invalid Phone Number</a>',  
       p\_display\_location => apex\_error.c\_inline\_with\_field\_and\_notif,  
       p\_page\_item\_name   => 'P\_PHONE'  
     );  
   END IF;

   IF p\_pan\_required AND p\_pan IS NULL THEN  
     apex\_error.add\_error(  
       p\_message          => '<a href="#P\_PAN">PAN is required</a>',  
       p\_display\_location => apex\_error.c\_inline\_with\_field\_and\_notif,  
       p\_page\_item\_name   => 'P\_PAN'  
     );  
   ELSIF p\_pan IS NOT NULL  
     AND NOT REGEXP\_LIKE(UPPER(p\_pan), '^\[A-Z\]{5}\[0-9\]{4}\[A-Z\]$') THEN  
     apex\_error.add\_error(  
       p\_message          => '<a href="#P\_PAN">Invalid PAN format</a>',  
       p\_display\_location => apex\_error.c\_inline\_with\_field\_and\_notif,  
       p\_page\_item\_name   => 'P\_PAN'  
     );  
   END IF;

   IF p\_gstin\_required AND p\_gstin IS NULL THEN  
     apex\_error.add\_error(  
       p\_message          => '<a href="#P\_GSTIN">GSTIN is required</a>',  
       p\_display\_location => apex\_error.c\_inline\_with\_field\_and\_notif,  
       p\_page\_item\_name   => 'P\_GSTIN'  
     );  
   ELSIF p\_gstin IS NOT NULL  
     AND NOT REGEXP\_LIKE(  
       UPPER(p\_gstin),  
       '^\[0-9\]{2}\[A-Z\]{5}\[0-9\]{4}\[A-Z\]\[1-9A-Z\]Z\[0-9A-Z\]$'  
     ) THEN  
     apex\_error.add\_error(  
       p\_message          => '<a href="#P\_GSTIN">Invalid GSTIN format</a>',  
       p\_display\_location => apex\_error.c\_inline\_with\_field\_and\_notif,  
       p\_page\_item\_name   => 'P\_GSTIN'  
     );  
   END IF;

 END validate\_identity;

 PROCEDURE validate\_mandatory (  
   p\_value     IN VARCHAR2,  
   p\_item\_name IN VARCHAR2,  
   p\_label     IN VARCHAR2  
 ) IS  
 BEGIN  
   IF p\_value IS NULL THEN  
     apex\_error.add\_error(  
       p\_message          => '<a href="#'||p\_item\_name||'">'||p\_label||' is required</a>',  
       p\_display\_location => apex\_error.c\_inline\_with\_field\_and\_notif,  
       p\_page\_item\_name   => p\_item\_name  
     );  
   END IF;  
 END validate\_mandatory;

END validation\_master\_pkg;  
/  

4. How to Use the Package on an APEX Page

All validations are triggered from a single After Submit page process.

Page Process Code

  
BEGIN  
 validation\_master\_pkg.validate\_mandatory(  
   p\_value     => :P9999\_COMPANY\_CODE,  
   p\_item\_name => 'P9999\_COMPANY\_CODE',  
   p\_label     => 'Company Code'  
 );

 validation\_master\_pkg.validate\_mandatory(  
   p\_value     => :P9999\_USERNAME,  
   p\_item\_name => 'P9999\_USERNAME',  
   p\_label     => 'Username'  
 );

 validation\_master\_pkg.validate\_mandatory(  
   p\_value     => :P9999\_PASSWORD,  
   p\_item\_name => 'P9999\_PASSWORD',  
   p\_label     => 'Password'  
 );  
END;  

5. User Experience Outcome

     
  • Errors appear directly below the related field
  •  
  • Errors are also visible in the notification area
  •  
  • Clicking an error focuses the corresponding item
  •  
  • Errors disappear automatically after valid input

6. Conclusion

This centralized validation framework provides a clean, reusable, and enterprise-ready approach to validation in Oracle APEX applications.

It improves maintainability, enforces consistency, and delivers a superior user experience without cluttering page-level logic.

📝 Nidhi Blog

Sharing knowledge, tutorials, and stories about Oracle APEX, development, and digital growth.

📧 Contact

Email: support@nidhispace.com

Follow us on:
linkedin | YouTube


© Nidhi Blog. All rights reserved.