CONVERT () ile bu sorunun nedeni nedir?


12

Aşağıdaki iki ifadeyi göz önünde bulundurun:

PRINT CONVERT(NUMERIC(38, 0), 0x0100000001, 0);
PRINT CONVERT(NUMERIC(38, 0), 0x0100010001, 0);

Her iki ifade de geri döner -1; ikinci ikili değer ondalık sayı ilk değerden 65.536 yüksek olduğu için yanlış değil, değil mi?

Elbette bu sessiz kesilmeden kaynaklanamaz mı?

Aşağıdaki ifadeleri çalıştırırsam:

PRINT CONVERT(NUMERIC(38, 0),   0x00000001, 0);
PRINT CONVERT(NUMERIC(38, 0),   0x00010001, 0);

Aşağıdaki hatayla karşılaştım:

Msg 8114, Level 16, State 5, Line 1
Error converting data type varbinary to numeric.

Burada olanları nasıl teşhis edebilirim?

SQL Server 2012, v11.0.5058 üzerinde çalışıyorum. Sonuçlar SQL Server 2008 R2 SP2, SQL Server 2005 ve SQL Server 2000'de aynıdır.


4
Ondalık ve tam sayılar değişken olarak çok farklı şekilde kodlanır. Ondalık basamakların daha fazla alana ihtiyacı vardır. DeneSELECT CONVERT(VARBINARY(32), 1), CONVERT(VARBINARY(32), 1.0);
Aaron Bertrand

4
Aaron yerinde. Beyniniz ikili verileri tamsayıya, sonra doğrudan sayısalya dönüştürüyor, ancak SQL Server bu örtülü dönüşümü ikili -> tamsayı -> sayısal (x, y) yapmıyor. SQL Server düşünce süreci takip etmek için, böyle bir şey yapmak zorundayız: PRINT CONVERT(NUMERIC(38, 0), convert(int, 0x00000001), 0); PRINT CONVERT(NUMERIC(38, 0), convert(int, 0x00010001), 0);.
Thomas Stringer

5
İlk bayt ölçeğidir (0x01 = 1), İkinci bayt doğrudur (0x00 = 0), Son bayt değerdir (0x01 = 1). Üç ve dört baytın ne için olduğundan emin değilim. İşaret orada ama iki bayt gerektirmiyor. Kesinlikle bu parçayı çevirmek hiçbir şeyi etkilememiş gibi görünüyor.
Martin Smith

1
Teşekkürler @MartinSmith - ilk iki baytın nasıl kullanıldığını nasıl belirlediniz? Bu belgelenmiş mi?
Max Vernon

3
@AaronBertrand: Bunu cevaplamak ister misiniz? Bunu "cevapsız" listesinden işaretleyebiliriz.
Tüm

Yanıtlar:


2

Ondalık ve tam sayılar değişken olarak çok farklı şekilde kodlanır. Ondalık basamakların daha fazla alana ihtiyacı vardır. Deneyin:

SELECT CONVERT(VARBINARY(32), 1), CONVERT(VARBINARY(32), 1.0);

Nihai hedefinize gelince, yer kazanmak için tam sayıları varbinli olarak saklamak, bence bu soruyu kendiniz cevapladınız - buna değmez.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.