Учтите следующее:
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
Вывод:
dt dt2 d
------------------ -------------------- --------
0x0000A13900000000 0x07000000000094360B 0x94360B
Теперь я уже понимаю из документации, которая datetime
имеет меньший диапазон и начинается с 1753-01-01, datetime2
а также date
использует 0001-01-01 в качестве даты начала.
Что я не понимаю, хотя, это то, что, datetime
кажется, с прямым порядком байтов в то время как datetime2
и date
с обратным порядком байтов. Если это так, как они могут быть правильно отсортированы?
Подумайте, хочу ли я узнать, сколько целых дней представлено date
типом. Вы могли бы подумать, что вы могли бы сделать это:
declare @d date
set @d = '0001-01-31'
select cast(convert(varbinary, @d) as int)
Но благодаря порядку байтов вы получаете 1966080 дней!
Чтобы получить правильный результат 30 дней, вы должны поменять его местами:
select cast(convert(varbinary,reverse(convert(varbinary, @d))) as int)
Или, конечно, вы можете сделать это:
select datediff(d,'0001-01-01', @d)
Но это означает, что внутренне где-то это все равно обращает байты.
Так почему же они поменяли порядок байтов?
Меня волнует только то, что я работаю над пользовательским UDT в SQLCLR, и двоичный порядок байтов, кажется, там имеет значение, но эти встроенные типы кажутся гораздо более гибкими. Есть ли в SQL Server что-то внутреннее, где каждый тип предоставляет собственный алгоритм сортировки? И если так, есть ли способ, которым я могу использовать это для своего пользовательского UDT?
См. Также связанный (но другой) вопрос о StackOverflow.
IComparable
, но он используется только на стороне клиента. SQL Server игнорирует его и отключает порядок байтов.
IComparable
? Вам никогда не нужно копаться во внутреннем представлении типов данных.