Pertimbangkan yang berikut ini:
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
Keluaran:
dt dt2 d
------------------ -------------------- --------
0x0000A13900000000 0x07000000000094360B 0x94360B
Sekarang, saya sudah mengerti dari dokumentasi yang datetime
memiliki rentang yang lebih kecil, dan mulai dari 1753-01-01, sementara datetime2
dan date
menggunakan 0001-01-01 sebagai tanggal mulai.
Apa yang saya tidak mengerti, adalah yang datetime
tampaknya menjadi little-endian sementara datetime2
dan date
big-endian. Jika itu masalahnya, bagaimana mereka bisa disortir dengan baik?
Pertimbangkan jika saya ingin tahu berapa hari bilangan bulat diwakili oleh suatu date
tipe. Anda akan berpikir Anda bisa melakukan ini:
declare @d date
set @d = '0001-01-31'
select cast(convert(varbinary, @d) as int)
Tetapi karena endianness, Anda mendapatkan 1966080 hari!
Untuk mendapatkan hasil yang benar selama 30 hari, Anda harus membaliknya:
select cast(convert(varbinary,reverse(convert(varbinary, @d))) as int)
Atau, tentu saja Anda dapat melakukan ini:
select datediff(d,'0001-01-01', @d)
Tapi itu berarti secara internal di suatu tempat ia membalik byte.
Jadi mengapa mereka beralih endianness?
Saya hanya peduli karena saya sedang mengerjakan custom UDT di SQLCLR dan urutan biner dari byte tampaknya penting di sana, tetapi tipe bawaan ini tampak jauh lebih fleksibel. Apakah SQL Server memiliki sesuatu internal di mana setiap jenis dapat menyediakan algoritma pengurutan itu sendiri? Dan jika demikian, apakah ada cara saya dapat memanfaatkannya untuk UDT khusus saya?
Lihat juga, pertanyaan terkait (tetapi berbeda) di StackOverflow.
IComparable
, tetapi hanya digunakan sisi klien. SQL Server mengabaikannya dan mematikan urutan byte.
IComparable
? Anda tidak perlu menggali representasi internal tipe data, selamanya.