Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

date in sqlServer

139 views
Skip to first unread message

rocco pasca

unread,
Nov 25, 2002, 10:28:02 AM11/25/02
to
ciao a tutti.
qualcuno di voi sa come fare per inserire in un campo datetime di sqlServer
una data molto molto vecchia?
mi sembra che per default il minimo valore sia 1700 e qualcosa.
Grazie.
Rocco


Lorenzo Benaglia

unread,
Nov 25, 2002, 10:44:15 AM11/25/02
to
"rocco pasca" <rocco...@hotmail.com> wrote in message
news:ORwqSdJlCHA.1364@tkmsftngp09...

Ciao Rocco,

> qualcuno di voi sa come fare per inserire in un campo datetime di
sqlServer
> una data molto molto vecchia?
> mi sembra che per default il minimo valore sia 1700 e qualcosa.

SQL Server offre 2 datatypes per la memorizzazione di date e ore: datetime e
smalldatetime.

datetime
permette di gestire data e ora dal 1 gennaio 1753 al 31 dicembre 9999 con
un'accuratezza di 1/333 di secondo.

smalldatetime
permette di gestire data e ora dal 1 gennaio 1900 al 6 giugno 2079 con
un'accuratezza al minuto.

Se le date che vuoi memorizzare sono al di fuori di questi ranges, devi
ricorrere a datatypes alternativi, come char o varchar.

Ciao!

--
Lorenzo Benaglia
UGIdotNET - http://www.ugidotnet.org
UGISS - http://www.ugiss.org

Luca Bianchi

unread,
Nov 25, 2002, 10:49:38 AM11/25/02
to
A seconda dello scopo puoi inserire una stringa di caratteri oppure,
copiando il metodo utilizzato da SQL Server, implementare un tuo
contatore... Supponi di porre ad esempio la data di partenza come quella del
1/1/1900 il valore (che sarà uguale a 0) il valore -1 indicherà il
31/12/1899 e il valore +1 il 2/1/1900. La difficoltà sta nel calcolare le
date ma se il linguaggio con cui scrivi l'applicazione client te lo consente
questo non rappresenta un problema. Oppure ancora dividi il campo in 3 parti
rispettivamente giorno, mese ed anno... Il primo metodo è utile se hai solo
la necessità di memorizzare una data ma non intendi effettuarci dei calcoli
sopra; il contatore puoi utilizzarlo agevolmente se devi calcolare il tempo
trascorso tra 2 date storiche mentre la terza è un compromesso che ti
consente l'una e l'altra possibilità. Dipende dalla necessità che hai.
Perchè devi memorizzare date così vecchie?

Ciao...


Luca Bianchi

"rocco pasca" <rocco...@hotmail.com> wrote in message
news:ORwqSdJlCHA.1364@tkmsftngp09...

rocco pasca

unread,
Nov 25, 2002, 10:56:54 AM11/25/02
to
il mio problema è che leggo tramite sqlServer su altri db remoti, in
particolare db2.
lui riconosce che il campo di partenza è di tipo date e lo mappa bene, ma se
in partenza mi trovo una data molto vecchia (una inizializzazione fatta ad
esempio all'1/1/1) non posso leggere il record (perchè non posso fare
nemmeno un cast).
Suggerimenti?


"Luca Bianchi" <rightjoinR...@hotmail.com> wrote in message
news:eEeUVoJlCHA.2140@tkmsftngp12...

Luca Bianchi

unread,
Nov 25, 2002, 11:09:23 AM11/25/02
to
Si tratta di un linked server? Oppure dei dati che vengono importati con
DTS, bcp, ecc?


LB

"rocco pasca" <rocco...@hotmail.com> wrote in message

news:#Bm$atJlCHA.2412@tkmsftngp12...

rocco pasca

unread,
Nov 25, 2002, 11:22:26 AM11/25/02
to
una specie di linket server.
tutte le query vengono fatte on-line.
nel DTS è stato facile, ho utilizzato vbScript.

"Luca Bianchi" <rightjoinR...@hotmail.com> wrote in message

