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.
sumber
IComparable
? Anda tidak perlu menggali representasi internal tipe data, selamanya.IComparable
, tetapi hanya digunakan sisi klien. SQL Server mengabaikannya dan mematikan urutan byte.Jawaban:
SQL Server tidak bergantung pada urutan biner untuk tipe datanya "sendiri". Untuk tipe data CLR Anda bisa menggunakan antarmuka iComparable, tetapi seperti yang disebutkan @MattJohnson, SQL Server mengabaikannya:
http://connect.microsoft.com/SQLServer/feedback/details/252230/sqlclr-menyediakan-kemampuan-untuk-menggunakan-icomparable-atau--samailar-mekanisme-untuk-udts
Microsoft tidak mempublikasikan detail tentang bagaimana tipe data yang berbeda disimpan dan bekerja dengan. Namun Books Online secara eksplisit menyatakan bahwa Anda tidak dapat bergantung pada format biner tertentu untuk tipe data tertentu dan bahwa format yang mereka gunakan dapat berubah sewaktu-waktu. Jadi adalah ide yang baik untuk menyimpan INT hanya sebagai itu dan bukan sebagai VARBINARY, karena Anda mungkin tidak dapat membaca data Anda lagi setelah SP berikutnya.
Adapun penyortiran: Sebagian besar inti SQL Server ditulis dalam C ++. Saya menganggap secara internal metode yang mirip dengan iComparable digunakan. Tetapi sekali lagi, tidak ada dokumentasi yang dapat diakses publik tentang ini tersedia. Bahkan jika itu, Anda mungkin tidak akan dapat memanfaatkannya karena perbedaan yang melekat antara .NET dan C ++.
sumber
int
sebagai bidang dukungan CLR UDT saya? Apakah Anda memiliki contoh cara melakukannya? TheCREATE TYPE
pernyataan akan mengambilbase_type
, atau perakitan eksternal - tetapi tidak keduanya.