Phase 2 · Foundation Data · Oracle RMS Series

The Oracle RMS Organizational Hierarchy

The Merchandise Hierarchy tells RMS what you sell. The Organizational Hierarchy tells it where you sell it. Mastering both is essential — every inventory transaction, purchase order, and stock query in RMS ties a product to a location.

14 min read📅April 19, 2026✍️Priyanshu Pandey📚Oracle RMS Series

What is the Organizational Hierarchy?

In Oracle RMS, every product that exists in the system must be tied to a location before it can be bought, sold, transferred, or counted. The Organizational Hierarchy is the structure that defines all those locations — from the broadest grouping (Chain) down to the individual Store, plus the separate concept of Warehouses.

Unlike the Merchandise Hierarchy — which classifies products — the Organizational Hierarchy classifies where business happens. The two hierarchies intersect at the item-location level: when an item is ranged to a store or warehouse, a record is created linking the item's merchandise hierarchy position to a location in the organizational hierarchy.

📍
Two separate hierarchies, one intersection point

The ITEM_LOC table is where both hierarchies meet. It holds one row per item-location combination, binding the item's DEPT/CLASS /SUBCLASS (merchandise hierarchy) to a LOC and LOC_TYPE (organizational hierarchy). Everything downstream — stock on hand, cost, replenishment — flows from this intersection.

The Oracle RMS Organizational Hierarchy has two distinct tracks:

The Store Track follows a five-level chain: Chain → Area → Region → District → Store. This represents your physical retail footprint — every store belongs to a District, which rolls up through management levels to the top.

The Warehouse Track sits alongside the store hierarchy. Warehouses are not part of the Chain-to-Store chain — they have their own table (WH) and their own type system (Physical, Virtual, Finisher). But in day-to-day RMS operations, stores and warehouses are treated identically as locations using the same LOC + LOC_TYPE pattern throughout the schema.

Store Track

The Store Hierarchy — Chain to Store

The store side of the Organizational Hierarchy is a strict five-level parent-child chain. Every store must belong to a District. Every District belongs to a Region. Every Region to an Area. Every Area to a Chain. Skipping a level is not possible — the database enforces this via foreign key constraints.

L1Chain
CHAIN

A Chain in Oracle RMS represents a grouping of stores that share the same retail format or brand identity. A multi-format retailer might have separate Chains for its flagship stores, its outlet centres, and its franchise network. Each Chain can have its own currency, though most single-country retailers operate with a single currency across all chains.

ColumnTypeDescription
CHAIN_NOPK
NUMBER(4)Unique chain identifier
CHAIN_NAME
VARCHAR2(120)Chain name
CURRENCY_CODE
VARCHAR2(3)Operating currency for this chain
L2Area
AREA

Areas subdivide a Chain into broad geographic or operational zones. For an Indian retailer, Areas might map to major zones — North, South, East, West — or to major metros like Delhi NCR, Mumbai, Bengaluru. The Area level is typically where senior regional leadership is aligned.

ColumnTypeDescription
AREA_NOPK
NUMBER(4)Unique area identifier
AREA_NAME
VARCHAR2(120)Area name
CHAIN_NOFK
NUMBER(4)Parent chain (FK → CHAIN)
L3Region
REGION

Regions sit beneath Areas and group Districts together. In RMS reporting, Region is one of the most commonly used rollup points for operational dashboards — regional managers can see aggregated performance across their Districts and Stores at this level without going all the way to Area or Chain.

ColumnTypeDescription
REGION_NOPK
NUMBER(4)Unique region identifier
REGION_NAME
VARCHAR2(120)Region name
AREA_NOFK
NUMBER(4)Parent area (FK → AREA)
L4District
DISTRICT

The District is the direct parent of the Store in the hierarchy. District managers in retail typically own profit-and-loss responsibility for all the stores in their District. In RMS, store operations, inventory moves, and replenishment can all be administered at the District level before cascading down to individual stores.

ColumnTypeDescription
DISTRICT_NOPK
NUMBER(4)Unique district identifier
DISTRICT_NAME
VARCHAR2(120)District name
REGION_NOFK
NUMBER(4)Parent region (FK → REGION)
L5Store
STORE