news:O$sSeyJlCHA.1364@tkmsftngp09...

Luca Bianchi

unread,
Nov 25, 2002, 11:35:31 AM11/25/02
to
...speravo si trattasse di un DTS...
Hai provato sul server di origine a creare una vista in cui cambi il tipo
dato? Insomma, l'equivalente del CAST/CONVERT per DB2 per poi leggere questa
vista anzichè la tabella sottostante...

LB


"rocco pasca" <rocco...@hotmail.com> wrote in message

news:eXzVs7JlCHA.2800@tkmsftngp09...

rocco pasca

unread,
Nov 25, 2002, 11:48:43 AM11/25/02
to
si, è una buona soluzione, ma richiede troppi interventi (anche di gestione)
sull'origine.


"Luca Bianchi" <rightjoinR...@hotmail.com> wrote in message

news:O3iYIBKlCHA.2108@tkmsftngp10...

Lorenzo Benaglia

unread,
Nov 25, 2002, 12:06:30 PM11/25/02
to
 
Ciao Luca & Rocco,
 
> Hai provato sul server di origine a creare una vista in cui cambi il tipo
> dato? Insomma, l'equivalente del CAST/CONVERT per DB2 per poi leggere questa
> vista anzichè la tabella sottostante...
Ho trovato Online la guida "IBM® DB2 Universal Database™ SQL Reference for Cross-Platform Development" e mi sto facendo una cultura anche su questo RDBMS ;-))
In DB2 il datatype DATE occupa ben 10 byte (contro gli 8 del DATETIME ed i 4 del SMALLDATETIME di SQL Server) ed è in grado di memorizzare un range che va dal 1 gennaio 0001 al 31 dicembre 9999.
 
Inoltre esiste una comoda funzione di conversione da Datetime a Character:
la funzione CHAR che accetta come parametro di input il formato di conversione in base alla seguente tabella:
 
Format Name                                Abbreviation Date Format Example
International Standards Organization       ISO          yyyy-mm-dd  1987-10-12
IBM USA standard                           USA          mm/dd/yyyy  10/12/1987
IBM European standard                      EUR          dd.mm.yyyy  12.10.1987
Japanese industrial standard Christian era JIS          yyyy-mm-dd  1987-10-12
 
La sintassi è:
 
CHAR (datetime-expression, ISO|USA|EUR|JIS)
 
Io definirei in SQL Server un campo CHAR(10) e memorizzerei le date in formato ISO (yyyy-mm-dd).
Il documento in formato PDF è disponibile al seguente link http://www-3.ibm.com/software/data/db2/

Luca Bianchi

unread,
Nov 25, 2002, 12:08:55 PM11/25/02
to
Se i campi "sporchi" sono molti, si... Non è di facile soluzione.
Hai provato con una query pass-through nel formato

SELECT *
FROM OPENQUERY(linked_server, 'SELECT campo1, campo2, ecc FROM tabella')

e facendo la conversione nella select interna? Se non sbaglio in questo modo
la conversione viene fatta dal server remoto...

LB

"rocco pasca" <rocco...@hotmail.com> wrote in message

news:#ogmZKKlCHA.2632@tkmsftngp12...

Luca Bianchi

unread,
Nov 25, 2002, 4:07:50 PM11/25/02
to
...aggiungiamo anche questo alla biblioteca... :-)))
 
    LB
"Lorenzo Benaglia" <lbenagl...@tin.it> ha scritto nel messaggio news:artlan$lncia$1...@ID-154627.news.dfncis.de...
 
Ciao Luca & Rocco,
 

Gianluca Hotz

unread,
Nov 28, 2002, 4:16:59 AM11/28/02
to
"rocco pasca" <rocco...@hotmail.com> wrote in message
news:#Bm$atJlCHA.2412@tkmsftngp12...

> il mio problema è che leggo tramite sqlServer su altri db remoti, in
> particolare db2.
> lui riconosce che il campo di partenza è di tipo date e lo mappa bene,
> ma se
> in partenza mi trovo una data molto vecchia (una inizializzazione
> fatta ad
> esempio all'1/1/1) non posso leggere il record (perchè non posso fare
> nemmeno un cast).
> Suggerimenti?

