Inhaltsverzeichnis
3.3 ENIVERSPIMS — Sicherheitsgespräche
Stand: 2026-03-05
Übergeordnet: PIMS-Architektur — Gesamtübersicht Verwandt: 3.1 Prüfwesen | 3.2 Arbeitsaufträge
Ausgangslage: Zwei parallele Systeme
Sicherheitsgespräche / SIL-Bewertungen werden in zwei getrennten Legacy-Systemen geführt:
| Merkmal | AMED EZASichGesp | ENIVERS tblSicherheitGespraech |
|---|---|---|
| Datensätze | 5.862 Zeilen | 60 Zeilen |
| Spaltenanzahl | 73 | 59 |
| Primärschlüssel | IDEZA (FK → EZAMASTER) | idSicherheitGespraech |
| Verknüpfung | pro EZA-Objekt (Instrument/Sensor) | pro Anlage/Schutzziel (fiSigBetrieb) |
| Risikodimensionen | SCHADENAUSMASS, AUFENTHALTSDAUER, GEFAHRENABWEICHUNG, EINTRITTSWAHRSCHEINL | intSigAusmassSchaden, intSigAufenthaltGefahrBereich, intSigVermeidungGefahr, intSigEintrittWahrscheinlichkeit |
| SIL-Feld | SIL (tinyint) | strSbWertSIL (via tblSicherheitBaum) |
| Klassifizierung | Klassif_A/B/C/X (bits), Risikoklasse | strSbKennbuchstaben, Klassifizierung, Status |
| Rechtl. Anforderungen | 10 bit-Flags (Dampfk_V, VAWS, VBF, …) | bln*-Felder |
| Aktor/Sensor-Daten | 8×(Schalt_Klassi, Kontakt, Grenzwert) — denormalisiert | tblSicherheitGespraechAktorSensor (normalisiert) |
| Unterschriften | — (nicht vorhanden) | tblSicherheitUnterschrift |
| Alarmschwellen | — (nicht vorhanden) | strSigMinVoralarm … strSigMaxAbschaltung2 |
| Schutzziel-Freitext | — (nicht vorhanden) | memSigSchutzziel (nvarchar MAX) |
Kernunterschiede
- AMED EZASichGesp = Sicherheitsgespräch pro EZA-Instrument/Aktor (Mikroebene).
Fokus: Klassifikation (A/B/C/X), gesetzliche Anforderungen, Risikoklasse, SIL-Ergebnis.
- ENIVERS tblSicherheitGespraech = SIL-Bewertung pro Schutzziel (Makroebene).
Fokus: Schutzziel-Freitext, Alarmschwellen, strukturierte AktorSensor-Liste, Unterschriften.
Beide basieren auf derselben 4-dimensionalen Risikomatrix (Schadensausmaß × Aufenthaltsdauer × Vermeidbarkeit × Eintrittswahrscheinlichkeit → SIL).
Merge-Strategie: "Must Have" ohne Datenverlust
Prinzip: gemeinsame Tabelle + conversation_type-Unterscheidung
Ein Merge ist möglich, weil der strukturelle Kern identisch ist. Quell-spezifische Felder werden erhalten — entweder als echte Spalten oder als JSON.
AMED EZASichGesp ──► safety.conversation (type='EZA')
│
conversation_actor_sensor
(aus 8×denorm. Spalten normalisiert)
ENIVERS tblSgEspr ──► safety.conversation (type='SCHUTZZIEL')
│
conversation_actor_sensor
(aus tblSicherheitGespraechAktorSensor)
│
conversation_justification
(aus tblSicherheitGespraechBegruendung)
│
conversation_signature
(aus tblSicherheitUnterschrift)
Migration ohne Datenverlust
- Alle
legacy_id+legacy_sourcebleiben erhalten → bidirektionale Traceability - Denormalisierte Spalten (EZASichGesp.Schalt_Klassi1–8 × 3 = 24 Spalten) → normalisiert in
conversation_actor_sensor(max. 8 Zeilen pro Gespräch) - Quell-spezifische Felder ohne Entsprechung auf der anderen Seite →
extended_data NVARCHAR(MAX)als JSON
safety.conversation
CREATE TABLE safety.conversation ( id INT NOT NULL IDENTITY PRIMARY KEY, conversation_type VARCHAR(20) NOT NULL, -- 'EZA' | 'SCHUTZZIEL' -- Verknüpfung item_id INT NULL, -- FK → ENIVERSCAFM.asset.item (für EZA) branch_id INT NULL, -- FK → ENIVERSCAFM.org.branch (für SCHUTZZIEL) -- Identifikation bau_nummer NVARCHAR(20) NULL, -- Bau-/RI-Nummer ri_fliessbild_nr NVARCHAR(20) NULL, -- R&I-Fließbild Nummer (tblSgEspr: strSigRiFliessbild) blatt_nummer INT NULL, -- Blattnummer anlage_teil NVARCHAR(50) NULL, bezeichnung NVARCHAR(200) NULL, schutzziel NVARCHAR(MAX) NULL, -- Schutzziel-Freitext (nur tblSgEspr) -- Risikomatrix (beide Systeme, 4 Dimensionen) risk_damage SMALLINT NULL, -- Schadensausmaß risk_presence SMALLINT NULL, -- Aufenthaltsdauer risk_avoidance SMALLINT NULL, -- Gefahrenvermeidung/-abweichung risk_probability SMALLINT NULL, -- Eintrittswahrscheinlichkeit -- Ergebnis sil_required TINYINT NULL, -- geforderter SIL (aus Risikomatrix) sil_achieved TINYINT NULL, -- erreichter SIL (aus MSR-Maßnahmen) risk_class NVARCHAR(5) NULL, -- Risikoklasse classification NVARCHAR(5) NULL, -- A / B / C / X -- Klassif.-bits (EZA): als JSON gespeichert klassif_a BIT NULL, klassif_b BIT NULL, klassif_c BIT NULL, klassif_x BIT NULL, -- Gesetzliche Anforderungen (EZA: 10 bit-Flags → JSON) legal_flags NVARCHAR(MAX) NULL, -- Technische Ausführung MSR techn_msr_notes NVARCHAR(MAX) NULL, -- Alarmschwellen (tblSgEspr: 4 Werte → JSON) alarm_thresholds NVARCHAR(MAX) NULL, -- Funktionsbeschreibung (EZASichGesp.Funktion) function_desc NVARCHAR(MAX) NULL, -- Abschluss done_at DATETIME2 NULL, -- Erweiterungs-JSON (quell-spezifische Felder ohne allg. Entsprechung) extended_data NVARCHAR(MAX) NULL, -- Migration legacy_id INT NULL, legacy_source VARCHAR(20) NULL, -- 'AMED_EZA' | 'ENIVERS_LD' -- Audit created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(), updated_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(), created_by INT NULL, updated_by INT NULL )
safety.conversation_actor_sensor
Normalisiert die denormalisierten EZASichGesp-Spalten (Schalt_Klassi1–8, Kontakt1–8, Grenzwert1–8) und tblSicherheitGespraechAktorSensor in eine gemeinsame Tabelle:
CREATE TABLE safety.conversation_actor_sensor ( id INT NOT NULL IDENTITY PRIMARY KEY, conversation_id INT NOT NULL, -- FK → safety.conversation sort_order SMALLINT NOT NULL DEFAULT 0, -- Identifikation plt_stelle NVARCHAR(100) NULL, -- PLT-Stelle / Funktionsbezeichnung typ NVARCHAR(50) NULL, -- Aktor- oder Sensortyp nummer NVARCHAR(50) NULL, -- Geräte-/KKS-Nummer -- Aktor-Wirkung (aus tblSgEspr) aktor_wirkung NVARCHAR(100) NULL, aktor_stellung NVARCHAR(100) NULL, -- Sensor-Messbereich (aus tblSgEspr) messbereich_von DECIMAL(10,4) NULL, messbereich_bis DECIMAL(10,4) NULL, einheit NVARCHAR(20) NULL, -- Klassifizierung (aus EZASichGesp Schalt_Klassi1–8) klassifizierung NVARCHAR(10) NULL, kontakt NVARCHAR(10) NULL, grenzwert NVARCHAR(20) NULL, grenzwert_einheit NVARCHAR(10) NULL, -- Belegung (aus tblSgEspr.fiSgasBelegung) belegung_id INT NULL, -- Sonstiges zusatz_info NVARCHAR(500) NULL )
safety.conversation_signature
CREATE TABLE safety.conversation_signature ( id INT NOT NULL IDENTITY PRIMARY KEY, conversation_id INT NOT NULL, -- FK → safety.conversation sort_order INT NOT NULL, name NVARCHAR(150) NULL, title NVARCHAR(150) NULL, signed_at DATETIME2 NULL )
safety.conversation_justification
Begründungsstruktur aus tblSicherheitGespraechBegruendung (SIL-Stufenbegründung):
CREATE TABLE safety.conversation_justification ( id INT NOT NULL IDENTITY PRIMARY KEY, conversation_id INT NOT NULL, -- FK → safety.conversation level_code VARCHAR(5) NULL, -- Stufe (intSbStufe / strSbText) text NVARCHAR(1024) NULL )
tblSicherheitBaum — Risikomatrix-Lookup
Die LD-Tabelle tblSicherheitBaum ist ein Lookup für die 4-dimensionale Risikomatrix
(Schadensausmaß × Aufenthaltsdauer × Vermeidbarkeit × Eintrittswahrscheinlichkeit → SIL-Wert).
Sie wird als seed data in shared.list_item oder als separate kleine Tabelle migriert:
CREATE TABLE safety.risk_matrix ( id INT NOT NULL IDENTITY PRIMARY KEY, damage_code VARCHAR(5) NOT NULL, presence_code VARCHAR(5) NULL, avoidance_code VARCHAR(5) NULL, probability_code VARCHAR(5) NOT NULL, sil_label VARCHAR(10) NULL, -- 'SIL 1', 'SIL 2', 'SIL 3', 'k' ak_label VARCHAR(10) NULL, -- Anforderungsklasse UNIQUE (damage_code, presence_code, avoidance_code, probability_code) ) -- Migration: alle Zeilen aus tblSicherheitBaum
Migrations-SQL-Skizze
-- 1. AMED EZASichGesp → safety.conversation (type='EZA') INSERT INTO safety.conversation ( conversation_type, item_id, risk_damage, risk_presence, risk_avoidance, risk_probability, sil_required, risk_class, klassif_a, klassif_b, klassif_c, klassif_x, techn_msr_notes, function_desc, done_at, legal_flags, legacy_id, legacy_source, created_at, updated_at ) SELECT 'EZA', i.id, -- asset.item.id via IDEZA → EZAMASTER → APPMASTER → asset.item (legacy_id) e.Schadenausmass_kurz, e.Aufenthaltsdauer_kurz, e.Gefahrenabweichung_kurz, e.Eintrittswahrscheinlichkeit_kurz, e.SIL, e.Risikoklasse, e.Klassif_A, e.Klassif_B, e.Klassif_C, e.Klassif_X, e.TECHN_AUSFUHR_MSR, e.Funktion, e.Done, -- legal_flags als JSON aus den 10 bit-Spalten: (SELECT e.Dampfk_V AS dampfk_v, e.VAWS AS vaws, e.VBF AS vbf, e.Gasbrenner AS gasbrenner, e.Stoerf_V AS stoerf_v, e.Einleitb AS einleitb, e.UVV_VBG AS uvv_vbg, e.Druckb_V AS druckb_v, e.Genehmigungsb AS genehmigungsb, e.Sonst_V AS sonst_v FOR JSON PATH, WITHOUT_ARRAY_WRAPPER), e.IDEZA, 'AMED_EZA', e.dtmEsgCreated, e.dtmEsgUpdated FROM [AMED].[dbo].[EZASichGesp] e LEFT JOIN ENIVERSCAFM.asset.item i ON i.legacy_id = CAST( -- IDEZA → EZAMASTER.erwAppNr → asset.item.legacy_id (SELECT CAST(m.erwAppNr AS VARCHAR) FROM [AMED].[dbo].[EZAMASTER] m WHERE m.IDEZA = e.IDEZA) AS VARCHAR) AND i.legacy_source = 'AMED'; -- 2. Denormalisierte Aktor-Spalten in conversation_actor_sensor auffalten -- (Schalt_Klassi1..8 × Kontakt1..8 × Grenzwert1..8 → 8 Zeilen pro Gespräch) INSERT INTO safety.conversation_actor_sensor (conversation_id, sort_order, klassifizierung, kontakt, grenzwert, grenzwert_einheit) SELECT c.id, v.ord, v.klassi, v.kont, v.grenz, v.grenzeinh FROM safety.conversation c JOIN [AMED].[dbo].[EZASichGesp] e ON e.IDEZA = c.legacy_id AND c.legacy_source = 'AMED_EZA' CROSS APPLY (VALUES (1, e.Schalt_Klassi1, e.Kontakt1, e.Grenzwert1, e.Grenzwerteinh1), (2, e.Schalt_Klassi2, e.Kontakt2, e.Grenzwert2, e.Grenzwerteinh2), -- ... bis 8 (8, e.Schalt_Klassi8, e.Kontakt8, e.Grenzwert8, e.Grenzwerteinh8) ) AS v(ord, klassi, kont, grenz, grenzeinh) WHERE COALESCE(v.klassi, v.kont, v.grenz) IS NOT NULL;