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)