Colonna calcolata con date

martedì 30 dicembre 2008 - 21.09

alexmed Profilo | Guru

Ciao a tutti
Vorrei aggiungere tre colonne in una tabella

DATA datetime
DURATA int
SCADENZA

Impostata la data di partenza (31/12/2008) e la durata (3 anni) nella colonna scadenza deve venire fuori 31/12/2011
Quindi ho inserito come formula nella colonna scadenza (dateadd(year,[DURATA],[DATA]))

Vorrei però lasciare la possibilità di inserire la data di scadenza manualmente nel caso la "durata" non sia espressa in anni interi (es. 15 mesi)
Quindi stavo pensando ad una formula del tipo

(IF durata > 0 (dateadd(year,[DURATA],[DATA])))

Ma a quanto pare non funziona quindi dopo aver fatto un pò di prove vi chiedo lumi.

Grazie

Alessandro

lbenaglia Profilo | Guru

>Ma a quanto pare non funziona quindi dopo aver fatto un pò di
>prove vi chiedo lumi.

Ciao Alessandro,

Semplice, non puoi dato che una colonna calcolata puoi considerarla "virtuale" e quindi non "editabile".
Se ti serve quella flessibilità devi definire una normale colonna per la scadenza e scrivere un trigger di INSERT/UPDATE che inglobi la logica per valorizzarla.

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

alexmed Profilo | Guru

Ciao Lorenzo
grazie per la dritta, sarei andato avanti per dei giorni.
Essendo un autodidatta ed essendo più "afferrato" in ambiente VB credo che la procedura la svilupperò direttamente lì.
Per ora le mie conoscienze non mi consentono di sviluppare il trigger in questione ma prima o poi affronterò l'argomento.
Ciao e grazie
PS
Buono a sapersi che le colonne calcolate sono "virtuali"

lbenaglia Profilo | Guru

>Essendo un autodidatta ed essendo più "afferrato" in ambiente
>VB credo che la procedura la svilupperò direttamente lì.
>Per ora le mie conoscienze non mi consentono di sviluppare il
>trigger in questione ma prima o poi affronterò l'argomento.
Ma no dai, se mi dici come fai a discriminare se una durata è espressa in anni o mesi (per me ti manca una colonna che stabilisca la tipologia della durata), ti farò vedere come fare

>Buono a sapersi che le colonne calcolate sono "virtuali"
A partire con SQL Server 2005 è possibile rendere persistenti le colonne calcolate mediante la keyword PERSISTED, in questo modo il valore viene scritto nelle data pages della tabella come in una normalissima colonna evitando il calcolo in fase di SELECT, rimane però il fatto che siano in "sola lettura".

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

alexmed Profilo | Guru

>Ma no dai, se mi dici come fai a discriminare se una durata è espressa in anni o mesi
Ciao
Non intendevo questo nello sviluppo della procedura ma quella di calcolare la scadenza in base alla durata.
Tramite una TextBox (durata espressa in anni), quando perde il focus, se contiene un numero intero (valido) lo sommo alla data iniziale
Una cosa del tipo

Dim scadenza As Date = Me.DATADateTimePicker.Value.AddYears(CType(Me.TextBox1.Text, Integer))
Me.SCADENZADateTimePicker.Value = scadenza

e poi registro tutto su db (lasciando, a questo punto, la colonna DURATA facoltativa)

> ), ti farò vedere come fare
Questo sarebbe un buon punto di partenza per studiare i trigger!!!

Grazie ancora


lbenaglia Profilo | Guru

>Non intendevo questo nello sviluppo della procedura ma quella
>di calcolare la scadenza in base alla durata.
>Tramite una TextBox (durata espressa in anni), quando perde il
>focus, se contiene un numero intero (valido) lo sommo alla data
>iniziale

Si ma nel primo post dicevi: "Vorrei però lasciare la possibilità di inserire la data di scadenza manualmente nel caso la "durata" non sia espressa in anni interi (es. 15 mesi)"
Anni interi? 15 mesi? Cosa intendi?

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

alexmed Profilo | Guru

Nel senso che se la durata è espessa in anni inserisci il dato nella TextBox e ti calcolo la data di scadenza se invece non è un anno intero la data di scadenza se la calcola l'utente e tanti saluti!!

Perchè stavo pensando di inserire tre RadioButton che mi stabiliscono se la durata è espressa in anni, mesi o giorni, ma se avessi una durata di 3 anni 4 mesi e 3 giorni? Che dato chiedo di inserire? giorni?
Ed allora volevo limitare il calcolo solo agli anni (anche se è un calcolo abbastanza semplice).

Inoltre in alcuni casi** non ho una durata ma una data certa di scadenza, ed è per quello che lascierei la data di scadenza "libera"

