2013-01-18 20 views
6

Come posso evitare problemi di blocco tra due trigger che si attivano sullo stesso evento sulla stessa tabella?Due diversi trigger di aggiornamento per la stessa tabella

Il DB su cui sto lavorando ha già un trigger di aggiornamento crittografato e pertanto non posso modificarlo. Ho fatto un altro trigger di aggiornamento per eseguire alcune nuove attività, funziona correttamente quando eseguo il test direttamente sul database, ma non riesco quando faccio un aggiornamento a un prodotto sull'applicazione front-end. Apparentemente, quando ho il mio trigger attivo, entrambi i trigger falliscono. Il messaggio che ottengo è qualcosa come "Documento già aperto, incrementerò il suo valore".

Si tratta di un problema di blocco?

C'è un related question dove qualcuno dice che possiamo avere più di un trigger (per lo stesso evento) su un tavolo.

Ecco il mio codice trigger:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE TRIGGER [dbo].[tr_st_rep_update] 
ON [dbo].[st] 
AFTER UPDATE 
AS 
    BEGIN 
     SET NOCOUNT ON; 

     IF (update(ref) 
      OR update(design) 
      OR update(u_update) 
      OR update(u_ativo) 
      OR update(stock) 
      OR update(epv1) 
      OR update(epv2) 
      OR update(epv3) 
      OR update(peso) 
      OR update(u_catnv1) 
      OR update(u_catnv2) 
      OR update(u_catnv3) 
      OR update(u_dpromoi) 
      OR update(u_dpromof) 
      OR update(u_destaque)) 
     BEGIN 
      IF (SELECT count(*) 
       FROM Inserted 
         INNER JOIN Deleted 
         ON Inserted.ststamp = Deleted.ststamp 
       WHERE inserted.u_ativo = 1 
         OR (Deleted.u_ativo = 1 
          AND Inserted.u_ativo = 0)) > 0 
       BEGIN 
        INSERT INTO RepData 
           (id, 
           REF, 
           familia, 
           stock, 
           epv1, 
           epv2, 
           epv3, 
           peso, 
           u_accao, 
           imagem, 
           process) 
        SELECT Inserted.ststamp AS id, 
         Inserted.REF  AS REF, 
         Inserted.familia AS familia, 
         Inserted.stock AS stock, 
         Inserted.epv1 AS epv1, 
         Inserted.epv2 AS epv2, 
         Inserted.epv3 AS epv3, 
         Inserted.peso AS peso, 
         CASE 
          WHEN Deleted.u_ativo = 1 
           AND Inserted.u_ativo = 0 THEN 'd' 
          ELSE 'u' 
         END    AS u_accao, 
         Inserted.imagem AS imagem, 
         0    AS process 
        FROM Inserted 
         INNER JOIN Deleted 
          ON Deleted.ststamp = Inserted.ststamp 
        WHERE inserted.u_ativo = 1 
          OR (Deleted.u_ativo = 1 
           AND Inserted.u_ativo = 0) 
       END 
     END 
    END 

Qualsiasi aiuto sarebbe apprezzato.

Aggiornamento: Database MSSQL 2008

+1

Puoi fornire il messaggio di errore ** esatto ** (o almeno il numero di errore se il messaggio non è in inglese). "Il documento è già aperto, incrementerò il suo valore" non sembra un messaggio di errore di SQL Server. –

+0

Non ottengo altro che quel messaggio, non è nemmeno mostrato come un errore ma un messaggio informativo.L'operazione è l'aggiornamento delle scorte del prodotto se pertinente. – Fabio

+1

se la sua produzione, controllare i registri delle app che deve scrivere da qualche parte, se non eseguire profiler sul db e vedere cosa sta succedendo – WKordos

risposta

0

Problema risolto.

Davvero non conosco la fonte del problema, anche se penso che si tratti di un problema relativo al blocco della tabella, in questo caso la tabella inserita.

Ho appena modificato l'istruzione di selezione interna in modo da prelevare i valori direttamente dalla tabella st anziché dall'inserto.

Grazie a tutti.

+1

Ah, OK. Ciò significa che l'altro trigger stava modificando le righe della tabella [st], che si rifletterebbero in [st] ma non in [inserito]. La mia ipotesi sarebbe che questo ha causato qualche violazione della chiave altrove (forse in [RepData]). – RBarryYoung

8

L'utilizzo di trigger per lo sviluppo e la personalizzazione in post-distribuzione post-implementazione è un'allettante, ma una cattiva idea, e senza dubbio continuerà a generare problemi come questo per voi.

Tuttavia, dato questo, quindi Primo: le tabelle possono avere più trigger,, non è questo il problema.

In secondo luogo, il messaggio di errore "documento è già aperto, io incrementare il suo valore" è o dalla vostra applicazione client o dall'altra (criptato) grilletto, non è un messaggio di errore di SQL Server. Detto questo, è possibile provare a impostare il trigger crittografato per eseguire prima, o impostare il trigger per eseguire l'ultimo. Questo probabilmente non risolverà il problema, ma è spostare l'errore dal trigger crittografato, nel trigger in cui si ha una migliore possibilità di segnalazione e/o indirizzamento in modo gestibile.

Sebbene sia estraneo, l'unico problema che può essere rilevato dal trigger è l'altro trigger che scrive anche sulla tabella RepData e la doppia scrittura causa violazioni delle chiavi duplicate.


ordine di innesco può essere controllato attraverso la procedura di sistema sp_settriggerorder, documentato here.

+0

Bella risposta, grazie! Quindi, come posso gestire l'ordine di esecuzione dei trigger? – Fabio

Problemi correlati