Converter valores numéricos de sequência de caracteres com vírgula como separador decimal em NUMERIC (10, 2)


12

Eu tenho uma tabela SQL de colunas varchar que contém números formatados em grego (. Como separador de milhar e vírgula como separador decimal)

A conversão clássica

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

não funciona porque o. (separador de milhar) mata a conversão

Por exemplo, tente

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

Eu quero converter esses valores para numéricos (10,2)

Alguma sugestão de como lidar com isso?

Respostas:


10

( Se você estiver usando o SQL Server 2012 ou mais recente, consulte a resposta de @ wBob para uma abordagem mais limpa. A abordagem descrita em minha resposta abaixo será necessária apenas se você estiver usando o SQL Server 2008 R2 ou mais antigo. )

Você não precisa (ou deseja) o separador de milhares ao converter para NUMERIC, independentemente de ser vírgula, ponto ou espaço, portanto, basta se livrar deles primeiro. Em seguida, converta a vírgula em um ponto / decimal e pronto:

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

Devoluções:

7000.45

Por uma questão de integridade, devo mencionar que também tentei:

  • SET LANGUAGE Greek;

  • Observando vários estilos de formato para CONVERT , mas nada se aplica aqui.

  • A função FORMAT , mas o tipo de entrada deve ser um valor numérico ou de data / hora / data / hora (que foi introduzido no SQL Server 2012, portanto, não aplicável ao SQL Server 2008 R2 ou anterior).

E nada mais parecia funcionar. Eu esperava encontrar algo mais elegante do que duas REPLACEligações, mas até agora não tive essa sorte.


Além disso, apenas para mencionar, embora não seja uma solução T-SQL pura, isso também pode ser realizado via SQLCLR. E há uma função pré-executada que faz isso na biblioteca SQL # (que eu escrevi) chamada String_TryParseToDecimal . Esta função está disponível na versão Free e funciona em todas as versões do SQL Server, começando com o SQL Server 2005:

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

Devoluções:

7000.45000000000000000000

10

Qual versão do SQL Server você está usando? A partir do SQL Server 2012, você pode usar TRY_PARSE com seu USING cultureargumento. Você também pode usar PARSE , a diferença PARSEserá que falhará se a conversão falhar e TRY_PARSEretornará um NULL, por exemplo

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

Resultado dos testes

HTH


11
Acabei de adicionar uma observação à parte superior da minha resposta, direcionando os leitores para cá se estiverem usando o SQL Server 2012 ou mais recente.
Solomon Rutzky

0

O código a seguir funcionou no meu caso:

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

saída: 123.456.789,03


ou selecione converter (varchar, FORMAT (conversão (seuValor como numérico (10,2)), '###, ###, ###. 00', 'de-de'))
Shahed Adnan

2
parece que você está respondendo ao problema inverso do que o OP pediu. eles não desejam formatar valores numéricos, desejam converter valores varchar formatados em numéricos.
ypercubeᵀᴹ

11
Além disso, duas notas: 1) sempre especificar um comprimento de VARCHAR, NVARCHAR, CHARe NCHARtipos. O padrão é 30 em alguns casos e 1 em outros casos, o que cria um código não sustentável / propenso a erros. 2) você não precisa do layout exato ao usar #. Você só precisa de um deles (por exemplo #) para todos os dígitos, mas sem separador de milhares, ou dois deles separados por vírgula (por exemplo #,#) para obter todos os dígitos e o separador de milhares. Portanto, SELECT CONVERT(VARCHAR(20), FORMAT(123456789.0258, N'#,#.00', N'de'));retorna a mesma saída que você está sugerindo.
Solomon Rutzky
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.