! Overview

This page documents miscellaneous triggers that do not fit neatly into vessel, ownership, cargo, structural, casualty, codebook, or supplemental categories. It covers:

  • 1ABSD_NCON — New-construction order register. The most complex trigger in the system: multi-table cascade, OWNC rebuild, EDM country validation (March 2026), and 6 satellite cascades.
  • 2ABSD_NCON_CONFI — Confidential attributes for new-construction orders (shiptype, dimensions, FLAG). Additional FK checks and dimensional cross-checks.
  • 3ABSD_SALE — Sale and scrap transaction records. Writes tblFSWSalesPage, enriched tblChanges audit via fnSalesDetail(), and J06 audit on effective-date change.
  • 4tblChanges — Self-trigger on the primary audit log table. Automatically zero-pads CompanyNo to 7 digits on every insert.
  • 5tblAnnotationLogGeneral — Self-trigger on the annotation log. Automatically populates Source field from the current user's settings on every insert.
  • 6QH_ShipsOwner_Data — Questionnaire response system. One business trigger (updates QH_Questionnaires.LastResponseDate) plus three SQL Server merge-replication infrastructure triggers.
  • 7ofac_sdn2 — OFAC Specially Designated Nationals list. Inserts and deletes write a tblChanges audit record (ChangeType='OFAC').
  • 8PANDI — P&I Club table. No trigger files are present in the Triggers directory; enforcement for this domain is handled elsewhere.

N ABSD_NCON — New Construction Register

ABSD_NCON_Update FOR UPDATE TRIGGER_DISABLE guard

The most complex trigger in the system. Validates new-construction order fields, enforces date rules, cascades to six satellite tables, rebuilds the entire ABSD_OWNC set from scratch, updates SHIP_SEARCH, and writes annotation and staging.

Guard & Cursor

  • 1Standard TRIGGER_DISABLE guard at the top. Cursor iterates over inserted by LRNO.

Country Code Validation — EDM March 2026

EDM Migration (March 2026 — MM): Country code lookups for COB (Country of Build) and PCOB (Previous Country of Build) were migrated from ABSD_CBCY to EDM.dbo.T_REF_COUNTRY with collation Latin1_General_CI_AI. This change was applied in March 2026. Any new country-validation code should target the EDM table, not the local codebook.
  • 2COB must exist in EDM.dbo.T_REF_COUNTRY (collate Latin1_General_CI_AI).
  • 3PCOB (Previous Country of Build) must also exist in EDM.dbo.T_REF_COUNTRY when populated.

Status / Indicator Field Validation

  • 4PIND (Program Indicator) must be one of: N, P, Y, C.
  • 5RIND (Request Indicator) must be Y or NULL.
  • 6SPSIND (Special Survey Indicator) must be Y or NULL.
  • 7COMI (Commercially Ordered flag) validated as Y/N via valStandardYN.
  • 8RET1 (Retention flag) validated as Y/N via valStandardYN.

Date Validation

  • 9DATE_NCON (Order Date): validated via valStandard4_new. Additionally, must not be in the future — enforced by comparing fnrealdatetolrdate(getdate()) against the field value. This is one of the few "future date" blocks in the system.
  • 10CDTE (Keel-laying date), PDTE (Planned delivery), KEST (Estimated keel), LEST (Estimated launch) — all validated via valStandard4_new.

Cascade to Satellite Tables

ABSD_NCSHIP — Cascades order number and vessel link fields.
ABSD_SUBSHIP — Cascades RIND to REQIND field.
ABSD_FREEFORMGNTE (General Notes) is split at 36 characters into GENNOTES (first 36) and GENNOTES2 (remaining 24), preserving the 36+24 mainframe character layout.
ABSD_SUNDRY — Derives and stores COMMQTR, LNCHQTR, and COMPQTR (quarter codes from dates).
ABSD_PREFAB — Cascades PRPOS (Prefab Portion) and PRCOB (Prefab Country).
ABSD_FABNOTE — Cascades fabrication note data.

OWNC Rebuild — Critical Business Rule

Full OWNC Rebuild on Every Update: On every ABSD_NCON update, the trigger deletes all ABSD_OWNC records for the vessel (SHLRNO) and rebuilds them from scratch. The rebuild logic:
  1. Insert from ABSD_HIMA where role = MR (Manager)
  2. Insert from ABSD_HIOW where role = RC (Registered Company)
  3. Exclude company code 9991001 from both sources
This means OWNC is not maintained incrementally — it is always a derived snapshot. Any direct edits to ABSD_OWNC will be overwritten by the next NCON update.

