Konwertuj wartości liczbowe ciągów za pomocą przecinka jako separatora dziesiętnego na NUMERIC (10, 2)


12

Mam tabelę SQL kolumn varchar, które zawierają liczby sformatowane w języku greckim (. Jako separator tysięcy i przecinek jako separator dziesiętny)

Klasyczna konwersja

CONVERT(numeric(10,2),REPLACE([value],',','.'))

nie działa, ponieważ. (separator tysięcy) zabija konwersję

Np. Spróbuj

CONVERT(numeric(10,2),REPLACE('7.000,45',',','.'))

Chcę przekonwertować takie wartości na wartości liczbowe (10,2)

Wszelkie sugestie, jak sobie z tym poradzić?

Odpowiedzi:


10

( Jeśli używasz programu SQL Server 2012 lub nowszego, zapoznaj się z odpowiedzią @ wBob, aby uzyskać bardziej przejrzyste podejście. Podejście przedstawione w mojej odpowiedzi poniżej jest wymagane tylko w przypadku korzystania z programu SQL Server 2008 R2 lub starszego ).

Nie potrzebujesz (lub nie chcesz) separatora tysięcy podczas konwersji na NUMERIC, niezależnie od tego, czy jest to przecinek, kropka czy spacja, więc po prostu pozbądź się ich najpierw. Następnie zamień przecinek na kropkę / dziesiętną i gotowe:

SELECT CONVERT(NUMERIC(10, 2), 
               REPLACE(
                       REPLACE('7.000,45', '.', ''),
                       ',', '.'
                      )
              ) AS [Converted];

Zwroty:

7000.45

Dla kompletności powinienem wspomnieć, że próbowałem również:

  • SET LANGUAGE Greek;

  • Patrząc na różne style formatu dla CONVERT , ale tutaj nic nie ma zastosowania.

  • Funkcja FORMAT , ale typem danych wejściowych musi być wartość liczbowa lub data / czas / data / godzina (która została wprowadzona w SQL Server 2012, więc nie dotyczy SQL Server 2008 R2 lub starszych).

I nic innego nie działało. Miałem nadzieję znaleźć coś bardziej eleganckiego niż dwa REPLACEpołączenia, ale jak dotąd nie miałem szczęścia.


Ponadto, aby wspomnieć, chociaż nie jest to czyste rozwiązanie T-SQL, można to również osiągnąć za pomocą SQLCLR. Jest też gotowa funkcja, która robi to w bibliotece SQL # (którą napisałem) o nazwie String_TryParseToDecimal . Ta funkcja jest dostępna w wersji darmowej i działa w każdej wersji SQL Server, począwszy od SQL Server 2005:

SELECT SQL#.String_TryParseToDecimal('7.000,45', 'el-GR');

Zwroty:

7000.45000000000000000000

10

Jakiej wersji programu SQL Server używasz? Począwszy od SQL Server 2012, możesz używać TRY_PARSE z jego USING cultureargumentem. Możesz także użyć PARSE , przy czym różnica PARSEnie powiedzie się, jeśli konwersja się nie powiedzie i TRY_PARSEzwróci NULLnp

DECLARE @t TABLE ( x VARCHAR(10) )

INSERT INTO @t
VALUES ( '7.000,45' ), ( 'xxx' )

SELECT x, 
    TRY_PARSE( x AS NUMERIC(10,2) USING 'El-GR' ) x
FROM @t

Wyniki testów

HTH


2
Właśnie dodałem notatkę na początku mojej odpowiedzi, kierując czytelników tutaj, jeśli używają programu SQL Server 2012 lub nowszego.
Solomon Rutzky

0

W moim przypadku działał następujący kod:

select convert(varchar,FORMAT(123456789.0258,'###,###,###.00','de-de'))

wyjście: 123.456.789,03


lub wybierz konwersję (varchar, FORMAT (obsada (twojaWartość jako wartość liczbowa (10,2)), „###, ###, ###. 00 ',„ de-de ”))
Shahed Adnan

3
wygląda na to, że odpowiadasz na odwrotny problem, o co poprosił PO. nie chcą formatować wartości liczbowych, chcą konwertować sformatowane wartości varchar na liczby.
ypercubeᵀᴹ

1
Również dwie uwagi: 1) zawsze określić długość dla VARCHAR, NVARCHAR, CHARi NCHARtypów. Domyślna wartość to 30 w niektórych przypadkach i 1 w innych przypadkach, co powoduje, że kod jest nieusuwalny / podatny na błędy. 2) nie potrzebujesz dokładnego układu podczas używania #. Potrzebujesz tylko jednej z nich (np. #) Dla wszystkich cyfr, ale bez separatora tysięcy, lub dwóch z nich oddzielonych przecinkiem (np. #,#), Aby uzyskać wszystkie cyfry i separator tysięcy. W związku z tym SELECT CONVERT(VARCHAR(20), FORMAT(123456789.0258, N'#,#.00', N'de'));zwraca ten sam wynik, co sugerujesz.
Solomon Rutzky
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.