Enterprise Integration Manager — Siebel's batch-oriented engine for moving data between interface tables and base tables. Every IFB directive, every column convention, every error code, laid out the way an engineer actually reads them.
External data cannot touch base tables directly — Siebel enforces this rule absolutely. EIM provides the only sanctioned batch path: external source writes to an interface table, EIM reads the interface table, resolves foreign keys, applies user-key logic, and writes to one or many base tables in a single transaction.
Direct SQL INSERT into S_ORG_EXT or S_CONTACT is unsupported and will corrupt the schema — Siebel's relational design has hundreds of cross-table dependencies, user-key columns, denormalised fields, and audit hooks. EIM is the only batch tool that resolves all of these correctly.
It is verbose, it is slow per row, but it is the only safe way to load 500,000 accounts at 2 a.m. without breaking the application.
Staging tables prefixed EIM_. They mirror base table columns plus control columns (IF_ROW_BATCH_NUM, IF_ROW_STAT, T_DELETED, T_MERGED_ROW_ID). External systems write here.
A plain-text configuration file telling EIM what to do: which batch number, which operation, which target tables, which columns to ignore, which user keys to use. One IFB can contain many process steps.
EIM runs as a Siebel Server component. Submit the IFB via the Process Batch component with a config file path; it reads batches marked FOR_IMPORT and processes them.
The real Siebel schema. EIM resolves the interface row against user keys, then writes/updates/deletes across every dependent base table in one atomic transaction. Failure rolls back the entire row.
Every EIM run is driven by a single ASCII configuration file. Its grammar is bracketed sections, key = value pairs, and shell-style includes. Below is a complete, annotated IFB for an account import.
; ─── Header: declares the process to run ───────────── [Siebel Interface Manager] PROCESS = "Import Accounts" ; ─── Shell process: chains steps in sequence ───────── [Import Accounts] TYPE = SHELL INCLUDE = "Import Accounts Step 1" INCLUDE = "Clear EIM Table" ; ─── Actual import step ─────────────────────────────── [Import Accounts Step 1] TYPE = IMPORT BATCH = 1000 TABLE = EIM_ACCOUNT ONLY BASE TABLES = S_ORG_EXT, S_ORG_BU ONLY BASE COLUMNS = S_ORG_EXT (NAME, LOC, BU_ID, VIS_ST, ACCNT_FLG), S_ORG_BU (BU_ID, ORG_ID) DEFAULT COLUMN = ACCNT_PR_POSTN_ID, "0-R5NH" DEFAULT COLUMN = VIS_ST, "Y" ATTACH ROWS = "ALL" UPDATE ROWS = "ALL" INSERT ROWS = S_ORG_EXT, S_ORG_BU TRANSACTION BORDER = 1000 ; ─── Cleanup step ───────────────────────────────────── [Clear EIM Table] TYPE = DELETE BATCH = 1000 TABLE = EIM_ACCOUNT DELETE MATCHES = EIM_ACCOUNT (IF_ROW_BATCH_NUM = 1000)
Every bracketed section is one process step. The header section tells the EIM component which process to execute — there can be only one per run.
One of SHELL (orchestrator), IMPORT, EXPORT, DELETE, or MERGE. SHELL sections only chain other sections via INCLUDE.
An integer identifying which rows in the interface table to process. Rows are tagged by setting IF_ROW_BATCH_NUM to this value before running EIM.
The most important performance directive. Restrict EIM to only the tables and columns you actually need — default behaviour touches every related table.
Provides a constant value for a column when the interface table does not. Useful for hardcoding BU_ID, currency codes, or visibility flags across a whole load.
Number of rows per database commit. Lower = safer, slower. Higher = faster, but a single failure rolls back more rows.
Each operation has its own TYPE value, its own data direction, and its own interface-table population rules. Memorise these four diagrams and you have 80% of EIM in your head.
Load new records or update existing ones. The most common EIM verb — used for every data migration, every ongoing feed from external systems.
Pull data out of base tables into an EIM interface table, then extract via SQL. Used for extracts, migrations out of Siebel, integration with downstream warehouses.
Remove rows from base tables. Two flavours: DELETE EXACT matches user keys precisely; DELETE MATCHES uses a WHERE clause on base tables.
Consolidate two records into one — surviving row absorbs the loser's child records, then the loser is deleted. Used for deduplication, account hierarchy consolidation.
Every interface table follows the pattern EIM_<ENTITY>, and every entity maps to a primary base table plus its dependents. Below are the tables you will encounter in 95% of EIM work.
Regardless of operation, every EIM run follows the same lifecycle. The diagram below is the entire pipeline — every EIM task you ever debug will map onto these five stages.
External source (file, ETL, API) writes rows into the EIM_ interface table. Set IF_ROW_BATCH_NUM to the batch number declared in the IFB.
Submit "Process Batch" component job with the IFB file path. EIM reads the header section and starts the declared PROCESS.
EIM resolves foreign keys using user keys on each target base table. Unresolved foreign keys mark the row as NOT_ALLOWED and skip it.
Atomic write across all base tables for the row. Either every table for this row commits, or the whole row rolls back.
EIM writes IF_ROW_STAT — IMPORTED, UPDATED, DELETED, MERGED, or one of the failure codes. Inspect this column to triage failures.
Every EIM interface table has two kinds of columns. Control columns drive EIM's behaviour — never written by the source system. Data columns hold the actual payload and map directly to base table columns.
IMPORTED = success. NOT_ALLOWED, DUP_ID_EXIST, ROW_LOCKED = various failures. Always inspect this column post-run.Y on rows that should be deleted from base tables.Y = visible to all positions; otherwise restricted to primary position. Affects visibility queries._X). Map to extension table columns — populated only when the parent base row has been resolved.After every EIM run, query SELECT IF_ROW_STAT, COUNT(*) FROM EIM_* GROUP BY IF_ROW_STAT. The status codes below tell you exactly what went wrong and where to look.
Left to its defaults, EIM will examine every related table, every column, every index. For a 500k-row load this means hours. The six directives below are the standard bag of tricks — applied together, they routinely cut run times by 80%.
Always use ONLY BASE TABLES. Without it, EIM touches every dependent table — for an account that means 12+ tables instead of 2.
Pair ONLY BASE TABLES with ONLY BASE COLUMNS. Skip columns your source does not populate — EIM will not need to read them.
For very large loads (1M+ rows), drop non-unique indexes on target base tables before EIM and rebuild them after. Index maintenance per row is the single biggest cost.
Run UPDATE STATISTICS on the interface table and target base tables before EIM. The query optimiser needs current stats to choose efficient plans.
Split one large batch into N smaller batches (e.g. 10 batches of 50k rows). Run them as parallel EIM tasks — different batches do not lock each other.
Set TRANSACTION BORDER to 1000–5000 rows. Too low = excessive commits. Too high = massive rollback on any single-row failure.
It will appear to work, then break visibility, denormalised columns, or audit hooks weeks later. EIM is the only sanctioned batch path — treat this as inviolable.
Successful rows should be deleted or archived. Failed rows should be moved to a "failures" batch for triage. Leftover rows accumulate and confuse the next run.
An IFB that runs in 30 seconds against 1000 test rows may take 8 hours against 500k production rows. Performance characteristics are non-linear.
Use semicolon comments at the top of every .ifb file: business purpose, batch number convention, source system, run schedule. Future-you will be grateful.
Use ranges: 1000–1999 for accounts, 2000–2999 for contacts, 3000–3999 for opportunities. Avoids collisions when multiple EIM jobs run in parallel.
Accounts before contacts. Positions before employees. Products before price lists. Foreign key violations are almost always load-order mistakes.
EIM has no interactive debugger. Set ErrorFlags, SQLTraceFlags, and TraceFlags in the component job parameters.
They are code, not config. Treat them as such: Git, pull requests, code review. An unreviewed IFB change can corrupt production data.