Chuyển đổi các giá trị số chuỗi bằng dấu phẩy dưới dạng dấu tách thập phân thành NUMERIC (10, 2)


12

Tôi có một bảng SQL gồm các cột varchar chứa các số được định dạng bằng tiếng Hy Lạp (. Nghìn phân cách và dấu phẩy là dấu phân cách thập phân)

Chuyển đổi cổ điển

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

không hoạt động vì. (nghìn phân cách) giết chết chuyển đổi

Ví dụ thử

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

Tôi muốn chuyển đổi các giá trị đó thành số (10,2)

Bất kỳ đề xuất làm thế nào để xử lý nó?

Câu trả lời:


10

( Nếu bạn đang sử dụng SQL Server 2012 hoặc mới hơn, vui lòng xem câu trả lời của @ wBob để biết cách tiếp cận sạch hơn. Cách tiếp cận được nêu trong câu trả lời của tôi dưới đây chỉ được yêu cầu nếu bạn đang sử dụng SQL Server 2008 R2 trở lên. )

Bạn không cần (hoặc muốn) dấu phân cách hàng nghìn khi chuyển đổi sang NUMERIC, bất kể đó là dấu phẩy, dấu chấm hoặc dấu cách, vì vậy hãy loại bỏ chúng trước. Sau đó chuyển đổi dấu phẩy thành dấu chấm / thập phân và bạn đã hoàn thành:

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

Trả về:

7000.45

Để hoàn thiện, tôi nên đề cập rằng tôi cũng đã thử:

  • SET LANGUAGE Greek;

  • Nhìn vào các phong cách định dạng khác nhau cho CHUYỂN ĐỔI , nhưng không có gì áp dụng ở đây.

  • Hàm FORMAT , nhưng loại đầu vào phải là giá trị số hoặc ngày / thời gian / thời gian (được giới thiệu trong SQL Server 2012, do đó không áp dụng cho SQL Server 2008 R2 trở lên).

Và không có gì khác dường như làm việc. Tôi đã hy vọng tìm thấy một cái gì đó thanh lịch hơn hai REPLACEcuộc gọi, nhưng cho đến nay không có may mắn như vậy.


Ngoài ra, chỉ cần đề cập, trong khi không phải là một giải pháp T-SQL thuần túy, điều này cũng có thể được thực hiện thông qua SQLCLR. Và, có một hàm được thực hiện trước đó thực hiện điều này trong thư viện SQL # (mà tôi đã viết) có tên String_TryPudeToDecimal . Chức năng này có sẵn trong phiên bản Miễn phí và hoạt động trong mọi phiên bản SQL Server bắt đầu với SQL Server 2005:

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

Trả về:

7000.45000000000000000000

10

Phiên bản SQL Server nào bạn đang sử dụng? Từ SQL Server 2012 trở đi, bạn có thể sử dụng TRY_PARSE với USING cultuređối số của nó . Bạn cũng có thể sử dụng phân tích , sự khác biệt con người PARSEsẽ thất bại nếu việc chuyển đổi thất bại và TRY_PARSEsẽ trở lại một NULL, ví dụ:

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

kết quả kiểm tra

HTH


1
Tôi vừa thêm một ghi chú vào đầu câu trả lời của mình, hướng người đọc đến đây nếu họ đang sử dụng SQL Server 2012 hoặc mới hơn.
Solomon Rutzky

0

Các mã sau đây làm việc trong trường hợp của tôi:

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

đầu ra: 123.456.789,03


hoặc chọn convert (varchar, FORMAT (cast (yourValue dưới dạng số (10,2)), '###, ###, ###. 00', 'de-de'))
Shahed Adnan

2
có vẻ như bạn đang trả lời vấn đề ngược lại về những gì OP yêu cầu. họ không muốn định dạng các giá trị số, họ muốn chuyển đổi các giá trị varchar được định dạng thành số.
ypercubeᵀᴹ

1
Ngoài ra, hai ghi chú: 1) luôn luôn chỉ định một chiều dài cho VARCHAR, NVARCHAR, CHAR, và NCHARcác loại. Mặc định là 30 trong một số trường hợp và 1 trong các trường hợp khác, điều này làm cho mã không thể nhận biết / dễ bị lỗi. 2) bạn không cần bố trí chính xác khi sử dụng #. Bạn chỉ cần một trong số chúng (ví dụ #) cho tất cả các chữ số nhưng không có dấu phân cách hàng nghìn hoặc hai trong số chúng được phân tách bằng dấu phẩy (ví dụ #,#) để có được tất cả các chữ số dấu phân cách hàng nghìn. Do đó, SELECT CONVERT(VARCHAR(20), FORMAT(123456789.0258, N'#,#.00', N'de'));trả về cùng một đầu ra như những gì bạn đang đề xuất.
Solomon Rutzky
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.