2011-09-19 17 views
9

Tôi đang sử dụng openrowset để nhập tệp csv vào SQL Server. Một trong các cột trong tệp csv chứa các số trong ký hiệu khoa học (1.08E + 05) và cột trong bảng đang được chènChuyển đổi ký hiệu khoa học thành float khi sử dụng OpenRowSet để nhập tệp .CSV

Theo mặc định, nhập giá trị là 1 và bỏ qua .08E + 05.

Tôi đã thử sử dụng hàm cast() và chuyển đổi() để chuyển đổi giá trị trực tiếp khi truy vấn được thực thi cũng như thiết lập kiểu dữ liệu trong bảng dưới dạng chuỗi ký tự và nhập nó như vậy. Tất cả các phương thức này có cùng một hành vi trong đó .08E + 05 bị bỏ qua.

Có cách nào để nhập giá trị là 108000 thay vì 1 không có .08E + 05 mà không phải tự thay đổi tệp csv không?

Thiết lập datatype như một varchar và đọc trong file csv dường như có tác dụng tương tự với đoạn mã sau:

CREATE TABLE #dataTemp (StartDate datetime, Value varchar(12)) 

SET @insertDataQuery = 'SELECT Date, CSVValue from OpenRowset(''MSDASQL'', ''Driver={Microsoft Text Driver (*.txt; *.csv)}; DefaultDir=' 
SET @insertDataQuery = @insertDataQuery + 'C:\Data\;'',''SELECT * FROM '+ '11091800.csv' + ''')' 

INSERT INTO #dataTemp EXEC(@insertDataQuery) 

SELECT * FROM #dataTemp 

Không phải tất cả các giá trị trong file CSV có ký hiệu khoa học và giá trị không có nó, ví dụ 81000 đi qua mà không có vấn đề.

Trả lời

13

Đối BULK INSERT phương pháp tôi đã thường được tìm thấy nó đơn giản đầu tiên di chuyển dữ liệu vào một bảng của tất cả các varchars, sau đó thoát khỏi những thứ không liên quan như delimiters trích dẫn và sửa chữa định dạng. Tôi nhớ có một heck của một thời gian loại bỏ các ký hiệu khoa học, bạn chỉ có thể chơi với bảng varchar cho đến khi bạn nhận được nó đúng. Tôi nhớ đã cố gắng tất cả các loại kết hợp chính xác/tỷ lệ cho đến khi tôi tìm thấy một loại tương thích. Tôi nghĩ rằng đối với tôi nó là FLOAT sau đó DECIMAL(24,12) ...

SELECT CONVERT(DECIMAL(24, 12), CONVERT(FLOAT, '1.08E+05'));

EDIT thêm những gì tôi đã cố gắng để repro và/hoặc chứng minh một cách ít phức tạp.

Tôi tạo ra một tập tin CSV rất đơn giản:

StartDate,Value 
20110808,81000 
20110808,1.08E+05 

Sau đó, tôi chạy đoạn mã sau (đối với một số lý do tôi không thể có được MSDASQL để chạy trên máy tính của tôi để cứu lấy mạng sống của tôi):

CREATE TABLE #dataTemp(StartDate DATETIME, Value VARCHAR(32)); 

BULK INSERT #dataTemp FROM 'C:\data\whatever.csv' 
    WITH (ROWTERMINATOR='\n', FIELDTERMINATOR=',', FIRSTROW = 2); 

SELECT * FROM #dataTemp 
GO 
SELECT StartDate, CONVERT(INT, CONVERT(FLOAT, Value)) FROM #dataTemp; 
GO 
DROP TABLE #dataTemp; 

Kết quả:

StartDate    Value 
----------------------- -------- 
2011-08-08 00:00:00.000 81000 
2011-08-08 00:00:00.000 1.08E+05 

StartDate    (No column name) 
----------------------- ---------------- 
2011-08-08 00:00:00.000 81000 
2011-08-08 00:00:00.000 108000 
+1

Trên thực tế trong trường hợp của bạn bây giờ mà tôi đang đọc lại các câu hỏi mà bạn có thể có lẽ chỉ sử dụng 'CHỌN CONVERT (INT , CONVERT (FLOAT, '1.08E + 05 ')); '- lần cuối tôi làm việc về ký hiệu khoa học Tôi đã giao dịch với các quầy hiệu suất từ ​​LogMan, và tôi chắc chắn cần số thập phân ... –

+0

Bất kỳ giải pháp nào ở trên đều hoạt động nếu tôi cung cấp giá trị một cách rõ ràng. Trong tệp CSV, tôi có một tên cột cho giá trị và nếu tôi sử dụng tên đó, ví dụ CONVERT (INT, CONVERT (FLOAT, COLUMN_NAME_IN_CSV)), tôi vẫn nhận được hành vi mà nó chỉ đọc chữ số đầu tiên. Suy nghĩ? – amarcy

+0

Suy nghĩ của tôi vẫn còn để chèn số lượng lớn vào một bảng varchars đầu tiên. Có thể có một cái gì đó khác đang xảy ra khi chèn của bạn ... chọn từ truy vấn openrowset đang cố gắng để phù hợp với loại bảng để siêu dữ liệu từ truy vấn. Nếu bạn đang chèn vào varchar đầu tiên, nó sẽ không quan tâm ... –

4

Sẽ truyền nó như một tác phẩm thực sự?

select cast('1.08E+05' as real) 
5

Trước hết, thực tế bạn có một ký hiệu khoa học có nghĩa là khả năng Excel hoặc một số của nó chương trình khác mà tạo ra giá trị có LOST một số dữ liệu .... nói cách khác, số lượng ban đầu bên trong ký hiệu đã được chuyển đổi và do đó một số con số và độ chính xác đã bị mất. đó là một vấn đề với nhiều sản phẩm của Microsoft chuyển đổi từ Excel và CSV.

Thứ hai, đây là một chuyển đổi piefce tốt hơn có thể chuyển đổi số thành một chuỗi:

CONVERT(nvarchar(255),LTRIM(RTRIM(str(ISNULL(YOUR_NUMBER,0),20,0)))) 
+1

..... có LOST một số dữ liệu ...... đó là một vấn đề với nhiều sản phẩm của Microsoft chuyển đổi từ Excel và CSV ..... chính xác. Cộng một. Không có cài đặt Excel là một điều kiện tiên quyết cho bất kỳ loại dữ liệu nào hoạt động. Vấn đề là khiến khách hàng của bạn gỡ cài đặt Excel khá khó khăn :) – DaveBoltman