The Store is the leaf node of the store hierarchy — the physical location where customers buy products. The STORE table is one of the most referenced tables in all of Oracle RMS. It contains the configuration for every operational aspect of the store: its default warehouse for replenishment, its VAT region, its transfer zone, its channel type, and its current status.

The primary key of the STORE table is simply STORE — a number. When this value appears as a location in other RMS tables, it always comes with a LOC_TYPE of 'S' to distinguish it from warehouse locations.

ColumnTypeDescription
STOREPK
NUMBER(10)Unique store number — also used as LOC in ITEM_LOC, ORDLOC, etc.
STORE_NAME
VARCHAR2(150)Store display name
DISTRICT_NOFK
NUMBER(4)Parent district (FK → DISTRICT)
STORE_TYPE
VARCHAR2(1)C = Company owned, F = Franchise, W = Warehouse (used as store)
CHANNEL
VARCHAR2(6)Sales channel — STORE, WEB, CATALOG, etc.
DEFAULT_WH
NUMBER(10)FK → WH. The default warehouse that replenishes this store
VAT_REGION
NUMBER(4)VAT region for this store — drives tax calculation
TRANSFER_ZONE
NUMBER(4)Determines which stores this store can transfer stock to/from
CURRENCY_CODE
VARCHAR2(3)Operating currency for this store
STATUS
VARCHAR2(1)A = Active, I = Inactive, C = Closed
Warehouse Track

Warehouses — Physical, Virtual and Finisher

Warehouses in Oracle RMS are all stored in a single table — WH. The WH_TYPE column discriminates between the three fundamental warehouse types. Understanding the difference between a Physical and a Virtual warehouse is essential for any developer working on inventory, ordering, or replenishment logic.

WHWH Table
WH

Unlike the store hierarchy which spans five tables (CHAIN → AREA → REGION → DISTRICT → STORE), all warehouse types live in the single WH table. The relationship between Physical and Virtual warehouses is expressed within the same table — a Virtual WH's DEFAULT_WH column points to its parent Physical WH.

When a warehouse appears as a location in RMS tables like ITEM_LOC or ORDLOC, the WH primary key value is used as the LOC, and the LOC_TYPE is set to 'W'.

ColumnTypeDescription
WHPK
NUMBER(10)Unique warehouse number. Used as LOC in ITEM_LOC, ORDLOC, etc.
WH_NAME
VARCHAR2(150)Warehouse name
WH_TYPE
VARCHAR2(2)PA = Physical · VA = Virtual · EX = External Finisher
DEFAULT_WH
NUMBER(10)For virtual WHs: FK → parent physical WH. NULL for physical WHs.
CURRENCY_CODE
VARCHAR2(3)Operating currency of this warehouse
PROTECTED_IND
VARCHAR2(1)Y = protected warehouse (inventory cannot be moved freely)
FINISHER_IND
VARCHAR2(1)Y = this warehouse performs finishing work on items
VAT_REGION
NUMBER(4)VAT region for this warehouse
⚠️
Virtual Warehouses cannot receive Purchase Orders

Purchase Orders are received into Physical Warehouses. A Virtual Warehouse cannot directly receive a PO — stock is received at the Physical WH level and then logically allocated to Virtual WHs. Trying to create a PO to a Virtual WH will fail validation.

The LOC Pattern

The LOC + LOC_TYPE Pattern — Most Important Concept

This is the single most important architectural pattern in Oracle RMS for developers to understand. Throughout the entire RMS schema, whenever a table needs to store a reference to a location — whether a store or a warehouse — it does so using two columns together: LOC (the location number) and LOC_TYPE (a code indicating what kind of location it is).

This pattern appears on dozens of tables — ITEM_LOC, ITEM_LOC_SOH, ORDLOC, TSFHEAD, STKLEDGR, and many more. Every time you query these tables, you must filter by both LOC and LOC_TYPE together, or you risk pulling records from the wrong location type.

The valid LOC_TYPE values you will encounter are:

ColumnTypeDescription
'S'
STORE

Store
Used in ITEM_LOC, ITEM_LOC_SOH, ORDLOC, STKLEDGR

'W'
WH

Warehouse
Used in ITEM_LOC, ITEM_LOC_SOH, ORDLOC, STKLEDGR

'E'
WH (WH_TYPE='EX')

External Finisher
Used in transfer contexts

'A'
AREA

Area
Pricing / promo context only

'R'
REGION

