Impedire Update record

lunedì 23 aprile 2012 - 11.38
Tag Elenco Tags  SQL Server 2008 R2

mmjc23 Profilo | Newbie

Buongiorno a tutti

Un'altra delle..."mie domande"...

Allora ho tre tabelle:

TA_APPARATO (tolgo alcune colonne che non servono):
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

TIPO_APPARATO:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

APPARATO_APPARATO_ASSOCIATO:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Quello che vorrei fare, è l'impossibilità di modificare il TIPO_APPARATO di un determinato ID_APPARATO della TA_APPARATO SE l'ID_APPARATO, è presente nella "APPARATO_APPARATO_ASSOCIATO".

Con la prima Foreign Key della TA_APPARATO (FK_TA_APPARATO_APPARATO_ASSOCIATO), sono riuscito ad impedire che il record della TA_APPARATO, possa essere eliminato se presente nella "APPARATO_APPARATO_ASSOCIATO"; ma, come impedirne l'UPDATE? (del campo TIPO_APPARATO (che non è chiave), ma va benissimo anche dell'intero record)

Se, per fare quello che voglio fare, dovessi aver bisogno di un Trigger (su Update del record), come faccio, all'interno del Trigger, ad annullare l'UPDATE?

Grazie

alx_81 Profilo | Guru

>Buongiorno a tutti
Ciao

>Se, per fare quello che voglio fare, dovessi aver bisogno di
>un Trigger (su Update del record), come faccio, all'interno del
>Trigger, ad annullare l'UPDATE?
Si credo tu necessiti di un trigger. Se al posto dell'update vuoi tornare un errore direi di fare un TRIGGER INSTEAD OF UPDATE
http://msdn.microsoft.com/it-it/library/ms189799(v=sql.100).aspx
e
http://msdn.microsoft.com/it-it/library/ms188601(v=sql.105).aspx

se vuoi tornare l'errore puoi usare una RAISERROR
http://msdn.microsoft.com/it-it/library/ms177497(v=sql.105).aspx

>Grazie
di nulla!
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

mmjc23 Profilo | Newbie

Ciao Alex e grazie della risposta...

Devo ammettere che non c'ho capito molto.

-Quando si definisce un trigger, questo scatta per ogni record oppure scatta sull'intera tabella. Mi spiego meglio...se io ho un datatable VB.NET, MODIFICO le varie righe (quindi UPDATE) e alla fine eseguo un "Aggiorna", cosa succede? Mi scatta un trigger UPDATE per ogni Riga (e quindi nelle tabelle INSERTED e DELETED mi trovo solo la riga modificata) oppure mi scatta sull'intera tabella (e quindi le due tabelle contengono tutte le righe modificate per quella tabella)? Scusami per l'esempio Vb.NET...credo che valga la stessa cosa se scrivo N istruzioni UPDATE e chiamo un unico GO alla fine giusto?

-Siccome ho già un trigger UPDATE per quella tabella, non posso modificare il trigger in modo che esegua un rollback qualora le mie condizioni non siano soddisfatte?

-Se invece voglio implementare un trigger "INSTEAD TRIGGER" e le mie condizioni sono soddisfatte, come faccio a "mandare avanti normalmente" l'UPDATE?

Grazie ancora
Ciao

mmjc23 Profilo | Newbie

Allora...ho fatto un po' di prove, ed ho modificato con l'obiettivo di modificare il meno possibile la parte già esistente e consolidata. Valuto comunque consigli se come ho fatto non è corretto.

Ho modificato quindi il mio trigger di update in modo che:
-verifichi se ci sono dei record aggiornati (tabella INSERTED), che hanno ID_APPARATO presenti anche nella tabella "APPARATO_APPARATO_ASSOCIATO"
-se ci sono, per quei record, confronta il valore "ID_TIPO_APPARATO" dei record nella tabella INSERTED con quelli nella tabella DELETED
-se i valori sono diversi, alzo un RAISERROR e faccio il Rollback (quindi annulla le modifiche fatte dall'utente), altrimenti, continua con quanto eseguito normalmente dal trigger.
Ecco il codice:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

GRAZIE

alx_81 Profilo | Guru

>-Quando si definisce un trigger, questo scatta per ogni record
>oppure scatta sull'intera tabella. Mi spiego meglio...se io ho
>un datatable VB.NET, MODIFICO le varie righe (quindi UPDATE)
>e alla fine eseguo un "Aggiorna", cosa succede? Mi scatta un
>trigger UPDATE per ogni Riga (e quindi nelle tabelle INSERTED
>e DELETED mi trovo solo la riga modificata) oppure mi scatta
>sull'intera tabella (e quindi le due tabelle contengono tutte
>le righe modificate per quella tabella)?
Dipende da quante righe vai a coinvolgere nell'operazione di update. Se cambi ad esempio 4 righe, la inserted avrà 4 righe e la deleted pure.
Non coinvolge l'intera tabella.

>Scusami per l'esempio Vb.NET...credo che valga la stessa cosa se scrivo N istruzioni
>UPDATE e chiamo un unico GO alla fine giusto?
Il GO è tutta un'altra cosa. E' la fine di un batch che non ha nulla a che vedere con i trigger di una tabella per un determinato evento.

>-Siccome ho già un trigger UPDATE per quella tabella, non posso
>modificare il trigger in modo che esegua un rollback qualora
>le mie condizioni non siano soddisfatte?
Hai letto i link che ti ho passato? Nella fattispecie: http://msdn.microsoft.com/it-it/library/ms189799
c'è proprio l'esempio con la ROLLBACK se ti serve quello.

>-Se invece voglio implementare un trigger "INSTEAD TRIGGER" e
>le mie condizioni sono soddisfatte, come faccio a "mandare avanti
>normalmente" l'UPDATE?
devi completare tu l'operazione, ma se vuoi fare l'operazione e in caso di errore fare ROLLBACK,
allora puoi usare un TRIGGER FOR UPDATE e fare rollback solo in caso di errore.
Leggiti bene il link che ti ho postato prima, contiene la spiegazione dei trigger FOR/AFTER e INSTEAD OF

>Ho modificato quindi il mio trigger di update in modo che:
>-verifichi se ci sono dei record aggiornati (tabella INSERTED),
>che hanno ID_APPARATO presenti anche nella tabella "APPARATO_APPARATO_ASSOCIATO"
>-se ci sono, per quei record, confronta il valore "ID_TIPO_APPARATO"
>dei record nella tabella INSERTED con quelli nella tabella DELETED
>-se i valori sono diversi, alzo un RAISERROR e faccio il Rollback
>(quindi annulla le modifiche fatte dall'utente), altrimenti,
>continua con quanto eseguito normalmente dal trigger.
>GRAZIE
di nulla, hai fatto alla fine il trigger di AFTER con la gestione dell'errore. Sembra corretto, ma conosco troppo poco il tuo caso reale. A occhio sembra ok.
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

mmjc23 Profilo | Newbie

Che dire...grazie infinite per il tempo dedicatomi e per le info fornitemi...davvero gentilissimo

Lo tengo testato, ma sembra funzionare.
Ciao
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5