Oracle RMS UDAs — User Defined Attributes
The standard Oracle RMS data model cannot anticipate every attribute a retailer needs to capture on an item. UDAs are the extension mechanism — retailer-defined fields that attach to items by department, drive activation gating, feed integrations, and power merchandising reports that the core schema alone cannot support.
What Are UDAs and Why Do They Exist?
The Oracle RMS core data model covers the attributes that every retailer needs on every item — description, department classification, unit of measure, pack indicators, supplier cost, and so on. But every retailer also needs attributes that are specific to their business, their product categories, and their reporting requirements.
A fashion retailer needs to capture season, trend direction, fabric composition, and fit type on clothing items. A grocery retailer needs shelf-life category, temperature handling class, and nutritional claims. A bookstore needs genre, reading age, and binding type. None of these are standard columns on ITEM_MASTER.
User Defined Attributes (UDAs) are Oracle RMS's answer to this. They are retailer-configured additional fields that can be attached to items, scoped by department, and made mandatory before an item can be activated. Once populated, UDA values are available for use in replenishment rules, promotion targeting, reporting, and external integrations.
UDAs vs Differentiators — an important distinction
UDAs and differentiators (DIFF_1 through DIFF_4 on
ITEM_MASTER) serve different purposes. Differentiators describe
variant dimensions that distinguish child SKUs from each other within a style
hierarchy — colour, size, fit. UDAs describe attributes of an item independent
of its variant structure. A UDA for Season applies to the whole item, not to
the size-blue variant specifically. Use differentiators for SKU-level
variation; use UDAs for item-level classification and merchandising metadata.
The Three UDA Types
Oracle RMS supports exactly three UDA types. Each type stores its item-level values in a separate table, has different validation rules, and serves a different kind of attribute.
A Date UDA stores a single Oracle DATE value for an item. Common uses include launch date, end-of-life date, next-delivery date, and campaign start date. Date UDAs have no pre-defined valid values — any date can be entered. They are stored in UDA_ITEM_DATE with the column UDA_DATE.
Real-world examples: Launch Date, Season End Date, Promotional Start Date, Discontinuation Date.
A List of Values UDA stores one value from a pre-defined pick-list. The valid options are defined in UDA_VALUES and linked to the UDA. The item-level value is stored in UDA_ITEM_LOV with the column UDA_VALUE, which is a foreign key back to UDA_VALUES. This is the most common UDA type — it enforces data consistency by constraining input to known values.
Real-world examples: Season (SS26, AW26), Brand Tier (PREMIUM, VALUE, CORE), Product Range (BASIC, FASHION, LIFESTYLE), Hazardous Class (NONE, FLAMMABLE, FRAGILE).
A Free Form UDA stores an unvalidated text string. It is the most flexible type and the one that should be used sparingly — because it has no validation, data quality tends to degrade over time as users enter inconsistent values. Free Form UDAs are appropriate for attributes where the value space is too wide or unpredictable to define as a pick-list.
Real-world examples: Marketing Tagline, Special Handling Instructions, Internal Reference Number, Buyer Notes.
The UDA Master Table
Every UDA — regardless of type — starts with a row in the UDA table. This is the definition record for the attribute: its ID, its type, its description, and its default behaviour.
| Column | Type | Description |
|---|---|---|
UDA_IDPK | NUMBER(5) | System-generated primary key. Referenced as a foreign key on all UDA value and assignment tables. |
UDA_DESC | VARCHAR2(120) | Display name of the UDA as it appears in the RMS UI and reports (e.g. 'Season', 'Brand Tier'). |
UDA_TYPE | VARCHAR2(2) | DA = Date · LV = List of Values · FF = Free Form. Determines which item-level table holds values. |
DISPLAY_TYPE | VARCHAR2(6) | How the UDA is displayed in the RMS Forms UI — TEXT, LOV, DATE picker, etc. |
SINGLE_VALUE_IND | VARCHAR2(1) | Y = item can hold only one value for this UDA. N = multiple values allowed (rarely used in practice). |
REQUIRED_IND | VARCHAR2(1) | Y = this UDA must be populated before an item can be activated. Checked at department level via UDA_DEPT. |
UDA_ID is the key that connects everything
UDA_ID is the foreign key used on every other UDA-related table —
UDA_VALUES, UDA_DEPT, UDA_ITEM_LOV,
UDA_ITEM_DATE, and UDA_ITEM_FF. When writing any query
that spans UDA tables, always join on UDA_ID and always include the
UDA.UDA_TYPE in your SELECT to know which storage table the value
came from.
UDA_VALUES — List of Values Options
For every UDA_TYPE = 'LV' UDA, the set of valid pick-list options is stored in UDA_VALUES. This table is the master reference for all LOV choices — both for the RMS UI drop-downs and for any integration that must validate UDA values before insertion.
| Column | Type | Description |
|---|---|---|
UDA_IDPKFK | NUMBER(5) | FK → UDA.UDA_ID. Identifies which List of Values UDA this value belongs to. |
UDA_VALUEPK | VARCHAR2(25) | The stored code value (e.g. 'SS26', 'PREMIUM', 'BASIC'). This is what is stored in UDA_ITEM_LOV. |
UDA_VALUE_DESC | VARCHAR2(120) | Human-readable label for the value (e.g. 'Spring/Summer 2026'). Displayed in the RMS UI drop-down. |
DISPLAY_ORDER | NUMBER(4) | Controls the order in which values appear in the pick-list. Lower numbers appear first. |
Inserting UDA_ITEM_LOV without validating against UDA_VALUES
The UDA_VALUE stored in UDA_ITEM_LOV is a foreign key to
UDA_VALUES. Direct SQL inserts that do not validate the value against
UDA_VALUES first will either fail with an integrity constraint
violation or — if the FK is not enforced at the database level — silently
create an invalid UDA assignment that the RMS UI cannot display correctly.
Always look up valid values from UDA_VALUES before inserting.
UDA_DEPT — Linking UDAs to Departments
A UDA defined in the UDA table is not automatically available on all items. UDAs are scoped to departments through the UDA_DEPT table. An item in Department 10 only has access to the UDAs that are assigned to Department 10 in UDA_DEPT. This scoping allows different product categories to have entirely different attribute sets — fashion departments capture season and trend direction; homeware departments capture material and country of manufacture.
| Column | Type | Description |
|---|---|---|
UDA_IDPKFK | NUMBER(5) | FK → UDA.UDA_ID. The UDA being assigned to this department. |
DEPTPKFK | NUMBER(4) | FK → DEPS.DEPT. The department this UDA applies to. |
REQUIRED_IND | VARCHAR2(1) | Y = items in this dept must have this UDA populated before activation. Overrides UDA.REQUIRED_IND at the dept level. |
DEFAULT_VALUE | VARCHAR2(25) | For LOV UDAs, the default value that is pre-populated when a new item is created in this dept. NULL if no default. |
DISPLAY_ORDER | NUMBER(4) | Order in which this UDA appears in the dept's UDA list within the RMS item setup form. |
The REQUIRED_IND on UDA_DEPT is the departmental override for the same column on UDA. A UDA can be optional globally but made mandatory for specific departments — or vice versa. When checking whether a UDA is required for an item, always check UDA_DEPT.REQUIRED_IND for the item's specific department, not UDA.REQUIRED_IND alone.
REQUIRED_IND — The Activation Gate
The single most important UDA concept for developers working on item integrations is the activation gate. When an item's status is being promoted from Candidate ('C') to Active ('A'), Oracle RMS checks whether all mandatory UDAs for that item's department have been populated. If any required UDA is missing a value, the activation is blocked.
This check is performed at the application layer. The logic is:
- Find all UDAs assigned to the item's department in
UDA_DEPTwhereREQUIRED_IND = 'Y' - For each required UDA, check that a corresponding row exists in the appropriate item-level table (
UDA_ITEM_LOV,UDA_ITEM_DATE, orUDA_ITEM_FF) - If any required UDA has no item-level row, activation fails with a validation message
Custom activation scripts must replicate this check
Any PL/SQL procedure or integration script that promotes items from Candidate
to Active by directly updating ITEM_MASTER.STATUS bypasses the
application-layer UDA check. Items that are activated this way may be missing
mandatory UDA values — they will look Active and can appear on purchase orders,
but reporting and replenishment logic that relies on those UDA values will
produce incorrect results. Always run the prerequisite UDA validation query
(see Practical SQL) before any programmatic activation.
Item-Level UDA Tables
Each of the three UDA types stores its item-level values in a dedicated table. All three follow the same structural pattern: composite primary key of ITEM + UDA_ID, and a single column carrying the actual value.
Stores one row per item per LOV UDA. The UDA_VALUE column is a foreign key to UDA_VALUES and must be one of the pre-defined valid values.
| Column | Type | Description |
|---|---|---|
ITEMPKFK | VARCHAR2(25) | FK → ITEM_MASTER.ITEM. Always VARCHAR2 — never cast to NUMBER. |
UDA_IDPKFK | NUMBER(5) | FK → UDA.UDA_ID. Must be a UDA with UDA_TYPE = 'LV'. |
UDA_VALUEFK | VARCHAR2(25) | FK → UDA_VALUES(UDA_ID, UDA_VALUE). The selected pick-list code. |
Stores one row per item per Date UDA. No validation against a pre-defined value set — any valid Oracle DATE is accepted.
| Column | Type | Description |
|---|---|---|
ITEMPKFK | VARCHAR2(25) | FK → ITEM_MASTER.ITEM. |
UDA_IDPKFK | NUMBER(5) | FK → UDA.UDA_ID. Must be a UDA with UDA_TYPE = 'DA'. |
UDA_DATE | DATE | The date value assigned to this item for this UDA. |
Stores one row per item per Free Form UDA. No validation — any text string up to 250 characters is accepted.
| Column | Type | Description |
|---|---|---|
ITEMPKFK | VARCHAR2(25) | FK → ITEM_MASTER.ITEM. |
UDA_IDPKFK | NUMBER(5) | FK → UDA.UDA_ID. Must be a UDA with UDA_TYPE = 'FF'. |
UDA_TEXT | VARCHAR2(250) | The free-form text value assigned to this item for this UDA. |
Querying UDAs Across All Three Types
Because UDA values are split across three tables depending on type, querying all UDAs for an item requires combining the three item-level tables. The standard pattern is a single query using LEFT JOIN to all three tables, with a CASE expression to surface the actual value regardless of which table it came from.
This pattern works for any item in any department
The query above is the universal UDA audit pattern. Run it against any item
to see every UDA the item's department requires, what value (if any) has been
set, and whether any required UDAs are missing. Use the
activation_status column output directly in pre-activation validation
scripts.
Integration Pattern — Inserting UDA Values Programmatically
When items are created through an integration pipeline, UDA values must be inserted programmatically after the ITEM_MASTER row exists but before the item is activated. The pattern is the same regardless of UDA type: look up the UDA_ID from the UDA table, validate the value if it is LOV type, then insert into the appropriate item-level table.
The recommended sequence for inserting UDA values in an integration:
- Identify all UDAs required for the item's department from
UDA_DEPT WHERE REQUIRED_IND = 'Y' - For each LOV UDA, validate the incoming value against
UDA_VALUES - Insert into
UDA_ITEM_LOV,UDA_ITEM_DATE, orUDA_ITEM_FFbased on the UDA type - Run the pre-activation UDA validation query to confirm no required UDAs remain missing
- Proceed with item activation
RC:Storefront is built to consume structured item data — categories, attributes, and metadata — from RC:OMS in real time. The same disciplined attribute thinking that UDAs bring to Oracle RMS is what powers clean, SEO-ready product pages on RC:Storefront. Self-hosted, zero transaction fees.
See RC:Storefront →Key Tables — Quick Reference
Practical SQL Examples
1. List all UDAs configured for a department with required status
2. Candidate items in a department missing required UDA values
3. All items assigned a specific LOV UDA value — season report
4. Pivot all LOV UDA values for items in a department — one row per item
5. PL/SQL — validate all required UDAs for an item before activation
Common Gotchas for Developers
Important Gotchas
- !
Checking UDA.REQUIRED_IND instead of UDA_DEPT.REQUIRED_IND. The
REQUIRED_INDcolumn exists on bothUDAandUDA_DEPT. The departmental override onUDA_DEPTtakes precedence for a specific item's department. A UDA marked optional globally may be mandatory in Menswear but not in Accessories. Always queryUDA_DEPT.REQUIRED_INDfiltered by the item's department, not the globalUDA.REQUIRED_IND. - !
Inserting to UDA_ITEM_LOV without validating against UDA_VALUES. The
UDA_VALUEcolumn onUDA_ITEM_LOVis a foreign key toUDA_VALUES. Inserting a value that does not exist inUDA_VALUESfor thatUDA_IDwill either fail at the constraint level or — if the FK is disabled — produce a record that renders as blank in the RMS UI because the join toUDA_VALUESfor the description returns no rows. - !
Using the wrong item-level table for a UDA type. Trying to insert a Date UDA value into
UDA_ITEM_LOV, or a LOV value intoUDA_ITEM_FF, will either fail at the constraint level or create data that no standard RMS query will find. Always readUDA.UDA_TYPEbefore deciding which of the three item-level tables to write to. - !
Not handling SINGLE_VALUE_IND = 'N' UDAs in queries. Most UDAs have
SINGLE_VALUE_IND = 'Y'— one value per item. For the rare UDA where multiple values are allowed,UDA_ITEM_LOVcan have multiple rows with the sameITEM + UDA_ID— only differing inUDA_VALUE. Queries that assume a single row per item-UDA pair and select into a scalar variable will throwTOO_MANY_ROWSfor these multi-value UDAs. - !
Pivoting UDA values with hardcoded UDA_IDs across environments.
UDA_IDvalues are system-generated and will differ between your DEV, UAT, and PROD environments unless you explicitly control the sequence or use named lookups. Any query or report that hardcodes a UDA_ID (e.g.WHERE uda_id = 42) will be wrong in a different environment. Always look up UDA_IDs byUDA_DESCat the top of any script that uses them, or parameterise them. - !
Forgetting to insert UDA values for new departments added after go-live. When a new department is set up in
DEPSand UDAs are assigned viaUDA_DEPT, existing items already in Active status in that department will have no UDA values. This is not a blocker for those items since they are already Active — but any report or integration that assumes all Active items in the department have UDA values will produce NULL-filled rows for legacy items. - !
Free Form UDA values never being cleaned up after LOV migration. Retailers occasionally migrate a Free Form UDA to a List of Values UDA as data governance improves. The old
UDA_ITEM_FFrows are not automatically deleted when the UDA type changes. Without a cleanup, queries that read UDA values via a type-aware CASE expression will find rows inUDA_ITEM_FFfor a UDA that is now configured asLV— producing confusing duplicated or contradictory results.
Key Takeaways
Key Takeaways
- UDAs are retailer-defined item attributes that extend the standard ITEM_MASTER schema. They are scoped to departments via UDA_DEPT and come in three types: Date (DA), List of Values (LV), and Free Form (FF).
- Each type stores item-level values in its own table: UDA_ITEM_LOV for LOV types, UDA_ITEM_DATE for dates, UDA_ITEM_FF for free text. Always check UDA.UDA_TYPE before deciding which table to read from or write to.
- UDA_VALUES holds the valid pick-list options for LOV UDAs. Always validate against UDA_VALUES before inserting to UDA_ITEM_LOV — invalid values either fail on the FK constraint or render as blank in the RMS UI.
- REQUIRED_IND on UDA_DEPT (not UDA) is the activation gate. Items in Candidate status with missing required UDA values cannot be activated. Always check UDA_DEPT.REQUIRED_IND for the item's specific department.
- UDA_ID values are instance-specific and differ between DEV, UAT, and PROD. Never hardcode UDA_IDs in scripts — always look them up by UDA_DESC or parameterise them.
- The universal UDA audit query joins UDA_DEPT → UDA → all three item-level tables with LEFT JOINs, using a CASE on UDA_TYPE to surface the correct value. This pattern works for any item in any department.


