vorrei eseguire la seguente operazione su una tabella chiamata TGA che
contiene, tra gli altri, i seguenti campi:
- TAttrezzaggioStimato FLOAT
- T1PzStimato FLOAT
- quantita FLOAT
- TTotale FLOAT
TTotale = TAttrezzaggioStimato + (quantita * T1PzStimato)
Quando eseguo le istruzioni INSERT e UPDATE su questa tabella, vorrei che
venisse aggiornato il valore del campo TTotale. Da quello che ho capito si
può fare con un trigger, ma dal momento che non ne ho mai scritto nemmeno
uno, chiedo il vostro aiuto.
Un grazie anticipato a chi può aiutarmi, ciao!
Marsilio
Si può fare con un trigger ma si può fare ancora meglio senza un trigger.
In SQL Server puoi definire un campo calcolato nella tabella nel momento in
cui definisci la tabella stessa (oppure con un comando ALTER TABLE se la
tabella esiste già).
Un campo calcolato è un campo che non viene materializzato a livello fisico
(ovvero non occupa spazio) ma che eseguendo una query lo vedi insieme alle
altre colonne. Puoi definire un campo calcolato in maniera simile a
CREATE TABLE dbo.MyTable
(
ID smallint not null,
c1 smallint not null,
c2 smallint not null,
c3 AS c1 + c2
)
Puoi anche decidere di materializzare il campo con la clausola PERSISTED.
Sia in un caso che nell'altro (persisted o non persisted) ti scordi
qualunque gestione...
Fai anche attenzione ai datatype FLOAT. Si tratta di datatype APPROSSIMATI e
questo già dovrebbe farti riflettere sul fatto che con tutta probabilità non
sono adatti ad un campo "quantità" e/o "importo".
> Un grazie anticipato a chi può aiutarmi, ciao!
>
> Marsilio
Bye
--
Luca Bianchi
Microsoft MVP - SQL Server
http://community.ugiss.org/blogs/lbianchi
Grazie mille, per la risposta e per la velocità!
Sto lavorando con un file ADP di Access collegato a una istanza di MSDE2000,
quindi non so come fare per aggiungere un campo simile, dal momento che non
ho lo script di creazione della tabella.
C'è un modo per aggiungere il campo calcolato?
Grazie anche per il consiglio riguardo il tipo di dati FLOAT, di cui terrò
conto; in alternativa a FLOAT, posso usare DECIMAL?
Infine, se per te non è una perdita di tempo troppo grande, potresti per
cortesia insegnarmi come si farebbe il trigger per risolvere il problema qui
sopra? Sarebbe per me una buona occasione per imparare qualcosa di
sicuramente utile (magari in altri casi).
Ciao!
Marsilio
Marsilio
Tutto quello che c'č da sapere sui trigger lo trovi sul Book On Line (BOL),
ovvero la documentazione ufficiale di SQL Server che puoi scaricare, nella
versione piů aggiornata, da questo link
In particolare le info necessarie per sapere come si crea un trigger sono
sotto la voce "CREATE TRIGGER" in questa pagina
http://msdn.microsoft.com/en-us/library/ms189799.aspx
> Ciao!
Ciao,
Marsilio
"Luca Bianchi" <rightjoinR...@hotmail.com> ha scritto nel messaggio
news:3777A2D6-F431-4229...@microsoft.com...
Marsilio
ALTER TRIGGER TGA_AnticipoRitardo
ON dbo.TGA
FOR INSERT, UPDATE
AS
DECLARE @dataconseg DATETIME,
@DataFineProgrammata DATETIME,
@Lotto NVARCHAR(9),
@Fase SMALLINT
SELECT @dataconseg = dataconseg FROM inserted
SELECT @DataFineProgrammata = DataFineProgrammata FROM inserted
SELECT @Lotto = Lotto FROM inserted
SELECT @Fase = Fase FROM inserted
IF @dataconseg > @DataFineProgrammata
UPDATE dbo.TGA SET AnticipoRitardo = N'A' WHERE Lotto = @Lotto AND Fase
= @Fase
ELSE
UPDATE dbo.TGA SET AnticipoRitardo = N'R' WHERE Lotto = @Lotto AND Fase
= @Fase
ALTER TRIGGER TGA_AnticipoRitardo
ON dbo.TGA
FOR INSERT, UPDATE
AS
DECLARE @dataconseg DATETIME,
@DataFineProgrammata DATETIME,
@Lotto NVARCHAR(9),
@Fase SMALLINT
SELECT @dataconseg = dataconseg,
@DataFineProgrammata = DataFineProgrammata,
@Lotto = Lotto,
Va sicuramente bene se viene inserita o aggiornata una sola riga. Ma se
vengono aggiunti o modificati 2 o più record le variabili conterranno i
valori dell'ultimo record e ti perderai tutto quelli precedenti. Un trigger
viene scatenato una sola volta per ciascuna istruzione per cui è definito,
quindi un inserimento/aggiornamento/cancellazione multiplo farà comunque
scattare un solo trigger...
Capisco, ma in questo caso cosa posso fare? E' meglio fare eseguire al
trigger una SP che aggiorni il campo AnticipoRitardo? Come si fa a
richiamare la SP, con EXEC ........... ?
Grazie
Marsilio
Mi è venuto in mente anche quanto segue:
ALTER TRIGGER TGA_AnticipoRitardo
ON dbo.TGA
FOR INSERT, UPDATE
AS
UPDATE dbo.TGA SET AnticipoRitardo = N'A' WHERE dataconseg >
DataFineProgrammata
UPDATE dbo.TGA SET AnticipoRitardo = N'R' WHERE DataFineProgrammata >
dataconseg
Può funzionare? C'è un modo perchè il trigger venga eseguito solo quando
vengono modificati/inseriti alcuni specifici campi?
Grazie
Marsilio
In questo modo vengono aggiornati indiscriminatamente TUTTI i record della
tabella. Immagino che il tuo obiettivo sia quello di far si che vengano
aggiornati SOLO quelli che sono stati toccati da una modifica ai dati.
Allora non ti resta che aggiungere all'istruzione UPDATE un join con la
tabella INSERTED e modificherai solo quelli coinvolti dall'INSERT/UPDATE...
> Grazie
>
> Marsilio
Ho capito, proverò a fare così. Ti ringrazio molto per l'aiuto, sto muovendo
i primi passi in questo affascinante mondo dei database per necessità, oltre
che per passione, ma senza qualche consiglio da chi ha già esperienza
sarebbe davvero dura!
Ciao,
Marsilio