2009-02-20 26 views
10

Giả sử dữ liệu sau:SQL IsNumeric trả về true nhưng báo cáo SQL 'chuyển đổi Không'

Column1 (data type: varchar(50)) 
-------- 
11.6 
-1 
1,000 
10"  
Non-Numeric String 

Tôi có một truy vấn, mà là kéo dữ liệu từ cột này và muốn để xác định xem giá trị là một số, sau đó trả lại như vậy trong truy vấn của tôi. Vì vậy, tôi làm như sau

SELECT CASE WHEN IsNumeric(Replace(Column1,'"','')) = 1 Then Replace(Column1,'"','') Else 0 End As NumericValue 

SQL được báo cáo lại: chuyển đổi thất bại khi chuyển đổi các giá trị 0,6' varchar '11 để kiểu dữ liệu int.

Tại sao? Tôi cũng đã cố gắng ép buộc điều này:

SELECT CASE WHEN IsNumeric(Replace(Column1,'"','')) = 1 Then cast(Replace(Column1,'"','') as float) Else 0 End As NumericValue 

Và tôi nhận được: Lỗi chuyển đổi loại dữ liệu varchar thành nổi.

+0

'IsNumeric()' sẽ chấp nhận đôi/phao/đĩa đơn vv. Ngoài ra, nó không kiểm tra tràn ('99999999999999999999999999999' là số, sẽ không chuyển đổi thành hầu hết các loại số). Phương pháp hay nhất cho loại tình huống là bạn _không lưu trữ dữ liệu số trong các trường chuỗi trong địa điểm đầu tiên_. –

Trả lời

11

Bạn cần phải thay dấu phẩy với thời gian:

CAST(REPLACE(column, ',', '.') AS FLOAT) 

SQL Server đầu ra thập phân tách được xác định với tên địa phương, nhưng không phải làm bất cứ điều gì unterstand nhưng một thời gian trong CAST s đến các loại số.

+0

Tính năng này hoạt động. Tôi nghĩ rằng tôi đang tìm kiếm một cái gì đó quá phức tạp để trang trải kịch bản này. Cảm ơn. –

+0

để '1.000' trở thành 1? – dotjoe

+1

Không, tôi đã xóa hoàn toàn dấu phẩy. –

1

Trả về ISNUMERIC 1 khi biểu thức nhập đánh giá đến một số nguyên hợp lệ, số dấu phẩy động, số tiền hoặc số thập phân;

Vì vậy, vấn đề là nó là một số hợp lệ nhưng không phải là một int hợp lệ.

+0

Tôi thấy điều đó, nhưng khi cố gắng truyền giá trị dưới dạng float tôi nhận được cùng một vấn đề. –

+0

có thể là dấu phẩy trong 1.000 – dotjoe

1

Kyle,

Tôi nghĩ điều này giải quyết được vấn đề. Vấn đề nằm ở thực tế là mệnh đề ELSE khởi tạo kết quả của bạn thành một INTEGER. Bằng cách làm cho một typecast rõ ràng để FLOAT và thêm gợi ý của Quassnoi, có vẻ như nó hoạt động.

DECLARE @MyTable TABLE (Column1 VARCHAR(50)) 
INSERT INTO @MyTable VALUES('11.6') 
INSERT INTO @MyTable VALUES('-1') 
INSERT INTO @MyTable VALUES('1,000') 
INSERT INTO @MyTable VALUES('10" ') 
INSERT INTO @MyTable VALUES('Non-Numeric String') 

SELECT CASE WHEN ISNUMERIC(REPLACE(Column1,'"','')) = 1 THEN REPLACE(REPLACE(Column1,'"',''), ',', '.') ELSE CAST(0 AS FLOAT) END 
FROM @MyTable 

Kính trọng,
Lieven

3

Có nhiều vấn đề với SQL không phải là số. Ví dụ:

select isnumeric('1e5') 

Điều này sẽ trả về 1 nhưng bằng nhiều ngôn ngữ nếu bạn cố chuyển đổi thành số sẽ thất bại. Một cách tiếp cận tốt hơn là tạo ra sử dụng chức năng định nghĩa của riêng bạn với các thông số bạn cần phải kiểm tra cho:

http://www.tek-tips.com/faqs.cfm?fid=6423

+0

Vẫn tốt hơn: không lưu trữ các trường số trong cột chuỗi ở vị trí đầu tiên. –

1

IsNumeric(' ') cũng trả về 1, nhưng sau đó CAST như int thổi lên. Brendan nói trên viết chức năng của riêng bạn. Anh ấy đúng.

+1

Trên máy SQL 2008 của tôi, 'IsNumeric ('')' trả về '0'. – sparebytes

5

Đầu tiên chuyển đổi chuỗi thành tiền, sau đó chuyển đổi chuỗi thành bất kỳ định dạng số nào khác vì loại tiền cung cấp chuỗi số thực đúng. Bạn sẽ không bao giờ thấy lỗi sau đó.

Hãy thử những điều sau trong truy vấn của bạn và bạn sẽ biết tôi đang nói về điều gì. Cả hai sẽ trả về 2345.5656. Loại dữ liệu tiền được làm tròn thành 4 chữ số thập phân, và do đó quá trình truyền sẽ làm tròn đến 4 chữ số thập phân.

SELECT CAST('2,345.56556' as money), CAST('$2,345.56556' as money) 

Cast (cast ('2344' như tiền) như float) sẽ làm việc một cách hoàn hảo hoặc cast (cast ('2344' như tiền) như thập phân (7,2)) cũng sẽ làm việc.

Thậm chí truyền (CAST ('$ 2,345.56556' làm tiền) dưới dạng int) sẽ làm việc hoàn toàn làm tròn nó thành số nguyên gần nhất.

+0

Đây là một gợi ý tuyệt vời. – leem

0

Giải pháp này không hoạt động trong mọi trường hợp (cụ thể là số có tiền và/hoặc nghìn dấu tách). Kết hợp một đại diện số mũ vào cuối số được biểu diễn bằng một chuỗi ... ISNUMERIC() hoạt động tốt từ đó. Ví dụ bên dưới:

-- CURRENT ISNUMERIC RESULTS 
SELECT ISNUMERIC('11.6'); --1 
SELECT ISNUMERIC ('-1'); --1 
SELECT ISNUMERIC('1,000'); --1 
SELECT ISNUMERIC('10"'); --0 
SELECT ISNUMERIC('$10'); --1 

-- NEW ISNUMERIC RESULTS 
SELECT ISNUMERIC('11.6'+'e+00'); --1 
SELECT ISNUMERIC ('-1'+'e+00'); --1 
SELECT ISNUMERIC('1,000'+'e+00'); --0 
SELECT ISNUMERIC('10"'+'e+00'); --0 
SELECT ISNUMERIC('$10'+'e+00'); --0 

Điều này, ít nhất, chuẩn hóa định dạng để sử dụng hàm REPLACE().

0

Tôi vừa gặp sự cố này.

Bạn có thể thử giải pháp này nếu bạn không ngại về giới hạn độ dài thập phân.

CONVERT(numeric, CONVERT(money, '.')) 

LƯU Ý:

  1. Đó là hỗ trợ trong SQL Server 2008 hoặc cao hơn.
  2. Tiền phạm vi là: -922,337,203,685,477.5808 đến 922,337,203,685,477.5807 - bốn số thập phân.
Các vấn đề liên quan