Converti valori numerici di stringa con virgola come separatore decimale in NUMERICO (10, 2)


12

Ho una tabella SQL di colonne varchar che contengono numeri in formato greco (. Come separatore delle migliaia e virgola come separatore decimale)

La conversione classica

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

non funziona perché il. (mille separatore) uccide la conversione

Ad esempio, prova

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

Voglio convertire tali valori in numerici (10,2)

Qualche suggerimento su come gestirlo?

Risposte:


10

( Se si utilizza SQL Server 2012 o versioni successive, consultare la risposta di @ wBob per un approccio più pulito. L'approccio descritto nella mia risposta di seguito è necessario solo se si utilizza SQL Server 2008 R2 o versioni precedenti. )

Non è necessario (o non si desidera) il separatore delle migliaia durante la conversione NUMERIC, indipendentemente dal fatto che si tratti di virgola, punto o spazio, quindi eliminarli prima. Quindi converti la virgola in un punto / decimale e hai finito:

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

Ritorna:

7000.45

Per completezza, dovrei menzionare che ho anche provato:

  • SET LANGUAGE Greek;

  • Guardando vari stili di formato per CONVERT , ma qui non si applica nulla.

  • La funzione FORMAT , ma il tipo di input deve essere un valore numerico o data / ora / datetime (che è stato introdotto in SQL Server 2012, quindi non applicabile a SQL Server 2008 R2 o precedenti).

E nient'altro sembrava funzionare. Speravo di trovare qualcosa di più elegante di due REPLACEchiamate, ma finora nessuna tale fortuna.


Inoltre, solo per citare, sebbene non sia una soluzione T-SQL pura, ciò può essere realizzato anche tramite SQLCLR. E c'è una funzione pre-fatta che lo fa nella libreria SQL # (che ho scritto) chiamata String_TryParseToDecimal . Questa funzione è disponibile nella versione gratuita e funziona in tutte le versioni di SQL Server a partire da SQL Server 2005:

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

Ritorna:

7000.45000000000000000000

10

Quale versione di SQL Server stai usando? Da SQL Server 2012 in poi è possibile utilizzare TRY_PARSE con il suo USING cultureargomento. Puoi anche usare PARSE , la differenza non PARSEriuscirà se la conversione fallisce e TRY_PARSErestituirà a NULL, ad es

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

risultati del test

HTH


1
Ho appena aggiunto una nota all'inizio della mia risposta, indirizzando i lettori qui se utilizzano SQL Server 2012 o versioni successive.
Solomon Rutzky,

0

Il seguente codice ha funzionato nel mio caso:

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

uscita: 123.456.789,03


oppure seleziona convert (varchar, FORMAT (cast (yourValue as numeric (10,2)), '###, ###, ###. 00', 'de-de'))
Shahed Adnan,

2
sembra che tu stia rispondendo al problema inverso di ciò che l'OP ha chiesto. non vogliono formattare valori numerici, vogliono convertire valori varchar formattati in valori numerici.
ypercubeᵀᴹ

1
Inoltre, due note: 1) specificano sempre una lunghezza per VARCHAR, NVARCHAR, CHAR, e NCHARtipi. Il valore predefinito è 30 in alcuni casi e 1 in altri casi, il che rende il codice non mantenibile / soggetto a errori. 2) non è necessario il layout esatto quando si utilizza #. Hai solo bisogno di uno di essi (ad es. #) Per tutte le cifre, ma senza separatore delle migliaia, o due di loro separati da una virgola (ad es. #,#) Per ottenere tutte le cifre e il separatore delle migliaia. Quindi, SELECT CONVERT(VARCHAR(20), FORMAT(123456789.0258, N'#,#.00', N'de'));restituisce lo stesso output di ciò che stai suggerendo.
Solomon Rutzky,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.