Considera quanto segue:
declare @dt datetime, @dt2 datetime2, @d date
set @dt = '2013-01-01'
set @dt2 = '2013-01-01'
set @d = '2013-01-01'
select convert(varbinary, @dt) as dt,
convert(varbinary, @dt2) as dt2,
convert(varbinary, @d) as d
Produzione:
dt dt2 d
------------------ -------------------- --------
0x0000A13900000000 0x07000000000094360B 0x94360B
Ora, ho già capito da documentazione che datetime
ha una gamma più piccola, e parte da 1753/01/01, mentre datetime2
e date
uso 0001-01-01 come la loro data di inizio.
Quello che non capisco, però, è che datetime
sembra essere mentre little-endian datetime2
e date
sono big-endian. In tal caso, come possono anche essere adeguatamente ordinabili?
Considera se voglio sapere quanti giorni interi sono rappresentati da un date
tipo. Penseresti di poter fare questo:
declare @d date
set @d = '0001-01-31'
select cast(convert(varbinary, @d) as int)
Ma a causa dell'endianità, ottieni 1966080 giorni!
Per ottenere il risultato corretto di 30 giorni, è necessario invertirlo:
select cast(convert(varbinary,reverse(convert(varbinary, @d))) as int)
Oppure, ovviamente puoi farlo:
select datediff(d,'0001-01-01', @d)
Ma ciò significa internamente da qualche parte che sta invertendo comunque i byte.
Allora perché hanno cambiato endianness?
Mi interessa solo perché sto lavorando su un UDT personalizzato in SQLCLR e l'ordine binario dei byte sembra importare lì, ma questi tipi predefiniti sembrano molto più flessibili. SQL Server ha qualcosa di interno in cui ogni tipo arriva a fornire il proprio algoritmo di ordinamento? E se è così, c'è un modo in cui posso attingere a quello per il mio UDT personalizzato?
Vedi anche, una domanda correlata (ma diversa) su StackOverflow.
IComparable
, ma viene utilizzato solo sul lato client. SQL Server lo ignora e disattiva l'ordine dei byte.
IComparable
? Non dovresti mai dover scavare nella rappresentazione interna dei tipi di dati, mai.