SHIP_SEARCH Update

  • 11Writes DATE_NCON to ABSD_SHIP_SEARCH to keep the search index current.

Annotation & Staging

  • 12Writes annotation record for field C11I (order-date field) grouping.
  • 13Inserts into ABSD_NCON_UPDATES staging table for downstream ETL processing.

C ABSD_NCON_CONFI — Confidential New Construction

ABSD_NCON_CONFI_Update FOR UPDATE TRIGGER_DISABLE guard

Validates confidential new-construction attributes including ship type, hull shape, classification, full vessel dimensions, flag country, and contact details. Writes a tblChanges audit record for Shipname and Shipmanager changes.

Country / Flag Validation — EDM March 2026

EDM Migration (March 2026 — MM): FLAG, PCOB, and COB all validated against EDM.dbo.T_REF_COUNTRY rather than the local ABSD_CBCY codebook.

Codebook FK Checks

  • 1STAT5CODE must exist in tblMasterShipTypeXref.
  • 2HULL_SHAPE must exist in ABSD_CBUB1 where FLDI='11' (hull shape codebook).
  • 3CLASS must exist in ABSD_CBUB1 where FLDI='62' (classification society codebook).
  • 4SHIPTYPE must exist in tblMasterShipTypeXref.inbassub.

Dimension Validation

Shiptype Exemption: Vessels with SHIPTYPE starting with '7' (offshore/non-conventional hulls) are exempt from the LBP>Breadth and LOA>Draught cross-checks. The rationale is that semi-submersibles and similar unusual forms have depth or beam configurations that violate conventional hull geometry rules.
  • 5GROSS and DWT — maximum 7 digits.
  • 6LBP ≤ LOA — Length Between Perpendiculars must not exceed Length Overall.
  • 7LBP > Breadth — LBP must be greater than beam (exempted for shiptype starting with '7').
  • 8LOA > Breadth — LOA must be greater than beam.
  • 9LOA > Maxdraught — LOA must exceed maximum draught.
  • 10LBP > Maxdraught — LBP must exceed maximum draught.

Date Validation

  • 11DATE_NCON, CDTE, KEST, LEST — all validated via valStandard4.

tblChanges Audit

  • 12Writes to tblChanges when Shipname changes — old and new values recorded.
  • 13Writes to tblChanges when Shipmanager changes — old and new values recorded.
  • 14Uses standard historical awareness: when the record is not current (SEQ ≠ '00'), the ChangeType is prefixed to indicate a historical amendment.
FieldValidationSource
FLAGFK existsEDM.dbo.T_REF_COUNTRY (Mar 2026)
PCOBFK existsEDM.dbo.T_REF_COUNTRY (Mar 2026)
COBFK existsEDM.dbo.T_REF_COUNTRY (Mar 2026)
STAT5CODEFK existstblMasterShipTypeXref
HULL_SHAPEFK existsABSD_CBUB1 FLDI='11'
CLASSFK existsABSD_CBUB1 FLDI='62'
SHIPTYPEFK in inbassubtblMasterShipTypeXref
GROSS, DWTmax 7 digits
LBP ≤ LOAcross-check
LBP > Breadthcross-check (exemption: shiptype '7*')
LOA > Breadthcross-check
LOA > Maxdraughtcross-check
LBP > Maxdraughtcross-check
DATE_NCON, CDTE, KEST, LESTvalStandard4

$ ABSD_SALE — Sale and Scrap Records

absd_sale_update FOR UPDATE TRIGGER_DISABLE guard

Manages the full lifecycle of sale and scrap transaction records. Writes to the vessel sales page (tblFSWSalesPage) when the effective date changes, produces enriched audit entries in tblChanges via fnSalesDetail(), and applies historical-awareness logic based on sequence number.

Guard & Cursor

  • 1Standard TRIGGER_DISABLE guard. Cursor iterates over inserted by LRNO + SEQ_NO.

Sales Page Integration (SEQ='00' only)

  • 2When SALE_EFD (Sale Effective Date) changes AND the record is current (SEQ_NO = '00'), updates tblFSWSalesPage to set the sale status to 'S' (Sold).
  • 3Historical records (SEQ_NO ≠ '00') do not trigger a tblFSWSalesPage update — only the current record drives the sales page status.

tblChanges Audit

  • 4Writes to tblChanges when Reported_Sold_To is not empty, OR when Sale_Price_USD > 0.
  • 5The Notes field in tblChanges is populated using the scalar function dbo.fnSalesDetail(), which formats a rich human-readable summary of the sale (price, currency, buyer, date, etc.).
  • 6Historical-awareness: When SEQ_NO ≠ '00', the ChangeType is prefixed with "Made historical" or "Historical amendment" to distinguish historical-record edits from current-record edits.

