Considérer ce qui suit:
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
Production:
dt dt2 d
------------------ -------------------- --------
0x0000A13900000000 0x07000000000094360B 0x94360B
Maintenant, je comprends déjà de la documentation qui datetime
a une plage plus petite, et commence à partir de 1753-01-01, datetime2
et date
utilise 0001-01-01 comme date de début.
Ce que je ne comprends pas bien, est que datetime
semble être peu endian tout datetime2
et date
sont big-endian. Si tel est le cas, comment peuvent-ils même être correctement triés?
Considérez si je veux savoir combien de jours entiers sont représentés par un date
type. On pourrait penser que vous pourriez faire ceci:
declare @d date
set @d = '0001-01-31'
select cast(convert(varbinary, @d) as int)
Mais en raison de l'endianisme, vous obtenez 1966080 jours!
Pour obtenir le résultat correct de 30 jours, vous devez l'inverser:
select cast(convert(varbinary,reverse(convert(varbinary, @d))) as int)
Ou bien sûr, vous pouvez le faire:
select datediff(d,'0001-01-01', @d)
Mais cela signifie en interne quelque part qu'il inverse les octets de toute façon.
Alors pourquoi ont-ils changé d'endianisme?
Je m'en soucie uniquement parce que je travaille sur un UDT personnalisé dans SQLCLR et l'ordre binaire des octets semble y avoir de l'importance, mais ces types intégrés semblent beaucoup plus flexibles. SQL Server a-t-il quelque chose de interne où chaque type peut fournir son propre algorithme de tri? Et si oui, existe-t-il un moyen de puiser dans cela pour mon UDT personnalisé?
Voir aussi, une question connexe (mais différente) sur StackOverflow.
IComparable
, mais il n'est utilisé que côté client. SQL Server l'ignore et désactive l'ordre des octets.
IComparable
? Vous ne devriez jamais avoir besoin de fouiller dans la représentation interne des types de données.