2012-12-19 80 views
5

Tôi phải đếm các chữ số sau dấu thập phân trong cơ sở dữ liệu được lưu trữ bởi máy chủ MS Sql (2005 hoặc 2008 không quan trọng), để sửa một số lỗi do người dùng tạo ra. Tôi có cùng một vấn đề trên một cơ sở dữ liệu Oracle, nhưng có những thứ ít phức tạp hơn. Điểm mấu chốt là trên Oracle, chọn là:Làm cách nào để lấy số chữ số sau dấu thập phân trong cột phao trong ms sql?

select length(substr(to_char(MY_FIELD), instr(to_char(MY_FILED),'.',1,1)+1, length(to_char(MY_FILED)))) as digits_length 
from MY_TABLE 

nơi tệp được gửi My_filed là phao (38).

trên MS SQL Server tôi cố gắng sử dụng:

select LEN(SUBSTRING(CAST(MY_FIELD AS VARCHAR), CHARINDEX('.',CAST(MY_FILED AS VARCHAR),1)+1, LEN(CAST(MY_FIELD AS VARCHAR)))) as digits_length 
from MY_TABLE 

Vấn đề là trên MS SQL Server, khi tôi đúc MY_FIELD như varchar số phao được cắt ngắn bởi chỉ có 2 số thập phân và số lượng của các chữ số là sai. Ai đó có thể cho tôi bất kỳ gợi ý nào không?

Trân trọng.

Trả lời

5

Tôi đã nhận được từ bạn tôi một giải pháp rất đơn giản, điều đó thật tuyệt. Vì vậy, tôi sẽ đăng cách giải quyết để giúp những người khác ở cùng vị trí với tôi.

Thứ nhất, thực hiện chức năng:

create FUNCTION dbo.countDigits(@A float) RETURNS tinyint AS 
BEGIN 
declare @R tinyint 
IF @A IS NULL 
    RETURN NULL 
set @R = 0 
while @A - str(@A, 18 + @R, @r) <> 0 
begin 
    SET @R = @R + 1 
end 
RETURN @R 
END 
GO 

Thứ hai:

select MY_FIELD, 
dbo.countDigits(MY_FIELD) 
from MY_TABLE 

Sử dụng chức năng sẽ giúp bạn có được con số chính xác của các chữ số sau dấu thập phân.

0

Điều đầu tiên là chuyển sang sử dụng CONVERT thay vì CAST. Sự khác biệt là, với CONVERT, bạn có thể chỉ định mã định dạng. CAST sử dụng bất kỳ mã định dạng mặc định nào là:

Khi biểu thức là nổi hoặc thực, kiểu có thể là một trong các giá trị được hiển thị trong bảng sau. Các giá trị khác được xử lý là 0.

Không có định dạng nào đặc biệt hấp dẫn, nhưng tôi nghĩ cách tốt nhất để bạn sử dụng sẽ là 2. Vì vậy, nó sẽ là:

CONVERT(varchar(25),MY_FIELD,2) 

Điều này sẽ không may, cho bạn giá trị theo ký hiệu khoa học và luôn có 16 chữ số, ví dụ: 1.23456789e+000. Để có được số chữ số "thực", bạn cần chia số này ra, tính số chữ số trong phần thập phân và bù số bằng số được cung cấp trong số mũ.


Và, tất nhiên, hãy cẩn thận chèn thông thường/cảnh báo về việc cố gắng để nói về chữ số khi giao dịch với một số trong đó có một định nghĩa nhị phân đại diện. Số "chữ số" của một số float cụ thể có thể khác nhau tùy thuộc vào cách nó được tính toán.

6
SELECT 
LEN(CAST(REVERSE(SUBSTRING(STR(MY_FIELD, 13, 11), CHARINDEX('.', STR(MY_FIELD, 13, 11)) + 1, 20)) AS decimal)) 
from TABLE 
+0

Chỉ cần lưu ý rằng đối với toàn bộ số, nó trả về 1 thay vì 0 được mong đợi. – user824276

0

Tôi không chắc chắn về tốc độ. vv hoặc sự thanh lịch của mã này. nó đã được cho một số thử nghiệm ad-hoc để tìm giá trị thập phân đầu tiên.nhưng mã này có thể được thay đổi để lặp qua tất cả các số thập phân và tìm lần cuối một giá trị lớn hơn không dễ dàng.

DECLARE @NoOfDecimals  int    = 0 
Declare @ROUNDINGPRECISION numeric(32,16) = -.00001000 

select @ROUNDINGPRECISION = ABS(@ROUNDINGPRECISION) 
select @ROUNDINGPRECISION = @ROUNDINGPRECISION - floor(@ROUNDINGPRECISION) 


while @ROUNDINGPRECISION < 1 
Begin 
    select @NoOfDecimals = @NoOfDecimals +1 
    select @ROUNDINGPRECISION = @ROUNDINGPRECISION * 10 

end; 

select @NoOfDecimals 
Các vấn đề liên quan