Annotation

  • 7Writes an annotation record for field group Sale_Efd (sale effective date grouping).
  • 8J06 audit is written when SALE_EFD changes.
ABSD_SALE_DELETE FOR DELETE TRIGGER_DISABLE guard

Records the deletion of a sale record as an "Erroneous sales report" in tblChanges. Only fires for current-record deletions (SEQ='00').

Business Rules

  • 1Standard TRIGGER_DISABLE guard. Cursor iterates over deleted.
  • 2Only processes records where SEQ = '00' — deletion of historical records does not generate a tblChanges entry.
  • 3Writes to tblChanges:
    • OldValue = 'Deleted'
    • NewValue = 'Deleted'
    • Notes = 'Erroneous sales report -' + dbo.fnSalesDetail()
  • 4Writes J06 audit record.
The "Erroneous sales report" prefix is hard-coded. This means the tblChanges record clearly communicates why the sale was deleted, not just that it was deleted. The full sale detail (buyer, price, date) is still appended via fnSalesDetail() for traceability.

A Audit Infrastructure Self-Triggers

These two triggers fire on the audit tables themselves (tblChanges and tblAnnotationLogGeneral). They are infrastructure triggers: every other trigger in the system that writes to these tables will automatically trigger these in turn, without needing to know about them. They exist to enforce invariants that would otherwise require every calling trigger to implement individually.
tblChanges_Insert FOR INSERT TRIGGER_DISABLE guard

Self-trigger on the tblChanges audit table. Automatically normalises CompanyNo to 7-digit zero-padded format on every insert, so that audit consumers always see a uniform company number format regardless of how the calling trigger formatted it.

Business Rules

  • 1Standard TRIGGER_DISABLE guard. Cursor iterates over inserted rows.
  • 2CompanyNo normalisation: If LEN(CompanyNo) < 7, pad with leading zeros to exactly 7 digits. Example: '1234''0001234'.
  • 3If CompanyNo is already 7 or more digits, no change is made.
  • 4This runs on every insert into tblChanges — including inserts made by OW* company triggers, SALE triggers, OFAC triggers, and any other system that writes to tblChanges.
Why a Self-Trigger: Rather than making every individual trigger responsible for zero-padding CompanyNo, this single self-trigger centralises the enforcement. If a calling trigger omits the padding, this trigger corrects it silently. This is a defensive normalisation pattern.
tblAnnotationLogGeneral_Insert FOR INSERT No TRIGGER_DISABLE guard

Self-trigger on the tblAnnotationLogGeneral annotation table. Automatically populates the Source field on every new annotation entry by looking up the current user's source setting from tblUserSettings. This means callers never need to supply Source — it is always resolved at insert time from the user context.

Business Rules

  • 1No TRIGGER_DISABLE guard. The trigger fires unconditionally on every insert into tblAnnotationLogGeneral.
  • 2On each new annotation row: looks up tblUserSettings.currentsource WHERE username = SYSTEM_USER.
  • 3Sets the Source field of the newly inserted annotation row to the retrieved currentsource value.
  • 4If SYSTEM_USER has no row in tblUserSettings, Source remains as supplied by the caller (or NULL).
No TRIGGER_DISABLE Guard: This trigger lacks the standard TRIGGER_DISABLE guard. It fires even when TRIGGER_DISABLE has a row. This is intentional — the Source auto-population should happen regardless of whether bulk-load mode is active, so that annotation provenance is always recorded.
MechanismDetail
Source lookupSELECT currentsource FROM tblUserSettings WHERE username = SYSTEM_USER
Applied toEvery INSERT into tblAnnotationLogGeneral
EffectCallers do not need to set Source — it is always resolved from session context
GuardNone — fires even in bulk-load mode

Q QH_ShipsOwner_Data — Questionnaire System

Replication Triggers: Three of the four triggers on QH_ShipsOwner_Data are SQL Server merge-replication infrastructure triggers auto-generated by SQL Server. They have GUIDs in their names (del_A3FCC..., ins_A3FCC..., upd_A3FCC...) and contain no business logic — they maintain the merge replication change-tracking tables (ctsv_... and tsvw_...). They all exit immediately when sessionproperty('replication_agent') = 1 and trigger_nestlevel() = 1, preventing infinite replication loops. These are not documented in detail as they are system-managed.
QH_shipsOwner_Data_UpdateTrigger FOR INSERT UPDATE DELETE No guard

