TRIGGER per compilazione varie colonne con WHEN

di il
3 risposte

TRIGGER per compilazione varie colonne con WHEN

Buongiorno,
ho un database MsSQL che tramite un programma esterno viene compilata ed aggiornata una tabella del DB denominata "MRC_STATI".
Quando cambia qualcosa in MRC_STATI, un TRIGGER mi esamina alcune colonne e mi aggiorna le cononne QUADRO_ON e QUADRO_OFF della tabella "T_STATOINGRESSI" con questo codice:
USE [Stati]
GO
/****** Object:  Trigger [dbo].[trigger_SensorTEST]    Script Date: 15/01/2021 16:24:26 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO

ALTER TRIGGER [dbo].[trigger_SensorTEST]
ON [dbo].[mrc_stati]
AFTER  INSERT,UPDATE
AS BEGIN
SET NOCOUNT ON;

/*MERGE t_StatoIngressi AS target /*CICLO CHIAVE QUADRO ON*/
USING INSERTED AS source
ON target.SERIALE = source.f1
WHEN MATCHED AND ((source.f19 LIKE '%Quadro = ON%') OR (source.f19 LIKE '%Chiave = ON%')) THEN
UPDATE SET Quadro_ON = RIGHT(source.f6,11) +''+ LEFT(RIGHT(source.f6,24),8)
WHEN NOT MATCHED AND ((source.f19 LIKE '%Quadro = ON%') OR (source.f19 LIKE '%Chiave = ON%')) THEN
INSERT (SERIALE, Quadro_ON) VALUES (source.f1, RIGHT(source.f6,11) +''+ LEFT(RIGHT(source.f6,24),8));

MERGE t_StatoIngressi AS target /*CICLO CHIAVE QUADRO OFF*/
USING INSERTED AS source
ON target.SERIALE = source.f1
WHEN MATCHED AND (((source.f19 LIKE '%Quadro = OFF%') AND (source.f19 NOT LIKE '%Quadro = OFF (%')) OR ((source.f19 LIKE '%Chiave = OFF%') AND (source.f19 NOT LIKE '%Chiave = OFF (%'))) THEN
UPDATE SET Quadro_OFF = RIGHT(source.f6,11) +''+ LEFT(RIGHT(source.f6,24),8)
WHEN NOT MATCHED AND (((source.f19 LIKE '%Quadro = OFF%') AND (source.f19 NOT LIKE '%Quadro = OFF (%')) OR ((source.f19 LIKE '%Chiave = OFF%') AND (source.f19 NOT LIKE '%Chiave = OFF (%'))) THEN
INSERT (SERIALE, Quadro_OFF) VALUES (source.f1, RIGHT(source.f6,11) +''+ LEFT(RIGHT(source.f6,24),8));
END
fino qui tutto ok, ora sto cercando di aggiungere oltre a questi valori di data e ora, anche una colonna "QUADRO_VAR" con delle variabili in base alla differenza di orario ma non riesco a capire come fare, non capisco se metterlo in fondo alla procedura di trigger o dove.
Posto il codice che pensavo di usare infondo al trigger precedente:
MERGE t_StatoIngressi AS target
USING INSERTED AS source
ON target.SERIALE = source.f1
	WHEN MATCHED AND DATEDIFF(mi, QUADRO_OFF, QUADRO_ON) >= 7200 THEN 
	UPDATE SET QUADRO_VAR = 6;
	WHEN MATCHED AND DATEDIFF(ss, QUADRO_OFF, QUADRO_ON) >= 600 AND DATEDIFF(mi, QUADRO_OFF, QUADRO_ON) < 7200 THEN 
	UPDATE SET QUADRO_VAR = '1' 
il QUADRO_ON e QUADRO_OFF sono dati che compilo con il trigger sopra prima, ma non riesco a far reagire questa seconda parte.