Region
Pricing / promo context only

'D'
DISTRICT

District
Pricing / promo context only

Always filter by both LOC and LOC_TYPE

The pattern to always follow: WHERE ils.loc = :v_loc AND ils.loc_type = 'S' for stores, AND ils.loc_type = 'W' for warehouses. Omitting the LOC_TYPE filter is the most common source of incorrect results in custom RMS queries.

RC:OMS · Multi-Channel Order Management
Managing inventory across multiple warehouses and sales channels?

RC:OMS was built with the same location-aware inventory thinking as Oracle RMS — every stock movement is a double-entry ledger transaction, tracked by location. Amazon FBA, Flipkart, Shopify, WooCommerce, and your own Storefront — all managed from a single source of truth.

Explore RC:OMS
Comparison

Stores vs Warehouses — Key Differences in RMS

From a database perspective, stores and warehouses are both just "locations" in RMS. But they behave very differently in business logic.

DimensionStoresLOC_TYPE = 'S'WarehousesLOC_TYPE = 'W'
HierarchyCHAIN → AREA → REGION → DISTRICT → STOREStandalone — not part of the store chain
ReplenishmentHas DEFAULT_WH — receives stock from a warehousePhysical WHs receive Purchase Orders directly
Purchase OrdersCannot receive POs directlyPhysical WHs receive POs; Virtual WHs cannot
Stock on HandSOH = sellable floor stockSOH = bulk / storage stock
SalesSales transactions reduce SOH (via ReSA/POS)No direct sales — dispatches to stores via Transfers
StatusA (Active) / I (Inactive) / C (Closed)
NestingOne store per rowVirtual WHs nest under Physical WHs via DEFAULT_WH
Quick Reference

Key Database Tables — Quick Reference

Organizational Hierarchy Tables — Oracle RMS
CHAIN
Store Track — L1
AREA
Store Track — L2
REGION
Store Track — L3
DISTRICT
Store Track — L4
STORE
Store Track — L5 (Leaf)
WH
Warehouse Track
ITEM_LOC
Item–Location Ranging
ITEM_LOC_SOH
Stock on Hand
Practical SQL

Practical SQL Examples

1. Full store hierarchy path — store to chain

SQL
-- Full store hierarchy rollup for a given store
SELECT s.store,
s.store_name,
s.store_type,
s.status,
d.district_name,
r.region_name,
a.area_name,
c.chain_name,
s.default_wh,
w.wh_name         default_wh_name
FROM   store    s
JOIN   district d  ON d.district_no = s.district_no
JOIN   region   r  ON r.region_no   = d.region_no
JOIN   area     a  ON a.area_no     = r.area_no
JOIN   chain    c  ON c.chain_no    = a.chain_no
LEFT JOIN wh    w  ON w.wh          = s.default_wh
WHERE  s.store = :v_store;

2. Stock on hand for an item — across all stores and warehouses

SQL

-- Item SOH across all locations (stores + warehouses combined) -- Uses UNION to join both location types with their names SELECT 'STORE' loc_type_desc, s.store loc_no, s.store_name loc_name, ils.stock_on_hand, ils.av_cost, ils.unit_retail FROM item_loc_soh ils JOIN store s ON s.store = ils.loc WHERE ils.item = :v_item AND ils.loc_type = 'S' AND ils.stock_on_hand > 0

UNION ALL

SELECT 'WAREHOUSE' loc_type_desc, w.wh loc_no, w.wh_name loc_name, ils.stock_on_hand, ils.av_cost, ils.unit_retail FROM item_loc_soh ils JOIN wh w ON w.wh = ils.loc WHERE ils.item = :v_item AND ils.loc_type = 'W' AND ils.stock_on_hand > 0

ORDER BY loc_type_desc, loc_no;

3. All active stores with their default warehouses in a region

SQL
-- Operational report: active stores in a region with warehouse info
SELECT s.store,
s.store_name,
s.store_type,
d.district_name,
w.wh            default_wh_no,
w.wh_name       default_wh_name,
w.wh_type
FROM   store    s
JOIN   district d  ON d.district_no = s.district_no
JOIN   region   r  ON r.region_no   = d.region_no
LEFT JOIN wh    w  ON w.wh          = s.default_wh
WHERE  r.region_no = :v_region
AND  s.status    = 'A'
ORDER BY d.district_name, s.store_name;