Ciao Rocco,
mi permetto di intervenire e dire anche la mia.

Prima di tutto una considerazione relativa al trattamento
di date "molto vecchie" (si vede che sto leggendo sto libro
sulle date ? :-) ed alla loro gestione sia con metodi alternativi
che non.

Supponiamo di modellare un database per contenere manuscritti,
poesie, lettere e quant'altro che abbiano una rilevanza storica.

Supponiamo di avere una tabella di questo tipo:

CREATE TABLE dbo.lettere (
IDLettera int NOT NULL,
Anno int NOT NULL,
Mese int NOT NULL,
Giorno int NOT NULL,
CONSTRAINT pk_lettere
PRIMARY KEY (IDLettera)
)

Inserisco questa riga:

INSERT dbo.lettere
VALUES (1, 1582, 10, 8)

Domanda: questa riga, che rapperesenta il fatto la lettera
con identificativo 1 e' stata scritta il giorno 8 Ottobre 1582,
e' vera ?

Risposta: dipende!

Il problema e' sta nel fatto che un anno tropicale dura
approssimativamente 365,242191 giorni.

Ai tempi dell'impero romano, almeno per un certo periodo,
la durata di un anno era di circa 366,25 con il risultato
di avere un divario di circa 1 mese ogni 30 anni.

Cesare, su consiglio di alcuni astronomi, decreto' che la
durata media di un anno dovesse essere di 365,25 giorni,
riducendo cosi' il divario a circa 13 minuti all'anno.

