How to safely customize Oracle RMS without breaking the upgrade path — because every base modification is a debt you'll pay at upgrade time.
Why the Extension Model Exists
Every retailer has unique business requirements that Oracle's base RMS product doesn't cover. A fashion retailer needs fabric composition tracking. A grocery retailer needs shelf-life management. An electronics retailer needs warranty period tracking.
The Extension Model provides a structured, upgrade-safe way to add this custom functionality without modifying Oracle's base code.
The Old Way: Base Modifications
Before the Extension Model, retailers customized RMS by directly modifying Oracle's base code:
THE BAD OLD DAYS:
1. ALTER TABLE item_master ADD fabric_type VARCHAR2(50); ❌
2. Modified base PL/SQL package: ITEM_ATTRIB_SQL ❌
3. Modified base Oracle Form: fm_item.fmb ❌
4. Added custom trigger on ITEM_MASTER: AFTER INSERT ❌
Each of these modifications created technical debt that accumulated with every Oracle patch and upgrade:
- Oracle's patch tries to ALTER the same table → conflict
- Oracle's patch replaces the PL/SQL package → your customizations are overwritten
- Oracle's patch updates the Form module → merge conflict in binary files
- Oracle's patch adds a new trigger → trigger execution order conflicts
The result: upgrades that should take 3 months took 18 months. Some retailers were so deeply customized that they could never upgrade — they were permanently stuck on v14.
The Extension Schema Pattern
The Extension Model separates custom code into a dedicated extension schema that Oracle never touches:
┌──────────────────────┐ ┌──────────────────────┐
│ RMS BASE SCHEMA │ │ EXTENSION SCHEMA │
│ (Oracle-owned) │ │ (Retailer-owned) │
│ │ │ │
│ ITEM_MASTER ◄────FK────│ CUST_ITEM_ATTR │
│ ORDHEAD ◄────FK────│ CUST_PO_ATTR │
│ SUPS ◄────FK────│ CUST_SUPPLIER_ATTR │
│ ITEM_LOC ◄────FK────│ CUST_ITEM_LOC_ATTR │
│ │ │ │
│ Oracle upgrades │ │ Your customizations │
│ this schema ────▶ │ │ stay untouched │
│ Your data stays │ │ │
└──────────────────────┘ └──────────────────────┘
Creating CUST_ Extension Tables
Naming Convention
| Object Type | Pattern | Example |
|---|---|---|
| Custom table | CUST_[entity]_[purpose] | CUST_ITEM_ATTR |
| Custom PL/SQL package | PKG_CUST_[domain] | PKG_CUST_ITEM_MGMT |
| Custom view | V_CUST_[entity] | V_CUST_ITEM_FULL |
| Custom sequence | SEQ_CUST_[entity] | SEQ_CUST_ATTR_ID |
Flex Attributes
Flex Attributes are pre-built extension columns on base RMS tables. Oracle has reserved generic columns (VARCHAR2, NUMBER, DATE) on key tables specifically for retailer use:
Flex vs. CUST_ Tables
| Aspect | Flex Attributes | CUST_ Tables |
|---|---|---|
| Complexity | Simple (use existing columns) | More complex (new table + joins) |
| Number of fields | Limited (15 VARCHAR2 + 5 NUMBER + 5 DATE) | Unlimited |
| Performance | Fast (same table, no join) | Slightly slower (requires JOIN) |
| Naming | Generic (UDA_VALUE_01) — not self-documenting | Custom names (fabric_type) — self-documenting |
| UI Integration | Can be configured in base RMS UI | Requires custom APEX screen |
| Best for | Few simple attributes | Complex, multi-valued, or relational data |
Custom PL/SQL Hooks
Oracle provides extension hooks — predefined points in base PL/SQL code where custom logic can be injected:
REST API Integration (ORDS)
Custom extension data is exposed to external systems via ORDS REST APIs:
Extensions in the Cloud (v19+)
In MFCS cloud, the Extension Model is the ONLY way to customize:
- Oracle provisions your extension schema via Service Request
- You access it through APEX SQL Workshop or SQL Developer Web
- Custom UIs are built in APEX
- External integration uses ORDS REST APIs
- There is literally no way to modify base code — you cannot see it
Best Practices
Important Gotchas
- !NEVER modify Oracle's base tables, packages, or views. Every base modification creates upgrade debt. Use CUST_ tables and extension hooks instead.
- !Custom PL/SQL hooks should NEVER raise unhandled exceptions. If your custom logic fails, it should log the error and allow the base operation to complete. Blocking base operations with custom errors makes the system unusable.
- !Use flex attributes for simple, single-valued extensions (up to 15 VARCHAR2 + 5 NUMBER + 5 DATE). Use CUST_ tables for complex, multi-valued, or relational custom data.
- !Document which flex attribute (UDA_VALUE_01) maps to which business field (fabric_type). Without documentation, generic column names become meaningless within months.
- !Always include audit columns (CREATE_DATETIME, LAST_UPDATE_DATETIME, LAST_UPDATE_ID) on CUST_ tables. They are essential for delta extraction and troubleshooting.
Key Takeaways
- The Extension Model provides upgrade-safe customization through CUST_ tables, flex attributes, custom hooks, and ORDS REST APIs.
- Base code modifications create massive technical debt — upgrades that should take 3 months end up taking 18 months.
- Extension schemas are physically separate from Oracle's base schema — Oracle upgrades never touch your custom objects.
- Flex attributes (UDA_VALUE_01-15) are quick for simple extensions; CUST_ tables are better for complex relational data.
- Custom PL/SQL hooks are called by base code at predefined integration points — they must handle errors gracefully and never block base operations.
- In v19+ Cloud, the Extension Model is mandatory — there is no access to base code or base schema objects.


