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 datetimea une plage plus petite, et commence à partir de 1753-01-01, datetime2et dateutilise 0001-01-01 comme date de début.
Ce que je ne comprends pas bien, est que datetimesemble être peu endian tout datetime2et datesont 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 datetype. 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.