LR Maritime Database · Trigger Business Rules Reference · Generated from SQL source 2026-05-03
The machinery trigger family covers main propulsion (HIMO), auxiliary machinery (MA* series), thruster (MATH), generator sets (HIGE / HIMT), and ship speed (MASP). All machinery triggers were redesigned in January–February 2007 to use cursors for bulk-update support. Two key EDM table migrations occurred in April 2026 for HIMO.
Main propulsion engine. 4-column composite key (LRNO, SEQNO, POS_CODE, TYPE). Updated Apr 2026 to use EDM tables.
Generator sets per propulsion position. 3-column composite key (LRNO, SEQNO, POS_CODE).
Main engine motor/turbine details. Standard (non-cursor) trigger.
Thruster data. 3-column key (LRNO, SEQ, TYPE). Status sync with ABSD_HIST.
Auxiliary generator. 3-column key (LRNO, SEQ, TYPE). AC/DC frequency cross-checks.
Emergency engines 1-3. MAEM1 has dual guard. MAEM1 has LFAN cross-check vs OVTY ship type.
Ship speed (trial / service / maximum). Updates SHIP_SEARCH.SSpeed. Multiple conditional annotation groups.
Boiler, bunker, gearbox, propeller, stability. Follow the standard MA* cursor pattern.
IF NOT EXISTS (SELECT * FROM TRIGGER_DISABLE)valStandard4_new; CC → valStandard2; SRCE → valStandard8; VER → valStandard1valStandard3NumMain propulsion engine trigger. Uses a 4-column composite key (LRNO, SEQNO, POS_CODE, TYPE). In April 2026, two codebook lookups were migrated from ABSD_CBUB3 and ABSD_CBUB1 to EDM.dbo.T_REF_CBUB3 and EDM.dbo.T_REF_CBUB1 respectively. Includes automatic creation of sister records in ABSD_HIPU, ABSD_HIPS, and ABSD_HIPM.
| Field | Rule | Error Message |
|---|---|---|
DC | NOT NULL mandatory | "Design code must be completed!" |
NEW | IN('Y','U','N'), NOT NULL | "NEW must be one of U N or Y" |
| Field | Max Digits |
|---|---|
DES_POWER | 6 |
POW_KW | 5 |
OE01_CN | 2 |
OE01_BORE | 4 |
OE01_ST1, OE01_ST2, OE01_ST_EX | 4 each |
OE01_RPM_DES | 4 |
GTE02_GASSNO | 1 |
STE03_AT | 1 |
STR04_EXP | 1 |
STR04_CN, STR04_HPCN | 2 |
STR04_HPCB, STR04_IPCB1, STR04_IPCB2, STR04_LPCB, STR04_CST | 4 each |
STR04_IPCN1, STR04_IPCN2, STR04_LPCN | 2 each |
| Field | Valid Values | Notes |
|---|---|---|
TYPE | '01','02','03','04' | Engine type code |
CLASS | NULL or IN('*','+','R','U','N') | Engine class; nullable — skip check if NULL |
DRIND | IN('DD','EE','GE','GG','YY','NN') | Drive indicator |
OE01_RECON_IND | IN('Y','U','N') | Reconditioning indicator |
OE01_SD | IN('N','Y') | Supercharge/diesel indicator |
OE01_ST_TYP | IN('2','4','Y','N') | Stroke type |
OE01_STCYC | IN('S','D','Y','N') | Stroke cycle |
OE01_ST2 > 0 requires OE01_ST1 > 0. Error: "OE01_ST2 cannot contain a value if OE01_ST1 is 0"OE01_ST_EX > 0 requires OE01_ST2 > 0. Error: "OE01_ST_EX cannot contain a value if OE01_ST2 is 0"| Field | Reference Table | Constraint | Collation |
|---|---|---|---|
OE01_CA | EDM.dbo.T_REF_CBUB3 | TABNO='26' (was ABSD_CBUB3 before Apr 2026) | Case-sensitive |
POSN | EDM.dbo.T_REF_CBUB1 | FLDI='03' (was ABSD_CBUB1 before Apr 2026) | Case-sensitive |
POS_CODE | EDM.dbo.T_REF_CBUB1 | FLDI='03' (was ABSD_CBUB1 before Apr 2026) | Case-sensitive |
DC | ABSD_CBED | Must match ENGKEY OR match pattern 'Z[A-Z][A-Z]' (escape: ZXX = unknown design) | Default |
EM | ABSD_CBEB.MM | Nullable — checked only when not null | Default |
EM2 | ABSD_CBEB.MM | Nullable — checked only when not null | Default |
| Field | Validation SP | Notes |
|---|---|---|
EFD, DM | valStandard4_new | YYMMDD format |
VER, POSN_VER, DC_VER, EM_VER, EM2_VER | valStandard1 | Confidence code |
DESPOW_CC, POWKW_CC, OE01_CN_CC, OE01_BORE_CC, OE01_ST1_CC, OE01_ST2_CC, OE01_ST_EX_CC, OE01_RPM_CC, OE01_SD_VER*, GTE02_GN_CC | valStandard2 | 2-char alpha confidence codes (*OE01_SD_VER uses valStandard1) |
OE01_ST1_VER, OE01_ST2_VER, OE01_ST_EX_VER | valStandard1 | Confidence codes |
-- For each (LRNO, SEQNO, POS_CODE, TYPE) in inserted: IF NOT EXISTS (SELECT * FROM ABSD_HIPU WHERE LRNO=@L AND POSN=@P AND SEQNO=@S AND TYPE=@T) INSERT INTO ABSD_HIPU (LRNO, POSN, SEQNO, TYPE, PU_SEQ) VALUES (..., '00') IF NOT EXISTS (SELECT * FROM ABSD_HIPS WHERE LRNO=@L AND POSN=@P AND SEQNO=@S AND TYPE=@T) INSERT INTO ABSD_HIPS (LRNO, POSN, SEQNO, TYPE, PS_SEQ) VALUES (..., '00') IF NOT EXISTS (SELECT * FROM ABSD_HIPM WHERE LRNO=@L AND POSN=@P AND SEQNO=@S AND TYPE=@T) INSERT INTO ABSD_HIPM (LRNO, POSN, SEQNO, TYPE, PM_SEQ) VALUES (..., '00')
Business Rule: Every main engine record must have corresponding HIPU (propulsion unit), HIPS (propulsion system), and HIPM (propulsion machinery) records. These are automatically created as shell records when a HIMO record is first inserted.
Conditional update — only writes J06 if the combination of J06_AUTHOR + J06_LNCHDATE does not already match the current user and today's date for this LRNO. Updates J06_AUTHOR and J06_LNCHDATE only (no J06_LNCHTIME). Uses SYSTEM_USER directly.
ABSD_HIMO_UPDATES — refreshed with the full set of current HIMO rows for the LRNO (delete+insert from base table).
| Type | Field Trigger | Notes |
|---|---|---|
| Primary (tblChanges) | MD (manufacturer date) | Standard @IsNew OldValue pattern |
| Secondary | Always fires per cursor row | Group: Tablename='ABSD_HIMO', Fieldname='POSN' |
Generator set trigger. Cursor key: (LRNO, SEQNO, POS_CODE). Records electrical generation data per engine position. The HIST trigger sets E45_GS (generator status) when vessel status changes.
| Field | Max Digits |
|---|---|
E45_NO | 2 |
E45_KW, E45_VOLT | 5 |
E45_FREQ | 2 |
E45_ACDC: IN('A','D','N','U','Y') when not nullE45_ACDC='A' (Alternating Current): E45_FREQ must be IN('50','60','0'). Error: "E45_FREQ must be 0,50 or 60 when E45_ACDC is A"E45_DM (manufactured date) must NOT be > E45_EFD (effective date). Exception: E45_DM='198099' is a sentinel value meaning "pre-1980" and is allowed to exceed EFD. Error: "E45_DM may not be greater than E45_EFD"E45_GS='8' (retired/scrapped): E45_EFD must NOT be > E45_ST (stop date). Error message reuses the "E45_DM" phrasing (a copy-paste bug in the original code).| Field | Reference | Notes |
|---|---|---|
E45_PM_POS_1 through E45_PM_POS_9 | ABSD_CBUB1 FLDI='03' | Engine position codes; E45_PM_POS_1 may be non-null; 2-9 checked only when not null. Case-sensitive collation. |
E45_GM | ABSD_CBEB.MM | Generator make; not null required |
E45_GS | ABSD_CBUB1 FLDI='19' | Generator status. Exception: code '8' is not validated against codebook (hardcoded sentinel for retired generators). |
ABSD_CBUB1 directly for E45_PM_POS_1–9 and E45_GS lookups.
| Field | Validation SP |
|---|---|
E45_EFD, E45_DM, E45_ST | valStandard4_new |
E45_VER, E45_POS_VER, E45_GM_VER, E45_DM_VER, E45_ST_VER | valStandard1 |
E45_DPI | valStandard2 |
E45_NO_CC+E45_NO, E45_KW_CC+E45_KW, E45_VOLT_CC+E45_VOLT | valStandard3Num |
ABSD_HIGE_UPDATES — refreshed per LRNOMain engine motor / turbine details trigger. Unlike most machinery triggers, HIMT was not rewritten as a cursor trigger in 2007. It processes the full inserted set as a batch. The commented-out ABSD_AWSH_UPDATES block (ShipWatch integration) was deactivated.
| Field | Max Digits |
|---|---|
E54_NO | 2 |
E54_SHP_PO | 6 |
E54_KW_PO | 5 |
E54_FREQ | 2 |
| Field | Valid Values |
|---|---|
E54_SHP_TY | 'D','S','M','U','N','Y' (shaft power type) |
E54_KW_TY | 'D','S','M','U','N','Y' (kW power type) |
E54_ACDC | 'D','A','U','N','Y' |
E54_MCS | 'C','S','T','W','Y','D','N','U' (motor/control system) |
| Field(s) | Validation SP |
|---|---|
E54_EFD, E54_DM, E54_ST | valStandard4_new |
E54_VER, E54_POS_VER | valStandard1 |
E54_SRCE | valStandard8 |
E54_NO_CC+E54_NO, E54_SHP_CC+E54_SHP_PO, E54_KW_CC+E54_KW_PO | valStandard3Num |
E54_NO_CC, E54_SHP_CC, E54_KW_CC | valStandard2 (double-validated — also as part of the Num pair) |
| Field | Reference | Notes |
|---|---|---|
E54_POSN | ABSD_CBUB1 FLDI='03' | Mandatory, case-sensitive |
E54_PM_POS_1 | ABSD_CBUB1 FLDI='03' | Mandatory for first position |
E54_PM_POS_2 through _9 | ABSD_CBUB1 FLDI='03' | Checked only when not null |
E54_MM | ABSD_CBEB.MM | Motor/turbine make |
ABSD_HIMT_UPDATESThruster data trigger. Cursor key: (LRNO, SEQ, TYPE). Contains a special business rule that syncs the thruster status field with the vessel's current live status when a new thruster is added.
| Field | Max Digits |
|---|---|
E95_THST_NO | 1 |
E95_THST_BHP, E95_LATT_BHP | 6 |
E95_THST_KW | 5 |
| Rule | Error |
|---|---|
E95_THST_TYP: must be in ABSD_CBUB1 FLDI='47' (case-sensitive) | "The code in E95_THST_TYP does not match a record in table 47 of CBUB1" |
When E95_THST_TYP NOT IN ('NN','UU','YY'): E95_THST_NO must be > 0 (added Dec 2007) | "The code in thruster type requires number of thrusters to be greater than 0." |
When E95_THST_TYP='YY': all other ABSD_MATH rows for the same LRNO must also have E95_THST_TYP='YY' (cross-row consistency) | "If a the code in E95_THST_TYP is 'YY' other thrusters should be set to the same code." |
When E95_THST_TYP='NN': both E95_THST_BHP and E95_THST_KW must be 0 | "Thruster type cannot be none when a power is specified" |
| Field(s) | Validation SP |
|---|---|
E95_EFD | valStandard4_new |
E95_CC | valStandard2 |
E95_SRCE | valStandard8 |
E95_THSTNO_CC+E95_THST_NO, E95_THBHP_CC+E95_THST_BHP, E95_THKW_CC+E95_THST_KW | valStandard3Num |
E95_THST_NO=0 for the current row AND another row already exists for the same LRNO with a different SEQ and E95_THST_NO=0: RAISERROR "Number of Thrusters (E95_THST_NO) must not be 0 if another 0 record exists"E95_THST_NO changes AND the new value > 0 AND ABSD_HIST.A02_STS ≠ E95_THST_STAT AND vessel status NOT IN ('9','B','G','H','V') (i.e., vessel is in an active/reportable state):
UPDATE ABSD_MATH SET E95_THST_STAT = ABSD_HIST.A02_STS for the vessel.
This ensures that when a thruster is first recorded, it immediately reflects the vessel's current live status.
ABSD_MATH_UPDATESAuxiliary generator trigger. Cursor key: (LRNO, SEQ, TYPE). Contains AC/DC and frequency cross-validation rules that are more complex than HIGE's equivalent.
| Field | Max Digits |
|---|---|
E89_GEN_NO | 2 |
E89_GEN_VOLT1, E89_GEN_VOLT2 | 4 |
E89_FREQ_HZ | 2 |
| Condition | Error |
|---|---|
E89_ACDC_IND='A' and E89_FREQ_HZ NOT IN('50','60','0') | "E89_FREQ_HZ must be 0,50 or 60 when E89_ACDC_IND is A" |
E89_ACDC_IND IN('N','U') and (E89_FREQ_HZ ≠ 0 OR E89_FHZ_CC NOT IN('U','N')) | "E89_FHZ_CC must be N or U when E89_ACDC_IND is N and E89_FREQ_HZ ≠ 0" |
E89_FHZ_CC='Y' and E89_ACDC_IND='A' | "E89_ACDC_IND must not be A when E89_FHZ_CC is Y" |
E89_GEN_MAKE: must be in ABSD_CBEB.MM (generator manufacturer)| Field(s) | Validation SP |
|---|---|
E89_EFD | valStandard4_new |
E89_SRCE | valStandard8 |
E89_VER | valStandard1 |
E89_CC, E89_MENG_DRVN | valStandard2 |
E89_GENNO_CC+E89_GEN_NO, E89_GENKW_CC+E89_GEN_KW, E89_GVOLT1_CC+E89_GEN_VOLT1, E89_GVOLT2_CC+E89_GEN_VOLT2, E89_FHZ_CC+E89_FREQ_HZ | valStandard3Num |
ABSD_MAAU_UPDATESEmergency engine #1 trigger. Cursor key: (LRNO, SEQ, TYPE). The only machinery trigger with a dual guard. Contains a cross-table check against ABSD_OVTY for the landing fan indicator.
IF NOT EXISTS (SELECT * FROM TRIGGER_DISABLE)
BEGIN
IF NOT EXISTS (SELECT * FROM TRIGGER_DISABLE_MAEM1)
BEGIN
-- all logic
END
END
The inner TRIGGER_DISABLE_MAEM1 guard is used to suppress the MAEM1 trigger during bulk operations that update multiple emergency engine records programmatically.
| Field | Max Digits |
|---|---|
E88_OILENG_NO | 2 |
E88_OLENG_BHP | 6 |
E88_OILENG_KW | 5 |
| Rule | Error |
|---|---|
E88_SEC_IND: IN('E','S','N','U','Y') | "E88_SEC_IND must be one of E S U N or Y" |
When E88_SEC_IND IN('E','S','Y'): E88_PROP_TEXT must NOT be NULL | "E88_PROP_TEXT must contain text when E88_SEC_IND is one of E S or Y" |
E88_LFAN_IND='Y' (lifting fan indicator):
The vessel's current ship type (ABSD_OVTY.D01_INT_BASIC at SEQNO='00') must begin with '6' (hovercraft/air cushion vessel type codes).
Error: "When E88_LFAN_IND is Y, D01_INT_BASIC must begin 6"
E88_GEAR_TYP: ABSD_CBUB1 FLDI='35' (gearbox type, case-sensitive)| Field(s) | Validation SP |
|---|---|
E88_EFD | valStandard4_new |
E88_CC | valStandard2 |
E88_SRCE | valStandard8 |
E88_VER, E88_OEBHP_VER, E88_OEKWP_VER, E88_GEART_VER | valStandard1 |
E88_LFAN_IND | valStandard2 |
E88_OEN_CC+E88_OILENG_NO, E88_OEBHP_CC+E88_OLENG_BHP, E88_OEKW_CC+E88_OILENG_KW | valStandard3Num |
ABSD_MAEM1_UPDATESABSD_MAEM2 and ABSD_MAEM3 follow the identical structure as MAEM1 but for the second and third emergency engines. Both use the dual guard pattern (TRIGGER_DISABLE + TRIGGER_DISABLE_MAEM2/MAEM3) and the same field validations with E88_ prefix fields.
Ship speed trigger. Records trial speed (E83), service speed (E84), maximum speed (E85), and unspecified speed (E86). The trigger updates ABSD_SHIP_SEARCH.SSpeed using a waterfall: service speed if available, otherwise maximum speed. Has four conditional annotation groups (one per speed type).
| Rule | Error |
|---|---|
E84_SERVICE_SPD > 60 | "E84_SERVICE_SPD cannot be over 60" |
E85_MAXIMUM_SPD > 60 | "E85_MAXIMUM_SPD cannot be over 60" |
| Field(s) | Validation SP |
|---|---|
E83_EFD | valStandard4_new |
E83_CC | valStandard2 |
E83_SRCE | valStandard8 |
E83_VER | valStandard1 |
E84_SS_CC+E84_SERVICE_SPD | valStandard3Num |
E85_MS_CC+E85_MAXIMUM_SPD | valStandard3Num |
-- Service speed takes priority over maximum speed:
UPDATE ABSD_SHIP_SEARCH SET SSpeed =
CASE WHEN ISNULL(E84_SERVICE_SPD,0) = 0
THEN E85_MAXIMUM_SPD
ELSE E84_SERVICE_SPD
END
FROM ABSD_SHIP_SEARCH INNER JOIN INSERTED ON ABSD_SHIP_SEARCH.LRNO = INSERTED.LRNO
WHERE INSERTED.LRNO = @INDEXLRNO
Fires when E84_SERVICE_SPD or E85_MAXIMUM_SPD is updated. No SEQNO filter — updates SHIP_SEARCH regardless of which sequence number is changed.
| Trigger Condition | Annotation Group (Fieldname) |
|---|---|
E83_EFD OR E83_SRCE OR E83_TRIAL_SPD changes | Tablename='ABSD_MASP', Fieldname='E83_EFD' |
E84_EFD OR E84_SRCE OR E84_SERVICE_SPD changes | Tablename='ABSD_MASP', Fieldname='E84_EFD' |
E85_EFD OR E85_SRCE OR E85_MAXIMUM_SPD changes | Tablename='ABSD_MASP', Fieldname='E85_EFD' |
E86_EFD OR E86_SRCE OR E86_UNSPEC_SPD changes | Tablename='ABSD_MASP', Fieldname='E86_EFD' |
Unlike most MA* triggers where a secondary annotation always fires, MASP fires up to four conditional annotations. Multiple can fire in a single update if multiple speed types are changed.
ABSD_MASP_UPDATESThe following machinery triggers follow the standard MA* cursor pattern without special exceptions. They are documented here as a group.
| Table | Subject | Key Prefix | Unique Rules | Staging Table | Secondary Ann. Fieldname |
|---|---|---|---|---|---|
ABSD_MABO |
Boiler | E63_ | E63_NO max 2; E63_PRESS max 5; E63_BOILER_TYP → CBUB1 FLDI='06' | ABSD_MABO_UPDATES | E63_EFD |
ABSD_MABU |
Bunker capacity | E79_ | E79_FUEL_TYP → CBUB1 FLDI='??'; capacity fields max 6 | ABSD_MABU_UPDATES | E79_EFD |
ABSD_MAGR |
Gearbox / reduction gear | E66_ | E66_GEAR_TYP → CBUB1; ratio fields; pairs validated with valStandard3Num | ABSD_MAGR_UPDATES | E66_EFD |
ABSD_MAPR |
Propeller | E73_ | E73_PROP_TYP → CBUB1 FLDI='??'; E73_PROP_DIA max 4; E73_PROP_NO max 2; pairs validated | ABSD_MAPR_UPDATES | E73_EFD |
ABSD_MAST |
Stability data | E87_ | E87_GM max 5; cross-checks on metacentric height values | ABSD_MAST_UPDATES | E87_EFD |
TRIGGER_DISABLE only (except MAEM1–3 which add a second guard)INSENSITIVE CURSOR FOR SELECT LRNO, SEQ, TYPE FROM insertedvalStandard4_new; SRCE → valStandard8; VER → valStandard1; CC → valStandard2valStandard3Num| Trigger | Guard | Cursor Key | EDM Tables? | J06_LNCHTIME | SHIP_SEARCH | Cascade | Special Rules |
|---|---|---|---|---|---|---|---|
HIMO |
TRIGGER_DISABLE | LRNO, SEQNO, POS_CODE, TYPE | Yes — Apr 2026 | No | — | Auto-create HIPU/HIPS/HIPM | DC ZXX escape code; stroke hierarchy; EDM ref tables |
HIGE |
TRIGGER_DISABLE | LRNO, SEQNO, POS_CODE | No | No | — | — | DM≤EFD rule; E45_GS='8' sentinel; ACDC/freq cross-check |
HIMT |
TRIGGER_DISABLE | None (batch) | No | No | — | — | Not cursor-based; AWSH_UPDATES commented out |
MATH |
TRIGGER_DISABLE | LRNO, SEQ, TYPE | No | No | — | MATH.E95_THST_STAT ← HIST.A02_STS | YY consistency rule; NN+power rule; multi-zero constraint |
MAAU |
TRIGGER_DISABLE | LRNO, SEQ, TYPE | No | No | — | — | Complex AC/DC/freq 3-way cross-check |
MAEM1–3 |
TRIGGER_DISABLE + TRIGGER_DISABLE_MAEMn | LRNO, SEQ, TYPE | No | No | — | — | E88_LFAN_IND→OVTY type '6%' check; E88_SEC_IND→PROP_TEXT |
MASP |
TRIGGER_DISABLE | LRNO, SEQ, TYPE | No | No | SSpeed | — | Speed max 60; service→max waterfall; 4 conditional annotation groups |
MABO, MABU, MAGR, MAPR, MAST |
TRIGGER_DISABLE | LRNO, SEQ, TYPE | No | No | — | — | Standard pattern; codebook lookups only |
All MA* triggers maintain a shadow staging table (e.g., ABSD_HIMO_UPDATES, ABSD_MATH_UPDATES). These tables contain the latest complete machinery data for each vessel and are used by downstream processes (ShipWatch feeds, bulk export jobs) to detect changes without polling the main tables. The pattern is always:
IF EXISTS (SELECT * FROM ABSD_XXXX_UPDATES WHERE LRNO = @INDEXLRNO) DELETE FROM ABSD_XXXX_UPDATES WHERE LRNO = @INDEXLRNO INSERT ABSD_XXXX_UPDATES SELECT * FROM ABSD_XXXX WHERE LRNO = @INDEXLRNO
Note: the staging table receives the full set of rows for that LRNO from the base table (not just the single row being changed), so it always reflects all records for the vessel.
All MA* and machinery triggers (except HIMT) use a conditional J06 update to avoid unnecessary writes:
IF NOT (SELECT COUNT(*) FROM ABSD_OVGE
WHERE J06_AUTHOR = @author AND J06_LNCHDATE = @today AND LRNO = @INDEXLRNO) > 0
UPDATE ABSD_OVGE SET J06_AUTHOR = ..., J06_LNCHDATE = ... WHERE LRNO = @INDEXLRNO
This means that if the same editor has already touched the vessel today, the J06 timestamp is not updated again. This differs from the ownership triggers (HIOW, HIMA, HISM) which use spGetUserSettings and always update J06 including J06_LNCHTIME.
As of April 2026, only ABSD_HIMO has been migrated to use EDM reference tables for codebook lookups. All other machinery triggers (HIGE, HIMT, MATH, MAAU, MAEM1–3, MABO, MABU, MAGR, MAPR, MAST, MASP) still reference ABSD_CBUB1, ABSD_CBUB3, and ABSD_CBEB directly.