**Si tratta di Autorizzazioni Comunali che variano da Comune a Comune (ad esempio in alcuni Comuni la validità è di 3 anni "fine anno" e ciò vuol dire che se la data di rilascio è il 15/07/08 la data di scadenza è 31/12/11.

Ciao

lbenaglia Profilo | Guru

>Nel senso che se la durata è espessa in anni inserisci il dato
>nella TextBox e ti calcolo la data di scadenza se invece non
>è un anno intero la data di scadenza se la calcola l'utente e
>tanti saluti!!
Quindi mi stai dicendo che la colonna durata rappresenta SEMPRE un numero espresso in anni?
OK, basta capirsi

>**Si tratta di Autorizzazioni Comunali che variano da Comune
>a Comune (ad esempio in alcuni Comuni la validità è di 3 anni
>"fine anno" e ciò vuol dire che se la data di rilascio è il 15/07/08
>la data di scadenza è 31/12/11.
Mmmm... ad ogni post le regole cambiano.
Teniamo buone queste, OK?

USE tempdb; CREATE TABLE dbo.Tempistiche( TempisticaID int NOT NULL IDENTITY PRIMARY KEY, Data datetime NOT NULL, Durata int NOT NULL DEFAULT 0, Scadenza datetime NULL, CONSTRAINT CHK_Durata CHECK(Durata >= 0) ); GO CREATE FUNCTION dbo.ufn_GetLastYearDay( @Today datetime ) RETURNS datetime BEGIN RETURN DATEADD(year, DATEDIFF(year, 0, @Today) + 1, -1); END GO CREATE TRIGGER dbo.trIU_Tempistiche ON dbo.Tempistiche AFTER INSERT, UPDATE AS IF UPDATE(Data) OR UPDATE(Durata) BEGIN UPDATE T SET Scadenza = DATEADD(year, I.Durata, dbo.ufn_GetLastYearDay(I.Data)) FROM dbo.Tempistiche AS T JOIN INSERTED AS I ON T.TempisticaID = I.TempisticaID WHERE I.Durata > 0; END GO INSERT dbo.Tempistiche(Data, Durata) VALUES('20080101', 3); INSERT dbo.Tempistiche(Data, Durata) VALUES('20080715', 3); INSERT dbo.Tempistiche(Data, Durata) VALUES('20081231', 3); INSERT dbo.Tempistiche(Data, Durata) VALUES ('20070101', 5) , ('20070715', 5) , ('20071231', 5); INSERT dbo.Tempistiche (Data, Scadenza) VALUES('20060101', '20101231'); SELECT * FROM dbo.Tempistiche; /* Output: TempisticaID Data Durata Scadenza ------------ ----------------------- ----------- ----------------------- 1 2008-01-01 00:00:00.000 3 2011-12-31 00:00:00.000 2 2008-07-15 00:00:00.000 3 2011-12-31 00:00:00.000 3 2008-12-31 00:00:00.000 3 2011-12-31 00:00:00.000 4 2007-01-01 00:00:00.000 5 2012-12-31 00:00:00.000 5 2007-07-15 00:00:00.000 5 2012-12-31 00:00:00.000 6 2007-12-31 00:00:00.000 5 2012-12-31 00:00:00.000 7 2006-01-01 00:00:00.000 0 2010-12-31 00:00:00.000 (7 row(s) affected) */ UPDATE dbo.Tempistiche SET Durata = 6 WHERE Data BETWEEN '20080101' AND '20081231'; SELECT * FROM dbo.Tempistiche; /* Output: TempisticaID Data Durata Scadenza ------------ ----------------------- ----------- ----------------------- 1 2008-01-01 00:00:00.000 6 2014-12-31 00:00:00.000 2 2008-07-15 00:00:00.000 6 2014-12-31 00:00:00.000 3 2008-12-31 00:00:00.000 6 2014-12-31 00:00:00.000 4 2007-01-01 00:00:00.000 5 2012-12-31 00:00:00.000 5 2007-07-15 00:00:00.000 5 2012-12-31 00:00:00.000 6 2007-12-31 00:00:00.000 5 2012-12-31 00:00:00.000 7 2006-01-01 00:00:00.000 0 2010-12-31 00:00:00.000 (7 row(s) affected) */ DROP FUNCTION dbo.ufn_GetLastYearDay; DROP TABLE dbo.Tempistiche;

La funzione scalare ufn_GetLastYearDay si preoccupa di calcolare l'ultimo giorno dell'anno della data passata come argomento, mentre il trigger trIU_Tempistiche aggiornerà la colonna Scadenza in fase di inserimento oppure di aggiornamento delle colonne Data o Durata.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

alexmed Profilo | Guru


Ok funziona
Adesso me la studio un pò.
Grazie mille e buon anno nuovo
Alessandro
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-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5