# Triggers Database Questa cartella contiene la documentazione di tutti i 19 triggers del database (esclusi quelli di sistema APEX). ## Triggers Generazione ID Questi triggers generano automaticamente gli ID tramite sequence. | Trigger | Tabella | Sequence | Evento | |---------|---------|----------|--------| | [EVENTI_TRG](EVENTI_TRG.md) | EVENTI | EVENTI_SEQ | BEFORE INSERT | | [EVENTI_DET_PREL_TRG](EVENTI_DET_PREL_TRG.md) | EVENTI_DET_PREL | EVENTI_DET_PREL_SEQ | BEFORE INSERT | | [EVENTI_DET_RIS_TRG](EVENTI_DET_RIS_TRG.md) | EVENTI_DET_RIS | EVENTI_DET_RIS_SEQ | BEFORE INSERT | | [EVENTI_DET_DEGUST_TRG](EVENTI_DET_DEGUST_TRG.md) | EVENTI_DET_DEGUST | EVENTI_DET_DEGUST_SEQ | BEFORE INSERT | | [EVENTI_ACCONTI_TRG](EVENTI_ACCONTI_TRG.md) | EVENTI_ACCONTI | EVENTI_ACCONTI_SEQ | BEFORE INSERT | | [EVENTI_ALTRICOSTI_TRG](EVENTI_ALTRICOSTI_TRG.md) | EVENTI_ALTRICOSTI | EVENTI_ALTRICOSTI_SEQ | BEFORE INSERT | | [EVENTI_ALLEG_TRG](EVENTI_ALLEG_TRG.md) | EVENTI_ALLEG | EVENTI_ALLEG_SEQ | BEFORE INSERT | | [CLIENTI_TRG](CLIENTI_TRG.md) | CLIENTI | CLIENTI_SEQ2 | BEFORE INSERT | | [LOCATION_TRG](LOCATION_TRG.md) | LOCATION | LOCATION_SEQ | BEFORE INSERT | | [RISORSE_TRG](RISORSE_TRG.md) | RISORSE | RISORSE_SEQ | BEFORE INSERT | | [ARTICOLI_DET_REGOLE_TRG](ARTICOLI_DET_REGOLE_TRG.md) | ARTICOLI_DET_REGOLE | ARTICOLI_DET_REGOLE_SEQ | BEFORE INSERT | | [TB_TIPI_PASTO_TRG](TB_TIPI_PASTO_TRG.md) | TB_TIPI_PASTO | TB_TIPI_PASTO_SEQ | BEFORE INSERT | ## Triggers Business Logic | Trigger | Tabella | Descrizione | |---------|---------|-------------| | [EVENTI_TRG](EVENTI_TRG.md) | EVENTI | Inizializza STATO=100, DATA_DOC, VERS_TOKEN | | [EVENTI_AI_TRG](EVENTI_AI_TRG.md) | EVENTI | Crea 4 record ospiti default (AFTER INSERT) | | [EVENTI_DET_OSPITI_TRG_AI](EVENTI_DET_OSPITI_TRG_AI.md) | EVENTI_DET_OSPITI | Gestione aggiornamento ospiti | | [EVENTI_DET_PREL_QTA_TOT_TRG](EVENTI_DET_PREL_QTA_TOT_TRG.md) | EVENTI_DET_PREL | Calcola QTA totale su UPDATE | ## Triggers Ordinamento | Trigger | Tabella | Descrizione | |---------|---------|-------------| | [ADD_COD_STEP](ADD_COD_STEP.md) | TB_TIPI_MAT | Assegna COD_STEP progressivo | | [ON_DELETE_REORDER](ON_DELETE_REORDER.md) | TB_TIPI_MAT | Riordina COD_STEP dopo DELETE | ## Triggers Sistema | Trigger | Tabella | Descrizione | |---------|---------|-------------| | [BI_GL_SCHEMA_CHANGES](BI_GL_SCHEMA_CHANGES.md) | GL_SCHEMA_CHANGES | Log modifiche schema | | [XLIB_LOGS_BI_TRG](XLIB_LOGS_BI_TRG.md) | XLIB_LOGS | Timestamp log | ## Dettaglio Triggers Critici ### EVENTI_TRG ```sql BEFORE INSERT ON EVENTI FOR EACH ROW ``` **Logica:** 1. Genera ID da sequence 2. Imposta `DATA_DOC = SYSDATE` 3. Se INSERT: - `STATO = NVL(:NEW.STATO, 100)` - Se `VERS_NUMBER = 0`: genera `VERS_TOKEN` random ### EVENTI_AI_TRG ```sql AFTER INSERT ON EVENTI FOR EACH ROW ``` **Logica:** Inserisce automaticamente i 4 tipi ospiti: - COD_TIPO_OSPITE = 8 (Adulti), ORDINE = 1 - COD_TIPO_OSPITE = 5 (Kinder), ORDINE = 2 - COD_TIPO_OSPITE = 6 (Baby), ORDINE = 3 - COD_TIPO_OSPITE = 7 (Staff), ORDINE = 4 ### EVENTI_DET_PREL_QTA_TOT_TRG ```sql BEFORE UPDATE ON EVENTI_DET_PREL FOR EACH ROW ``` **Logica:** ```sql :NEW.QTA := :NEW.QTA_APE + :NEW.QTA_SEDU + :NEW.QTA_BUFDOL + :NEW.QTA_MAN_APE + :NEW.QTA_MAN_SEDU + :NEW.QTA_MAN_BUFDOL ``` ## Migrazione .NET ### Sostituzione Sequence → Identity ```csharp // Entity Framework Configuration modelBuilder.Entity() .Property(e => e.Id) .UseIdentityColumn(); ``` ### Sostituzione Trigger → SaveChanges Interceptor ```csharp public class EventiSaveChangesInterceptor : SaveChangesInterceptor { public override ValueTask> SavingChangesAsync( DbContextEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) { var context = eventData.Context; foreach (var entry in context.ChangeTracker.Entries()) { if (entry.State == EntityState.Added) { // Logica EVENTI_TRG entry.Entity.Stato ??= 100; entry.Entity.DataDoc = DateTime.Now; if (entry.Entity.VersNumber == 0) { entry.Entity.VersToken = GenerateRandomToken(); } } else if (entry.State == EntityState.Modified) { entry.Entity.DataDoc = DateTime.Now; } } // Logica EVENTI_DET_PREL_QTA_TOT_TRG foreach (var entry in context.ChangeTracker.Entries()) { if (entry.State == EntityState.Modified || entry.State == EntityState.Added) { entry.Entity.Qta = entry.Entity.CalcolaQuantitaTotale(); } } return base.SavingChangesAsync(eventData, result, cancellationToken); } } ``` ### Creazione Ospiti Default ```csharp public override async Task SaveChangesAsync(CancellationToken ct = default) { var newEvents = ChangeTracker.Entries() .Where(e => e.State == EntityState.Added) .Select(e => e.Entity) .ToList(); var result = await base.SaveChangesAsync(ct); // Logica EVENTI_AI_TRG foreach (var evento in newEvents) { var tipiOspiti = new[] { (8, 1), (5, 2), (6, 3), (7, 4) }; foreach (var (tipo, ordine) in tipiOspiti) { EventiDetOspiti.Add(new EventiDetOspiti { IdEvento = evento.Id, CodTipoOspite = tipo.ToString(), Numero = 0, Ordine = ordine }); } await base.SaveChangesAsync(ct); } return result; } ```