Business trigger for the ship-owner questionnaire system. When a questionnaire response record is actioned, updates the parent questionnaire's LastResponseDate to the current datetime.

Business Rules

  • 1Fires on INSERT, UPDATE, and DELETE — but reads the ActionType from the Inserted table.
  • 2Only executes the business logic when ActionType = 'R' (Response). Other action types are silently ignored.
  • 3When ActionType = 'R': updates QH_Questionnaires.LastResponseDate = GetDate() for the matching QH_Questionnaires.ID = Inserted.QuestID.
  • 4No TRIGGER_DISABLE guard — fires regardless of bulk-load mode.
The trigger fires on DELETE as well as INSERT/UPDATE, but the ActionType = 'R' check reads from Inserted which is empty on a DELETE — so the LastResponseDate update cannot fire on deletes. The FOR DELETE is present to make the trigger fire on all operations, likely for future extensibility.
TriggerTypePurpose
QH_shipsOwner_Data_UpdateTriggerBusinessActionType='R' → update QH_Questionnaires.LastResponseDate
del_A3FCCDB257C64C08AB9FEA7D543EDF32ReplicationMerge replication DELETE tracking (system-managed)
ins_A3FCCDB257C64C08AB9FEA7D543EDF32ReplicationMerge replication INSERT tracking (system-managed)
upd_A3FCCDB257C64C08AB9FEA7D543EDF32ReplicationMerge replication UPDATE tracking, prevents rowguid updates
del / ins / upd _A3FCCDB257C64C08AB9FEA7D543EDF32 INSERT UPDATE DELETE Replication guard

SQL Server merge-replication change-tracking triggers (system-generated). These maintain ctsv_/tsvw_ tracking tables and must not be modified manually.

  • 1All three triggers exit immediately if sessionproperty('replication_agent') = 1 AND trigger_nestlevel() = 1 — prevents replication loops.
  • 2del_*: On delete, records rowguid + type=1 ('delete') into tsvw_A3FCC... with UPDATELINEAGE tracking. Removes the row from ctsv_A3FCC....
  • 3ins_*: On insert, tracks the new row in ctsv_A3FCC... with lineage and column-vector (colv1). Handles 41 columns (@ccols = 41). Special logic for re-insert of a previously deleted rowguid (increments version counter).
  • 4upd_*: On update, updates lineage and colv1 bit-map in ctsv_A3FCC... via UPDATECOLVBM. Prevents rowguid column updates (RAISERROR 20062 and rollback).
  • 5All three use tablenick = 8648000 to identify the article in sysmergearticles.
  • 6All use ANSI_NULLS OFF (note the SET at the top) — this is the standard SQL Server replication trigger pattern.

O ofac_sdn2 — OFAC Sanctions List

OFAC — US Treasury Sanctions: The ofac_sdn2 table contains the OFAC Specially Designated Nationals (SDN) list maintained by the US Treasury. The triggers on this table write a tblChanges audit record every time a vessel is added to or removed from the SDN list. The IMO field maps to LRNo in tblChanges, and the identifier field carries the SDN designation code.
OFAC_INSERT FOR INSERT No TRIGGER_DISABLE guard

Records the addition of a vessel to the OFAC SDN sanctions list in tblChanges. No business validation — pure audit trail.

  • 1No TRIGGER_DISABLE guard — fires unconditionally on every insert.
  • 2Inserts one row per inserted row into tblChanges:
    • LRNo = i.IMO (maps OFAC IMO number to vessel LRNO)
    • CompanyNo = NULL
    • EffDate = CAST(getdate() AS varchar)
    • ChangeType = 'OFAC'
    • Source = 'OFAC'
    • OldValue = NULL
    • NewValue = i.identifier (the SDN designation added)
    • Confidential = 0
OFAC_DELETE FOR DELETE No TRIGGER_DISABLE guard

Records the removal of a vessel from the OFAC SDN sanctions list in tblChanges. No business validation — pure audit trail.

  • 1No TRIGGER_DISABLE guard — fires unconditionally on every delete.
  • 2Inserts one row per deleted row into tblChanges:
    • LRNo = d.IMO
    • CompanyNo = NULL
    • EffDate = CAST(getdate() AS varchar)
    • ChangeType = 'OFAC'
    • Source = 'OFAC'
    • OldValue = d.identifier (the SDN designation removed)
    • NewValue = NULL
    • Confidential = 0
