Преобразовать строковые числовые значения с запятой в качестве десятичного разделителя в NUMERIC (10, 2)


12

У меня есть таблица SQL столбцов varchar, которые содержат греческие отформатированные числа (. Как разделитель тысяч и запятую как разделитель десятичных)

Классическая конверсия

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

не работает, потому что. (разделитель тысяч) убивает конверсию

Например, попробуйте

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

Я хочу преобразовать такие значения в числовые (10,2)

Любые предложения о том, как справиться с этим?

Ответы:


10

( Если вы используете SQL Server 2012 или новее, см. Ответ @ wBob для более чистого подхода. Подход, изложенный в моем ответе ниже, требуется только в том случае, если вы используете SQL Server 2008 R2 или более раннюю версию . )

Вам не нужен (или не нужен) разделитель тысяч при преобразовании NUMERIC, независимо от того, запятая ли это, точка или пробел, поэтому сначала просто избавьтесь от них. Затем преобразуйте запятую в точку / десятичную точку, и все готово:

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

Возвращает:

7000.45

Для полноты картины должен упомянуть, что я также попробовал:

  • SET LANGUAGE Greek;

  • Рассматривая различные стили форматирования для CONVERT , но здесь ничего не применимо.

  • Функция FORMAT , но тип ввода должен быть числовым или значением даты / времени / даты / времени (оно и было введено в SQL Server 2012, поэтому не применимо к SQL Server 2008 R2 или более ранней версии).

И ничто иное, казалось, не сработало. Я надеялся найти что-то более элегантное, чем два REPLACEзвонка, но пока не повезло.


Кроме того, просто чтобы упомянуть, хотя это и не чисто решение T-SQL, это также может быть достигнуто с помощью SQLCLR. И есть готовая функция, которая делает это в библиотеке SQL # (которую я написал) с именем String_TryParseToDecimal . Эта функция доступна в бесплатной версии и работает в каждой версии SQL Server, начиная с SQL Server 2005:

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

Возвращает:

7000.45000000000000000000

10

Какую версию SQL Server вы используете? Начиная с SQL Server 2012, вы можете использовать TRY_PARSE с его USING cultureаргументом. Вы также можете использовать PARSE , разница PARSEбудет невозможна, если преобразование завершится неудачно и TRY_PARSEвернет NULL, например,

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

результаты теста

НТН


1
Я только что добавил примечание в начало моего ответа, направляя читателей сюда, если они используют SQL Server 2012 или новее.
Соломон Руцки

0

Следующий код работал в моем случае:

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

выход: 123.456.789,03


или выберите команду convert (varchar, FORMAT (cast (yourValue как число (10,2)), '###, ###, ###. 00', 'de-de'))
Shahed Adnan

2
кажется, вы отвечаете на обратную проблему, заданную ОП. они не хотят форматировать числовые значения, они хотят преобразовать форматированные значения varchar в числовые.
ypercubeᵀᴹ

1
Кроме того , два замечания: 1) всегда указывать длину VARCHAR, NVARCHAR, CHARи NCHARтипов. В некоторых случаях значение по умолчанию равно 30, а в других - 1, что означает наличие не поддерживаемого кода, подверженного ошибкам. 2) вам не нужно точное расположение при использовании #. Вам просто нужен один из них (например #) для всех цифр, но без разделителя тысяч, или два из них, разделенных запятой (например #,#), чтобы получить все цифры и разделитель тысяч. Следовательно, SELECT CONVERT(VARCHAR(20), FORMAT(123456789.0258, N'#,#.00', N'de'));возвращает тот же результат, что вы предлагаете.
Соломон Руцкий
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.