Nguyên nhân của vấn đề này với CONVERT () là gì?


12

Hãy xem xét hai tuyên bố sau:

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

Cả hai tuyên bố trở lại -1; không phải là không chính xác vì giá trị nhị phân thứ hai là thập phân 65,536 cao hơn giá trị thứ nhất, phải không?

Chắc chắn điều này không thể là do cắt ngắn im lặng?

Nếu tôi chạy các câu lệnh sau:

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

Tôi gặp lỗi sau:

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

Làm thế nào tôi có thể chẩn đoán những gì đang xảy ra ở đây?

Tôi đang chạy cái này trên SQL Server 2012, v11.0.5058. Kết quả giống nhau trên SQL Server 2008 R2 SP2, SQL Server 2005 và SQL Server 2000.


4
Số thập phân và toàn bộ được mã hóa rất khác nhau trong varbinary. Số thập phân cần nhiều không gian hơn. Hãy thửSELECT CONVERT(VARBINARY(32), 1), CONVERT(VARBINARY(32), 1.0);
Aaron Bertrand

4
Aaron là tại chỗ. Bộ não của bạn đang chuyển đổi dữ liệu nhị phân thành dữ liệu số nguyên sau đó chuyển thẳng sang số, nhưng SQL Server không thực hiện chuyển đổi ngầm định từ nhị phân -> số nguyên -> số (x, y). Để SQL Server tuân theo quy trình suy nghĩ của bạn, bạn phải làm một cái gì đó như thế này : PRINT CONVERT(NUMERIC(38, 0), convert(int, 0x00000001), 0); PRINT CONVERT(NUMERIC(38, 0), convert(int, 0x00010001), 0);.
Thomas Stringer

5
Byte đầu tiên là scale (0x01 = 1), byte thứ hai có độ chính xác (0x00 = 0), byte cuối cùng là giá trị (0x01 = 1). Không chắc chắn những gì ba và bốn là cho. Dấu hiệu ở đó nhưng không cần hai byte. Chắc chắn việc lật bit đó dường như không ảnh hưởng gì.
Martin Smith

1
Cảm ơn, @MartinSmith - làm thế nào trên trái đất bạn đã xác định hai byte đầu tiên được sử dụng như vậy? Đó có phải là tài liệu?
Max Vernon

3
@AaronBertrand: Bạn có muốn đưa ra câu trả lời không? Chúng tôi có thể đánh dấu điều này ra khỏi danh sách "chưa được trả lời".
Jon của tất cả các giao dịch

Câu trả lời:


2

Số thập phân và toàn bộ được mã hóa rất khác nhau trong varbinary. Số thập phân cần nhiều không gian hơn. Thử:

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

Đối với mục tiêu cuối cùng của bạn, lưu trữ toàn bộ số dưới dạng phương sai để tiết kiệm dung lượng, tôi nghĩ bạn đã tự trả lời câu hỏi đó - không đáng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.