Considere o seguinte:
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
Resultado:
dt dt2 d
------------------ -------------------- --------
0x0000A13900000000 0x07000000000094360B 0x94360B
Agora, eu já entendem a partir da documentação que datetime
tem um alcance menor, e começa a partir de 1753/01/01, enquanto datetime2
e date
usar 0001-01-01 como sua data de início.
O que eu não entendo, porém, é que datetime
parece ser um pouco endian enquanto datetime2
e date
é um big end. Se for esse o caso, como eles podem ser classificados adequadamente?
Considere se eu quero saber quantos dias inteiros são representados por um date
tipo. Você pensaria que poderia fazer isso:
declare @d date
set @d = '0001-01-31'
select cast(convert(varbinary, @d) as int)
Mas devido à persistência, você recebe 1966080 dias!
Para obter o resultado correto de 30 dias, é necessário revertê-lo:
select cast(convert(varbinary,reverse(convert(varbinary, @d))) as int)
Ou, é claro, você pode fazer isso:
select datediff(d,'0001-01-01', @d)
Mas isso significa que internamente em algum lugar está invertendo os bytes de qualquer maneira.
Então, por que eles trocaram endianness?
Só me importo porque estou trabalhando em um UDT personalizado no SQLCLR e a ordem binária dos bytes parece importar lá, mas esses tipos internos parecem muito mais flexíveis. O SQL Server tem algo interno onde cada tipo obtém para fornecer seu próprio algoritmo de classificação? E, em caso afirmativo, existe uma maneira de aproveitar isso para o meu UDT personalizado?
Consulte também uma pergunta relacionada (mas diferente) no StackOverflow.
IComparable
, mas ele é usado apenas no lado do cliente. O SQL Server o ignora e sai da ordem dos bytes.
IComparable
? Você não precisa se aprofundar na representação interna dos tipos de dados.