none
Trigger ricorsivi RRS feed

  • Domanda

  • Salve a tutti, ho un problema con i Trigger Ricorsivi. Premetto che è la prima volta che ho la necessità di abilitarli. Utilizzo SQL Server 2012.

    Dopo averli abilitati con il comando:

    ALTER DATABASE dbTest SET RECURSIVE_TRIGGERS ON

    ho fatto un po' di prove con il tirgger per il quale ero interessato alla ricorsione, tutto ok, strumento veramente potente.

    Proseguendo con lo sviluppo però mi si è presentato un problema: ho la necessità di aggiornare un campo idPriorita sulle righe di una tabella tbCommessaRig in base alla quantità di tempo che la riga non viene modificata (per questo utilizzo un campo LastRipStateChange). Non potendo utilizzare i JOBS (o PROCESSI) ho deciso di creare un trigger:

    ALTER TRIGGER [dbo].[tr_upd_IncrementaPriorita]
       ON  [dbo].[tbCommessaRig]
       AFTER UPDATE
    AS 
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
    
    	IF (UPDATE(idPriorita))
    	BEGIN
    		SELECT 1 //DO NOTHING
    	END
    	ELSE
    	BEGIN
    		DECLARE @Timeout int = 365
    		SELECT @Timeout = CAST(value AS int) FROM tbConfig WHERE id = 'PRIORITY_INC_TIMEOUT'
    		IF @Timeout IS NULL
    			SET @Timeout = 365
    
    		DECLARE @Count int = 0
    		SELECT	@Count = COUNT(*)
    		FROM	tbCommessaRig
    		WHERE	idPriorita < (SELECT MAX(id) FROM tbPriorita) AND --Priorità non massima
    				((idStatoRip >= 2 AND idStatoRip <= 8) OR (idStatoRip = 13)) AND isStorico = 0 AND --Non terminato
    				DATEADD(d, @Timeout, LastRipStateChange) < GETDATE() /*Timeout scaduto*/
    
    		IF (@Count > 0)
    		BEGIN
    			UPDATE	tbCommessaRig SET idPriorita += 1, LastRipStateChange = GETDATE()
    			WHERE	idPriorita < (SELECT MAX(id) FROM tbPriorita) AND --Priorità non massima
    					((idStatoRip >= 2 AND idStatoRip <= 8) OR (idStatoRip = 13)) AND isStorico = 0 AND --Non terminato
    					DATEADD(d, @Timeout, LastRipStateChange) < GETDATE() /*Timeout scaduto*/
    		END
    	END
    END

    Lasciando perdere le ottimizzazioni (molte modifiche sono state fatte per cercare una soluzione al problema), quello che si verifica è che il trigger viene eseguito ricorsivamente fino a raggiungere il numero masso di ricorsioni possibili (di default 32).

    Mi sapreste spiegare perché? Sapete darmi una soluzione?

    Quello che faccio (che vorrei fare in realtà :) ) è aggiornare questo campo priorità solo sotto determinate condizioni (se la priorità non è già massima, se "idStatoRip" ha determinati valori, se isStorico = 0 e se la data di ultima modifica è minore della data corrente..

    Grazie a tutti per le risposte!


    Andrea

    Ovviamente quando chiedo "di spiegarmi il perché" intendo dire che, visti i controlli che faccio, non dovrebbe andare a modificare ogni volta la tabella (con la conseguente riesecuzione del trigger in questione)

    martedì 1 ottobre 2013 18:08

Risposte

  • Chiedo scusa, mi rispondo da solo: il trigger che creava problemi era un altro, che richiamava ricorsivamente quello sopra riportato.

    Non cancello il post perché magari altri possono avere uno spunto da quanto ho scritto.

    Grazie a tutti


    Andrea

    martedì 1 ottobre 2013 20:34