3 Risposte

  • Re: TRIGGER per compilazione varie colonne con WHEN

    Salve,
    che tipo di dato e' mrc_stati.f6, e cosa c'e' dentro?
    salutoni romagnoli
    --
    Andrea
  • Re: TRIGGER per compilazione varie colonne con WHEN

    Il dato di f6 è una data e ora lo salvo per sapere l ultimo aggiornamento effettivo
  • Re: TRIGGER per compilazione varie colonne con WHEN

    Salve ZMax,

    sinceramente [f6] a me non sembra un attibuto di tipo datetime, e il contenuto mi resta abbastanza dubbio, tanto piu' visto le estrazioni LEFT/RIGHT con le quali ci operi sopra...
    io ho utilizzato direttamente un tipo di dato datetime per la mia semplicita' di riproduzione...

    di base, puoi arricchire il comando di UPDATE (parte del MERGE) come di consuetudine con confronti basati sulla clausola CASE, e qui puoi aggiungere le verifiche a te interessanti...

    nell'esempio seguente, non ho messo il comando di creazione in quanto le regole di validazione del forum fanno si che i post che le contengono vengano spesso rifiutati, quindi considera 2 tabelle:
    (leggi la sintassi in maniera "fantasiosa" )
    
    mrc_stati 
    	f1 int,
    	f6 datetime,           -- io uso datetime per MIA semplicita', ma direi anche per correttezza se il dato e' un dato temporale
    	f19 varchar(20)
    
    e
    t_StatoIngressi
    	SERIALE int,
    	Quadro_ON datetime,    -- io uso datetime per MIA semplicita'
    	Quadro_OFF datetime,   -- io uso datetime per MIA semplicita'
    	Quadro_VAR int NULL
    GO
    
    { genera  o modifica } TRIGGER [dbo].[trigger_SensorTEST] ON [dbo].[mrc_stati]
    	AFTER  INSERT,UPDATE
    AS BEGIN
    
    	IF (SELECT COUNT(*) FROM INSERTED) = 0
    		RETURN;
    
    	SET NOCOUNT ON;
    
        -- la sintassi seguente USA il confronto diretto tra datetime e non i cast + left/right di selezione che tu hai usato,
        -- ma se proprio devi, puoi continuare di conseguenza
    	MERGE t_StatoIngressi AS target /*CICLO CHIAVE QUADRO ON */
    		USING INSERTED AS source
    		ON target.SERIALE = source.f1
    	WHEN MATCHED AND ((source.f19 LIKE '%Quadro = ON%') OR (source.f19 LIKE '%Chiave = ON%')) THEN
    		UPDATE SET Quadro_ON = source.f6 --RIGHT(source.f6,11) +''+ LEFT(RIGHT(source.f6,24),8)
    	WHEN NOT MATCHED AND ((source.f19 LIKE '%Quadro = ON%') OR (source.f19 LIKE '%Chiave = ON%')) THEN
    		INSERT (SERIALE, Quadro_ON) VALUES (source.f1, source.f6);
    
        -- la sintassi seguente USA il confronto diretto tra datetime e non i cast + left/right di selezione che tu hai usato,
        -- ma se proprio devi, puoi continuare di conseguenza
    	MERGE t_StatoIngressi AS target /*CICLO CHIAVE QUADRO OFF*/
    		USING INSERTED AS source
    		ON target.SERIALE = source.f1
    	WHEN MATCHED AND (((source.f19 LIKE '%Quadro = OFF%') AND (source.f19 NOT LIKE '%Quadro = OFF (%')) OR ((source.f19 LIKE '%Chiave = OFF%') AND (source.f19 NOT LIKE '%Chiave = OFF (%'))) THEN		
    		UPDATE SET Quadro_OFF = source.f6,
    			Quadro_VAR =
                    -- questo e' quello che dovresti fare tu
    				--CASE WHEN DATEDIFF(mi, QUADRO_ON, source.f6) >= 7200 THEN 6
    				--	WHEN DATEDIFF(ss, QUADRO_ON, source.f6) >= 600 AND DATEDIFF(mi, QUADRO_ON, source.f6) < 7200 THEN 1
    				--	ELSE Quadro_VAR 
    				
                    -- io ho usato un confronto piu' breve per fare validazioni piu' veloci
    				CASE WHEN DATEDIFF(ms, QUADRO_ON, source.f6) >= 2000 THEN 6
    					WHEN DATEDIFF(ms, QUADRO_ON, source.f6) >= 100  AND DATEDIFF(ms, source.f6, QUADRO_ON) < 2000 THEN 1
    					ELSE Quadro_VAR 
    
    				END
    	WHEN NOT MATCHED AND (((source.f19 LIKE '%Quadro = OFF%') AND (source.f19 NOT LIKE '%Quadro = OFF (%')) OR ((source.f19 LIKE '%Chiave = OFF%') AND (source.f19 NOT LIKE '%Chiave = OFF (%'))) THEN
    		INSERT (SERIALE, Quadro_OFF) VALUES (source.f1, source.f6);
    END;
    GO
    
    
    salutoni romagnoli e buona domenica
    --
    Andrea
Devi accedere o registrarti per scrivere nel forum
3 risposte