Considera lo siguiente:
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
Salida:
dt dt2 d
------------------ -------------------- --------
0x0000A13900000000 0x07000000000094360B 0x94360B
Ahora, yo ya entiendo de la documentación que datetime
tiene un rango menor, y se inicia a partir de 01.01.1753, mientras que datetime2
y date
utilizo 0001-01-01 como su fecha de inicio.
Sin embargo, lo que no entiendo es que datetime
parece ser little endian datetime2
y date
big-endian. Si ese es el caso, ¿cómo pueden clasificarse correctamente?
Considere si quiero saber cuántos días enteros están representados por un date
tipo. Pensarías que podrías hacer esto:
declare @d date
set @d = '0001-01-31'
select cast(convert(varbinary, @d) as int)
Pero debido a la resistencia, ¡obtienes 1966080 días!
Para obtener el resultado correcto de 30 días, debe revertirlo:
select cast(convert(varbinary,reverse(convert(varbinary, @d))) as int)
O, por supuesto, puedes hacer esto:
select datediff(d,'0001-01-01', @d)
Pero eso significa internamente en algún lugar que está invirtiendo los bytes de todos modos.
Entonces, ¿por qué cambiaron endianness?
Solo me importa porque estoy trabajando en un UDT personalizado en SQLCLR y el orden binario de los bytes parece importar allí, pero estos tipos incorporados parecen mucho más flexibles. ¿SQL Server tiene algo interno donde cada tipo puede proporcionar su propio algoritmo de clasificación? Y si es así, ¿hay alguna manera de aprovechar eso para mi UDT personalizado?
Consulte también una pregunta relacionada (pero diferente) sobre StackOverflow.
IComparable
, pero solo se usa del lado del cliente. SQL Server lo ignora y sale del orden de bytes.
IComparable
? No debería necesitar profundizar en la representación interna de los tipos de datos, nunca.