none
Trigger, Lo ho fatto bene ?? Mi potrebbe generare azioni Rindondanti ??? RRS feed

  • Domanda

  • Ho 1 dubbio su un Trigger che ho appena creato,
    è in assoluto il primo trigger che faccio e lo ho scopiazzato e riadattato dalla rete  :)
    ma non mi sento sicuro anche se ai test sembra funzionare .......

    Ho 3 tabelle
    --- PAp   con il campo PARef  ( Ammette duplicati )
    --- SAp   con il campo SARef  ( Ammette duplicati )
    --- Bar    con il campo Barcode ( Ammette duplicati )
    Nessun indice sui campi interessati quindi non posso fare relazioni ....

    Ho bisogno che modificando in qualunque record di  dbo.PAp.PARef
    vengano modificati i corrispondenti valori di dbo.SAp.SARef e dbo.Bar.Barcode

    Inoltre devo modificare sulla stessa tabella i restanti valori di dbo.PAp.PARef

    Ho il dubbio che venga generata una grande azione rindondante in quanti il
    Trigger si "scatena" su UPDATE di dbo.PAp.PARef e poi lo stesso Trigger
    va a modificare migliaia valori sulla stessa tabella dbo.PAp.PARef

    Temo che il trigger si esegua migliaia di volte   :)))

    USE Uni040; GO CREATE TRIGGER dbo.trAfUp ON dbo.PAp AFTER UPDATE AS DECLARE @OlBar nvarchar(50) DECLARE @NwBar nvarchar(50) SELECT @OlBar = PARef FROM deleted SELECT @NwBar = PARef FROM inserted -- le tre azioni da eseguire UPDATE dbo.SAp SET SARef = @NwBar WHERE SARef = @OlBar ; UPDATE dbo.Bar SET Barcode = @NwBar WHERE Barcode = @OlBar ;
    -- Quando esegue quest'ultima non mi fa ripartire il Trigger ???? UPDATE dbo.PAp SET PARef = @NwBar WHERE PARef = @OlBar GO

    Seconda domanda, visto che è il èrimo Trigger che scrivo,
    è fatto bene in generale,   si puo migliorare,   alternative migliori ?????

    Grazie

    • Modificato Mancini, domenica 18 ottobre 2015 20:07
    domenica 18 ottobre 2015 20:01

Risposte

  • Ciao Mancini,

    il trigger che hai creato funziona solo se viene modificato un record alla volta, nel caso di una update massiva avrà effetto solo su un record, ma probabilmente nel tuo caso va bene così, ma se ad esempio esegui l'update:

    UPATE dbo.PAp SET PARef = PAReg + 'x'

    il trigger non funzionerà per tutte le righe modificate.

    Nell' ultima parte del trigger il valore non viene aggiornato perché in un trigger AFTER UPDATE i campi sono già aggiornati con gli stessi valori della tabella virtuale Inserted quindi il valore del campo PARef corrispondente a @OlBar non esiste più a meno che non esegui una update con lo stesso valore già presente.

    In ogni caso il trigger ripartirebbe solo se nel database è attiva l'opzione Trigger ricorsivi abilitati in caso di opzione attiva riceverai l'errore del superamento massimo di livelli di nidificazione che se non ricordo male sono 32.

    [Aggiunta]

    io farei così il trigger:

    CREATE TRIGGER dbo.trAfUp 
    ON dbo.PAp
    AFTER UPDATE
    
    AS
    -- Aggiorno tabella SAp
    UPDATE dbo.SAp
      SET  SARef = I.Paref
    FROM   INSERTED AS I INNER JOIN DELETED AS D ON I.Id = D.Id
    WHERE  SARef = D.Paref;
    
    -- Aggiorno tabella BAR
    UPDATE dbo.BAR
      SET  Barcode = I.Paref
    FROM   INSERTED AS I INNER JOIN DELETED AS D ON I.Id = D.Id
    WHERE  Barcode = D.Paref

    è necessario un campo che identifichi in modo univoco il record come ad esempio un Identity

    Ciao

    Giorgio Rancati




    lunedì 19 ottobre 2015 08:15
    Moderatore

Tutte le risposte

  • Ciao Mancini,

    il trigger che hai creato funziona solo se viene modificato un record alla volta, nel caso di una update massiva avrà effetto solo su un record, ma probabilmente nel tuo caso va bene così, ma se ad esempio esegui l'update:

    UPATE dbo.PAp SET PARef = PAReg + 'x'

    il trigger non funzionerà per tutte le righe modificate.

    Nell' ultima parte del trigger il valore non viene aggiornato perché in un trigger AFTER UPDATE i campi sono già aggiornati con gli stessi valori della tabella virtuale Inserted quindi il valore del campo PARef corrispondente a @OlBar non esiste più a meno che non esegui una update con lo stesso valore già presente.

    In ogni caso il trigger ripartirebbe solo se nel database è attiva l'opzione Trigger ricorsivi abilitati in caso di opzione attiva riceverai l'errore del superamento massimo di livelli di nidificazione che se non ricordo male sono 32.

    [Aggiunta]

    io farei così il trigger:

    CREATE TRIGGER dbo.trAfUp 
    ON dbo.PAp
    AFTER UPDATE
    
    AS
    -- Aggiorno tabella SAp
    UPDATE dbo.SAp
      SET  SARef = I.Paref
    FROM   INSERTED AS I INNER JOIN DELETED AS D ON I.Id = D.Id
    WHERE  SARef = D.Paref;
    
    -- Aggiorno tabella BAR
    UPDATE dbo.BAR
      SET  Barcode = I.Paref
    FROM   INSERTED AS I INNER JOIN DELETED AS D ON I.Id = D.Id
    WHERE  Barcode = D.Paref

    è necessario un campo che identifichi in modo univoco il record come ad esempio un Identity

    Ciao

    Giorgio Rancati




    lunedì 19 ottobre 2015 08:15
    Moderatore
  • alla risposta già precisa di Giorgio voglio solo aggiungere una sottolineatura alla necessità di avere un campo chiave nelle in ciascuna delle tre tabelle.

    Edoardo Benussi
    Microsoft MVP - Directory Services
    edo[at]mvps[dot]org

    lunedì 19 ottobre 2015 09:57
    Moderatore