OldValue / NewValue Pattern: OFAC_INSERT sets OldValue=NULL, NewValue=identifier (something appeared). OFAC_DELETE sets OldValue=identifier, NewValue=NULL (something disappeared). This is the standard tblChanges pattern used throughout the system for add/remove events. The tblChanges_Insert self-trigger will also fire on these insertions, but since CompanyNo = NULL, the zero-padding rule is a no-op.
TriggerEventOldValueNewValueChangeType
OFAC_INSERTVessel added to SDN listNULLidentifier'OFAC'
OFAC_DELETEVessel removed from SDN listidentifierNULL'OFAC'

P PANDI — P&I Club

No Trigger Files Found: A search of the Triggers/ directory for dbo.ABSD_PAND*.sql and related patterns returned no results. The PANDI (Protection & Indemnity Club) table does not have any trigger files scripted out in this deployment. P&I club changes may be enforced at the application layer, handled by a stored procedure, or this table may be populated via a feed with no trigger-based rules. If trigger files exist on the live server but were not scripted, they should be scripted and added to this documentation.

X Complete Trigger Reference

Table Trigger Operation Guard Key Output
ABSD_NCONABSD_NCON_UpdateUPDATETRIGGER_DISABLEEDM COB/PCOB validation; 6 satellite cascades; OWNC rebuild; SHIP_SEARCH; annotation C11I; NCON_UPDATES staging
ABSD_NCON_CONFIABSD_NCON_CONFI_UpdateUPDATETRIGGER_DISABLEEDM FLAG validation; STAT5/HULL/CLASS/SHIPTYPE FK; dimensional cross-checks; tblChanges Shipname/Shipmanager
ABSD_SALEabsd_sale_updateUPDATETRIGGER_DISABLESALE_EFD → tblFSWSalesPage status='S'; tblChanges via fnSalesDetail(); annotation Sale_Efd; J06
ABSD_SALEABSD_SALE_DELETEDELETETRIGGER_DISABLESEQ='00' → tblChanges 'Erroneous sales report -' + fnSalesDetail(); J06
tblChangestblChanges_InsertINSERTTRIGGER_DISABLEZero-pad CompanyNo to 7 digits if len<7
tblAnnotationLogGeneraltblAnnotationLogGeneral_InsertINSERTNoneAuto-populate Source from tblUserSettings.currentsource for SYSTEM_USER
QH_ShipsOwner_DataQH_shipsOwner_Data_UpdateTriggerINSERT/UPDATE/DELETENoneActionType='R' → QH_Questionnaires.LastResponseDate = GetDate()
QH_ShipsOwner_Datadel_A3FCC...DELETERepl. agent checkMerge replication change-tracking (system-managed)
QH_ShipsOwner_Datains_A3FCC...INSERTRepl. agent checkMerge replication change-tracking (system-managed)
QH_ShipsOwner_Dataupd_A3FCC...UPDATERepl. agent checkMerge replication change-tracking; blocks rowguid updates
ofac_sdn2OFAC_INSERTINSERTNonetblChanges ChangeType='OFAC', NewValue=identifier
ofac_sdn2OFAC_DELETEDELETENonetblChanges ChangeType='OFAC', OldValue=identifier
PANDINo trigger files found

D Design Patterns in This Page

PatternWhere UsedPurpose
Future-date blockABSD_NCON DATE_NCONOrders cannot be dated in the future; uses fnrealdatetolrdate(getdate()) for comparison
Full-rebuild delete+insertABSD_NCON → ABSD_OWNCEvery NCON update rebuilds all OWNC records from scratch; OWNC is a derived snapshot, not independently maintained
GNTE split at 36/24ABSD_NCON → ABSD_FREEFORMMainframe 60-char field split into two ABSD columns to preserve fixed-width layout
Enriched audit via functionABSD_SALE → tblChangesfnSalesDetail() formats a human-readable sale summary; no other trigger uses this pattern
Self-trigger normalisationtblChanges_InsertInfrastructure trigger corrects CompanyNo format centrally, relieving callers of this responsibility
Self-trigger source resolutiontblAnnotationLogGeneral_InsertSource populated from session context, not from the calling trigger
ActionType field dispatchQH_shipsOwner_Data_UpdateTriggerSingle FOR INSERT/UPDATE/DELETE trigger dispatches on ActionType value rather than having multiple triggers
OFAC add/remove auditOFAC_INSERT / OFAC_DELETEOldValue/NewValue=NULL pattern: INSERT sets NewValue, DELETE sets OldValue
EDM country migrationNCON, NCON_CONFIMarch 2026 migration of FLAG/COB/PCOB from ABSD_CBCY to EDM.dbo.T_REF_COUNTRY