2009-06-12 29 views
9

Tôi đã thực hiện một số nghiên cứu cho "Cách bast để chèn dữ liệu lớn vào DB với C#" sau đó rất nhiều người chỉ đề nghị tôi sử dụng SqlBulkCopy. Sau khi tôi thử nó và nó thực sự làm tôi ngạc nhiên. Chắc chắn, SqlBulkCopy là rất rất nhanh. Có vẻ như SqlBulkCopy là một cách hoàn hảo để chèn dữ liệu (đặc biệt là dữ liệu khổng lồ). Nhưng tại sao chúng ta không sử dụng nó vào mọi lúc. Có bất kỳ hạn chế của việc sử dụng SqlBulkCopy?Hạn chế của SqlBulkCopy

Trả lời

9

Có hai lý do tôi có thể nghĩ:

  1. Theo như tôi biết, nó chỉ có sẵn cho Microsoft SQL Server
  2. Trong rất nhiều khối lượng công việc bình thường, bạn không làm số lượng lớn insert s, nhưng thỉnh thoảng insert được trộn lẫn với select s và update s. Microsoft tự tuyên bố rằng một thông thường insert hiệu quả hơn cho điều đó, trên SqlBulkCopy MSDN page.

Lưu ý rằng nếu bạn muốn SqlBulkCopy tương đương với chèn thông thường, ít nhất bạn sẽ phải chuyển thông số SqlBulkCopyOptions.CheckConstraints.

+0

Vâng, SqlBulkCopy chỉ có thể được sử dụng với MS SQL Server. Đây cũng chỉ là một trong những hạn chế mà tôi biết. Đôi khi nó không phải là thực sự lớn đối phó. Ví dụ: Khách hàng của chúng tôi chỉ sử dụng MS SQL Server và chúng tôi chỉ xây dựng các ứng dụng cho họ với một số lớp thuộc về không gian tên System.Data.SqlClient. –

+0

Tại sao 'SqlBulkCopyOptions.CheckConstraints' sai theo mặc định? - nó rất trực quan! –

+3

@BarryKaye: Không, không phải. Tên là 'Bulk Copy', vì vậy bạn nên sao chép dữ liệu mà các ràng buộc đã được biết là chính xác, nếu không thì bạn không biết bạn đang làm gì ... :) –

13

SqlBulkCopy cũng tồn tại đối với Oracle v11, nhưng nó được cung cấp bởi các hội đồng Oracle .NET bạn nhận được khi cài đặt Oracle Client. Lớp SqlBulkCopy về cơ bản được triển khai từng cái một, bởi nhà cung cấp của cơ sở dữ liệu đích.

Một hạn chế HUGE, mặc dù - hoàn toàn không có báo cáo lỗi. Nếu, ví dụ, bạn đã cập nhật dữ liệu trong một DataSet, đang xả nó trở lại DB với adapter, và có một sự vi phạm chính (hoặc bất kỳ lỗi nào khác), DataRows thủ phạm sẽ có .HasErrors thiết lập là true, và bạn có thể thêm nó vào thông báo ngoại lệ của bạn khi nó được nâng lên.

Với SqlBulkCopy, bạn chỉ nhận được loại lỗi và đó là nó. Chúc may mắn gỡ lỗi nó.

+2

+1 Hoàn toàn đồng ý rằng gỡ lỗi là một vấn đề với BulkCopy. Một cách tiếp cận tôi có là "giải mã" các lệnh BulkCopy không thành công và chèn hàng theo hàng trong một khối cuối cùng. Bằng cách đó tôi có thể xác định DataRow vi phạm như một phần của báo cáo Lỗi của tôi. – Totero

+1

Tôi đã tìm ra rằng để báo cáo lỗi có một cách để lấy lại các lỗi riêng lẻ, nhưng nó liên quan đến việc gửi lại bản sao hàng loạt trong các trang của một bản ghi và sau đó bắt và ném tất cả các ngoại lệ (cùng với các hàng thủ phạm). Nó không phải là hiệu quả nhất, nhưng nó chỉ xảy ra khi một lỗi xảy ra, do đó, nó không phải là quá xấu. Xem ở đây để xem toàn bộ bài viết: http://www.codeproject.com/Articles/387465/Retrieving-failed-records-after-an-SqlBulkCopy-exc –