2013-04-30 32 views
6

Tôi đang cố gắng đổ một tập dữ liệu rất lớn từ tệp .csv vào cơ sở dữ liệu SQL Server 2012. Thay vì làm hàng ngàn INSERT, tôi đang điều tra bcp.BCP không trả về lỗi nào, nhưng cũng không sao chép bất kỳ hàng nào

CHỈNH SỬA: Đây là quy trình tự động và không chỉ là một lần duy nhất. Tôi cũng không có quyền BULK INSERT đối với cơ sở dữ liệu này.

Khi tôi cố gắng sao chép dữ liệu vào cơ sở dữ liệu, bcp không trả về bất kỳ lỗi nào, nhưng cũng không thực sự sao chép bất kỳ lỗi nào - nó chỉ trả lại 0 rows copied. Tôi đã cắt giảm điều này xuống một trường hợp tối thiểu không hoạt động.

Đầu tiên, tạo một bảng đơn giản với hai cột:

CREATE TABLE [dbo].[mincase](
    [key] [varchar](36) NOT NULL, 
    [number] [int] NOT NULL 

    PRIMARY KEY CLUSTERED 
    (
     [key] ASC 
    ) 
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 40) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

Sau đó, sử bcp để tạo ra một tập tin định dạng từ này. Lưu ý rằng ví dụ này tạo ra một tệp định dạng XML, nhưng nó không quan trọng cho dù đó là XML hay bản địa cho việc này.

bcp MyDB.dbo.mincase format nul -T -n -f mincasexml.fmt -x -S .\SQLEXPRESS 

Bây giờ, tạo tệp data.csv với một hàng và hai mục, được phân cách bằng tab. Trong trường hợp của tôi, các tập tin chỉ đơn giản là:

somecharacters 12345 

Một lần nữa, đó là một tab, không phải là hai không gian, và nó dường như không quan trọng cho dù có trailing dòng mới hay không.

Bây giờ cố gắng sử dụng bcp với tập tin định dạng để chèn dữ liệu từ tập tin này:

bcp MyDB.dbo.mincase in data.csv -f mincasexml.fmt -T -S .\SQLEXPRESS 

Thay vì sao chép dữ liệu vào cơ sở dữ liệu, tôi có được điều này:

Starting copy... 

0 rows copied. 
Network packet size (bytes): 4096 
Clock Time (ms.) Total  : 1 

Có ai biết những gì đang xảy ra ở đây?

Cảm ơn!

+0

bạn đã thử tùy chọn DỮ LIỆU NHẬP KHẨU chưa? –

Trả lời

8

Lệnh bcp thường cần một số nhận dạng để chỉ định chế độ định dạng của tệp bcp.

  • -c xác định nhân vật (plaintext) chế độ
  • -n định chế độ bản địa
  • -w quy định cụ thể chế độ unicode

Trong trường hợp thử nghiệm của bạn, các tập tin mà bạn đã tạo được bản rõ, vì vậy bạn nên chỉ định '-c' trong lệnh bcp của bạn.

bcp MyDB.dbo.mincase in data.csv -c -T -S .\SQLEXPRESS 

Microsoft Recommends bằng cách sử dụng '-n' cho hàng nhập khẩu và xuất khẩu để tránh vấn đề với delimiters lĩnh vực xuất hiện trong các giá trị cột (Xem phần trên Chế độ nhân vật và Native Mode Best Practices).

+1

Đó là nó, với một chỉnh sửa nhỏ: -f ghi đè -c, do đó, loại bỏ các tập tin định dạng hoàn toàn rất gọn gàng giải quyết vấn đề. Kết quả cuối cùng là: 'bcp MyDB.dbo.mincase trong dữ liệu.csv -c -T -S. \ SQLEXPRESS' – Mark

+1

Tuyệt vời..đáp ứng câu trả lời của tôi. –

1

Tôi đã gặp sự cố tương tự, ngoại trừ việc tôi đã sử dụng tệp định dạng, vì vậy việc thêm một trong các cờ định dạng sẽ không hữu ích. Đối với bất kỳ ai khác kết thúc ở đây, tôi muốn giải thích nguyên nhân gây ra vấn đề này cho tôi (và hy vọng giúp giải thích nguyên nhân gây ra vấn đề cơ bản là gì).

Vấn đề là BCP không thực sự xử lý các dòng văn bản trong một tệp; thay vào đó, nó chỉ xử lý một luồng dữ liệu, theo các hướng dẫn bạn đưa ra. Điều này có nghĩa là các dòng mới sẽ bị bỏ qua, nếu đó là những gì bạn (vô tình) yêu cầu BCP thực hiện.

Trong trường hợp của tôi, điều này hóa ra lại là một lỗi đánh máy trong dòng cuối cùng trong file định dạng:

13.0 
1348 
1 SQLCHAR 0 21 "," 1 RecordKey "" 
2 SQLCHAR 0 30 "," 0 SubmissionKey "" 
3 SQLCHAR 0 1 "," 2 A1cLvl "" 
... 
1347 SQLCHAR 0 1 "," 0 WoundIntVac "" 
1348 SQLCHAR 0 1 "/r/n" 0 XClampTm "" 

Nếu bạn nhìn kỹ, bạn sẽ thấy các dấu gạch chéo là ngược trong lĩnh vực terminator trên dòng cuối cùng. Vì vậy, thay vì tìm kiếm các kết thúc dòng kiểu Windows, BCP thực sự đang tìm kiếm chuỗi văn bản "/ r/n" trong luồng dữ liệu.

Vì chuỗi không thực sự xuất hiện trong dữ liệu của tôi, BCP chưa bao giờ thực sự tìm thấy bất kỳ điều gì khớp với trường cuối cùng của tôi. Vì vậy, nó có ý nghĩa rằng nó tìm thấy "0 hàng" để sao chép.

Tôi vẫn không chắc tại sao điều này không gây ra lỗi như "Lỗi không mong muốn EOF gặp phải" hoặc điều gì đó, nhưng hy vọng ai đó sẽ có thể mở rộng trên điều này.

Các vấn đề liên quan