2012-12-19 10 views
5

Muszę policzyć cyfry po przecinku w bazie danych obsługiwanej przez serwer MS SQL (2005 lub 2008, nie ma znaczenia), w celu skorygowania błędów popełnionych przez użytkowników. Mam taki sam problem w bazie danych Oracle, ale tam są rzeczy mniej skomplikowane. Konkluzja jest Oracle SELECT jest:Jak uzyskać liczbę cyfr po przecinku w kolumnie swobodnej w 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 

gdzie złożony My_filed jest pływak (38).

Na serwerze MS SQL próbuję użyć:

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 

Problemem jest to, że na MS SQL Server, gdy rzucam MY_FIELD jako varchar liczby typu float są obcinane przez zaledwie 2 miejsc po przecinku, a liczba cyfr jest źle. Czy ktoś może mi podać jakieś wskazówki?

Pozdrawiamy.

Odpowiedz

5

Otrzymałem od mojego przyjaciela bardzo proste rozwiązanie, które jest po prostu świetne. Opublikuję obejście, aby pomóc innym w tej samej sytuacji, co ja.

Po pierwsze, upewnij funkcja:

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 

drugie:

select MY_FIELD, 
dbo.countDigits(MY_FIELD) 
from MY_TABLE 

Korzystanie z funkcji będzie Ci dokładną liczbę cyfr po przecinku.

0

Pierwszą rzeczą jest przejście na używanie CONVERT zamiast CAST. Różnica polega na tym, że pod numerem CONVERT można podać kod formatu. CAST używa dowolnego domyślnego kodu formatu:

Gdy wyrażenie jest zmiennoprzecinkowe lub rzeczywiste, styl może być jedną z wartości pokazanych w poniższej tabeli. Inne wartości są przetwarzane jako 0.

Żaden z formatów są szczególnie atrakcyjne, ale myślę, że najlepiej do użycia byłby 2. Tak więc byłoby:

CONVERT(varchar(25),MY_FIELD,2) 

To niestety da ci wartość w notacji naukowej i zawsze z 16 cyframi, np. 1.23456789e+000. Aby uzyskać liczbę "prawdziwych" cyfr, musisz podzielić tę liczbę osobno, obliczyć liczbę cyfr w części dziesiętnej i zrównoważyć ją liczbą podaną w wykładniku.


I, oczywiście, włóż tradycyjnych zastrzeżeń/ostrzeżenia o próbują mówić o cyfry gdy ma do czynienia z numerem, który ma zdefiniowaną binarny reprezentacji. Liczba "cyfr" określonego modelu float może się różnić w zależności od sposobu obliczenia.

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

Należy zauważyć, że dla liczb całkowitych zwraca 1 zamiast oczekiwanego 0. – user824276

0

Nie jestem pewien szybkości. itp. lub elegancja tego kodu. to było dla niektórych testów ad-hoc, aby znaleźć pierwszą wartość dziesiętną.ale ten kod mógł zostać zmieniony tak, by przechodził przez wszystkie dziesiętne miejsca i znajdował się po raz ostatni, gdy wartość była większa od zera.

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 
Powiązane problemy