4. PL/SQL — Validate a location exists (any type)

PL/SQL

-- Function to validate a LOC + LOC_TYPE combination -- Used in integration staging validation before inserting to RMS FUNCTION loc_exists ( p_loc IN item_loc.loc%TYPE, p_loc_type IN item_loc.loc_type%TYPE ) RETURN BOOLEAN IS l_count PLS_INTEGER := 0; BEGIN IF p_loc_type = 'S' THEN SELECT COUNT(1) INTO l_count FROM store WHERE store = p_loc AND status = 'A';

ELSIF p_loc_type = 'W' THEN SELECT COUNT(1) INTO l_count FROM wh WHERE wh = p_loc;

END IF;

RETURN (l_count > 0); EXCEPTION WHEN OTHERS THEN RETURN FALSE; END loc_exists;

Gotchas

Common Gotchas for Developers

  • !

    Querying ITEM_LOC without a LOC_TYPE filter. Store 101 and Warehouse 101 are completely different locations with the same LOC value. Filtering by only LOC = 101 will return rows for both. Always include AND LOC_TYPE = 'S' or 'W' explicitly.

  • !

    Treating Virtual Warehouses like Physical Warehouses in PO logic.

    Purchase Orders are received into Physical Warehouses. A Virtual Warehouse cannot directly receive a PO — stock is received at the Physical WH level and then logically allocated to Virtual WHs. Trying to create a PO to a Virtual WH will fail validation.

  • !

    Forgetting that STORE and WH number ranges can overlap. There is no technical separation in RMS preventing Store 5000 and Warehouse 5000 from coexisting. The LOC_TYPE is the only discriminator. Integration scripts that strip LOC_TYPE and try to look up just by number will fail silently or return wrong data.

  • !

    Assuming DEFAULT_WH on STORE is always set. In some RMS configurations, stores may not have a DEFAULT_WH assigned — especially during initial data migration or for online-only stores. Always LEFT JOIN on WH when reading DEFAULT_WH, or validate for NULL before using it in batch logic.

  • !

    Missing the difference between Store STATUS values. A store with STATUS = 'I' (Inactive) still exists in the hierarchy and may still have stock on hand. STATUS = 'C' (Closed) means the store has completed closure. Logic that only checks for STATUS = 'A' will miss Inactive stores that still need inventory management.

  • !

    Using LOC_TYPE = 'A' (Area) in item_loc context. LOC_TYPE values like 'A', 'R', 'D' (Area, Region, District) are used in some RMS contexts for aggregated pricing and promotion assignment — but they are not valid in ITEM_LOC or ITEM_LOC_SOH. Those tables only accept 'S', 'W', or 'E'.

Key Takeaways

Key Takeaways
  • The RMS Organizational Hierarchy has two tracks: Store (CHAIN → AREA → REGION → DISTRICT → STORE) and Warehouse (WH table with WH_TYPE)
  • All three warehouse types — Physical (PA), Virtual (VA), and Finisher (EX) — live in the single WH table. Virtual WHs reference their parent via DEFAULT_WH.
  • The LOC + LOC_TYPE pattern is the most important architectural concept — stores use LOC_TYPE = 'S', warehouses use 'W'. Always filter by both columns together.
  • ITEM_LOC and ITEM_LOC_SOH are where the Merchandise and Organizational hierarchies intersect. One row per item per location.
  • Store SOH = sellable floor stock. Warehouse SOH = bulk/storage stock. Both live in ITEM_LOC_SOH but with different LOC_TYPE values.
  • STORE.DEFAULT_WH links each store to its replenishment source — this is critical for replenishment batch logic.
RetailCoder
All systems operational
v1.0 Live

RC:OMS

Multi-channel order management with double-entry inventory ledger. Amazon, Flipkart, Shopify, WooCommerce — one source of truth.

Launch demo →
v1.0 Live

RC:Storefront

Self-hosted headless e-commerce. Your server, your data, zero transaction fees. Native RC:OMS inventory sync.

Visit Storefront →
Pipeline

RC:Pulse

AI-powered retail analytics and demand forecasting — built natively on top of your RC:OMS and Storefront data.

Request early access →
Built in India 🇮🇳  ·  Architected by Priyanshu PandeyTalk to an engineer →