In questo calendario, detto Giuliano, un anno e' di 365
giorni con una correzione di un giorno ogni 4 anni (cioe'
ogni 4 anni l'anno dura 366 giorni).

Ma anche pochi minuti ogni anno possono dare dei problemi,
nel 1581 l'equinozio di primavera cadde il 2 Aprile al posto
del 21 Marzo.

Papa Gregorio decise allora di riformare il calendario
portando la durata media di un anno a 365,2425 giorni
riducendo cosi' il divario con la durata dell'anno tropicale
a 25,96 secondi.

Questo calendario, detto Gregoriano, per la durata di anno
prevede le stesse regole di quello Giuliano, ovvero 365 giorni
con l'aggiunta di un giorno ogni 4 anni, ma introduce una
nuova regola: se l'anno e' divisibile per 100 non deve durare
366 giorni ma 365 con l'eccezione degli anni che sono
divisibili anche per 400 (anno 2000?).

Oltre alla regolamentazione di come gestire lo scarto,
l'introduzione dei due calendari implico' anche una
rettifica del calendario per sincronizzarlo.

Tralasciamo i dettagli relativi al passaggio al calendario
Giuliano, per il passaggio a quello Gregoriano fu' deciso
di eliminare 10 giorni: dal 5 Ottobre al 14 Ottobre 1582.

Questa decisione da luogo a tutta una serie di problematiche
da gestire se dobbiamo gestire un database storico.

Prima di tutto le funzioni che sommano e sottraggono date
devono gestire il problema: ad esempio se stiamo applicando
il calendario Gregoriano il giorno dopo il 4 Ottobre 1582
e' il 15 Ottobre 1582 e non il 5 Ottobre 1582.

Tornando alla domanda, se e' lecita la data 8 Ottobre 1582,
potremmo allora dire che non e' valida se interpretata
secondo il calendario Gregoriano.

Eppure potremmo avere in mano una lettera di quel tempo
che riporta proprio quella data.

Questo perche' l'adozione del calendario Gregoriano e'
avvenuta in tempi differenti tra le varie popolazioni.

Ad esempio l'Inghilterra, e le sue colonie, lo hanno
adottato solo nel 1752 tra l'altro eliminando i giorni
dal 3 Settembre 1752 al 12 Settembre 1752.

Quindi trattando date storiche dobbiamo tenere conto
anche del contesto geografico e storico.

Lo standard SQL adotta il calendario Gregoriano quindi
dobbiamo tenerne conto ed effettuare eventualmente le
dovute conversioni (ad esempio mi risulta che Oracle
pur ammettendo l'inserimento della data 8 Ottobre 1582,
nelle funzioni che sommano/sottraggono le date ragiona
seconda il calendario, cioe' il giorno dopo il 4 Ottobre
1852 e' effettivamente il 15 Ottobre 1852).

Inoltre, non essendo tale claendario specificato per le
date precedenti il 1852, dobbiamo sapere come l'RDBMS le
considera (presumibilmente estende le regole del calendario
Gregoriano fino all'anno 1).

Per complicare ulteriormente le cose possiamo aggiungere
che altri paesi hanno adottato il calendario in tempi
diversi, che alcuni paesi hanno tutt'ora dei calendari
diversi, che ci sono molte altre sottigliezze se dobbiamo
trattare le date prima e dopo Cristo.

Tornando pero' al tuo problema, l'utilizzo della data di
inizio calendario (0001-01-01) e di quella di fine calendario
(9999-12-31) e' piuttosto comune per indicare il periodo di
validita' dei dati.

Riprendendo l'esempio delle persone e dei ruoli:

idpersona idruolo datainizio datafine
11122333 120033 0001-01-01 1996-06-01
11122333 120034 1996-06-01 1998-10-01
11122333 120035 1998-10-01 9999-12-31

La prima riga indica che la persona con identificativo
11122333 ha ricoperto il ruolo 120033 dall'inizio dei
tempi fino al 1 Giugno 1996.

Mentre l'ultima riga indica che la persona con
identificativo 11122333 ha iniziato ricoprire il ruolo
120035 il 1 Ottobre 1998 e lo sta tutt'ora ricoprendo.

Mentre nel secondo caso trovo sia pratico e vincente
usare la data di fine calendario (al posto del valore
NULL o di qualche altro valore fittizzio) nel primo
caso quasi sempre c'e' l'alternativa di poter
utilizzare o una data significativa (ad esempio se
ho a disposizione la data di assunzione) oppure una
data minima assoluta per tutte le date che indicano
l'inizia di validita' (informalmente, una specie di data
di partenza del sistema).

Facendo la Query remota potresti usare il construtto
CASE per trasformare queste date che hanno funzione di
delimitatore in alter date che sono supportate in
SQL Server.

Attenzione al fatto che in alcuni casi una data di quel
tipo potrebbe anche indicare semplicemente assenza del
valore, nel qual caso puo' essere trasformata piu'
coerentemente in NULL.

Ciao,
--
Gianluca Hotz
Backoffice MVP (SQL Server) MCP SQL Server and MCP Windows
Vice-President of the Italian User Group for SQL Server
Founding Member of the Italian User Group for .NET
http://www.ghotz.com
http://www.ugiss.org

Lorenzo Benaglia

unread,
Nov 28, 2002, 4:40:49 AM11/28/02
to
"Gianluca Hotz" <gh...@alphasys.it> wrote in message
news:O1$Jp$rlCHA.1284@tkmsftngp02...

Ciao Gianluca,
grazie infinite per questa stupenda lezione storica sulla gestione delle
date.

Gianluca Hotz

unread,
Nov 28, 2002, 5:03:53 AM11/28/02
to
"Lorenzo Benaglia" <lbenagl...@tin.it> wrote in message
news:as4ob1$np2ds$1...@ID-154627.news.dfncis.de...

> "Gianluca Hotz" <gh...@alphasys.it> wrote in message
> news:O1$Jp$rlCHA.1284@tkmsftngp02...
>
> Ciao Gianluca,
> grazie infinite per questa stupenda lezione storica sulla gestione
> delle
> date.

In realta' non e' che io sappia queste cose, faccio il topo
di biblioteca, scrivere queste risposte mi obbliga a fare delle
ricerce e delle prove quindi sono il primo ad imparare :-)

Gianluca.


0 new messages