2012-09-20 51 views
14

可能重複:
Any way to SQLBulkCopy 「insert or update if exists」?C#批量插入使用SqlBulkCopy - 更新是否存在

我使用SQLBulkCopy插入大容量記錄

我怎樣才能在更新完成(而不是一個插入)在已經存在的記錄上?這可能與SQLBulkCopy

這是我SqlBulkCopy的代碼

using (var bulkCopy = new SqlBulkCopy(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString, SqlBulkCopyOptions.KeepNulls & SqlBulkCopyOptions.KeepIdentity)) 
{ 
    bulkCopy.BatchSize = CustomerList.Count; 
    bulkCopy.DestinationTableName = "dbo.tCustomers"; 
    bulkCopy.ColumnMappings.Clear(); 
    bulkCopy.ColumnMappings.Add("CustomerID", "CustomerID"); 
    bulkCopy.ColumnMappings.Add("FirstName", "FirstName"); 
    bulkCopy.ColumnMappings.Add("LastName", "LastName"); 
    bulkCopy.ColumnMappings.Add("Address1", "Address1"); 
    bulkCopy.ColumnMappings.Add("Address2", "Address2"); 
    bulkCopy.WriteToServer(CustomerList); 
} 

應用程序詳細信息

  1. ASP.net MVC 3.0 Razor視圖引擎
  2. SQL Server 2008中
+3

SqlBulkCopy不支持此操作。使用SqlBulkCopy複製到臨時表並使用MERGE。搜索將揭示解決方案。 – 2012-09-20 22:17:02

+0

http://stackoverflow.com/questions/1700487/using-sqlbulkcopy-to-insert-update-database?rq=1,http://stackoverflow.com/questions/12292644/speed-up-update-of-185k -rows-in-sql-server-2008/12379039#12379039(我的回答,雖然沒有詳細資料),http://stackoverflow.com/questions/4889123/any-way-to-sqlbulkcopy-insert-or-update-if - 存在 – 2012-09-20 22:18:46

+0

搜索「sqlbulkcopy更新」。有一大堆你不能這樣做,但你可以做這個答案。其中之一可能會有所幫助。 –

回答

18

感謝@pst

與他的建議,這是我如何實施,如果任何人必須實施類似。

批量插入到永久臨時表

using (var bulkCopy = new SqlBulkCopy(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString, SqlBulkCopyOptions.KeepNulls & SqlBulkCopyOptions.KeepIdentity)) 
      { 
       bulkCopy.BatchSize = CustomerList.Count; 
       bulkCopy.DestinationTableName = "dbo.tPermanentTempTable"; 
       bulkCopy.ColumnMappings.Clear(); 
       bulkCopy.ColumnMappings.Add("CustomerID", "CustomerID"); 
       bulkCopy.ColumnMappings.Add("FirstName", "FirstName"); 
       bulkCopy.ColumnMappings.Add("LastName", "LastName"); 
       bulkCopy.ColumnMappings.Add("Address1", "Address1"); 
       bulkCopy.ColumnMappings.Add("Address2", "Address2"); 
       bulkCopy.WriteToServer(CustomerList); 
      } 

然後調用存儲過程來合併臨時表與實際的表

using (Entities context = new Entities()) 
      { 
       System.Nullable<int> iReturnValue = context.usp_Customer_BulkUploadMerge(customerid, locationID).SingleOrDefault(); 
       if (iReturnValue.HasValue) 
       { 
        // return was successful! 
       } 
      } 

這是我在我的存儲過程

使用合併
ALTER PROCEDURE usp_Customer_BulkUploadMerge 
    (
     @CustomerID INT , 
     @locationID INT 
    ) 
AS 
    BEGIN 
    DECLARE @retValue INT 
     BEGIN TRY 
      IF OBJECT_ID('tCustomers') IS NOT NULL 
       BEGIN 
        BEGIN TRANSACTION MergPatientsTable 
        SET NOCOUNT ON; 
        MERGE dbo.tCustomers AS target 
         USING 
          (SELECT PU.CustomerID , 
             PU.LocationID , 
             PU.FirstName , 
             PU.LastName , 
             PU.MiddleInitial , 
             PU.Gender , 
             PU.DOB 

           FROM  dbo.tPermanentTempTable PU 
           WHERE  PU.CustomerID = @CustomerID 
             AND PU.LocationID = @locationID 
           GROUP BY PU.CustomerID , 
             PU.LocationID , 
             PU.FirstName , 
             PU.LastName , 
             PU.MiddleInitial , 
             PU.Gender , 
             PU.DOB 

          ) AS source (CustomerID, LocationID, FirstName, 
              LastName, MiddleInitial, Gender, DOB) 
         ON (LOWER(target.FirstName) = LOWER(source.FirstName) 
          AND LOWER(target.LastName) = LOWER(source.LastName) 
          AND target.DOB = source.DOB 
          ) 
         WHEN MATCHED 
          THEN 
     UPDATE    SET 
       MiddleInitial = source.MiddleInitial , 
       Gender = source.Gender,    
       LastActive = GETDATE() 
         WHEN NOT MATCHED 
          THEN  
     INSERT (
        CustomerID , 
        LocationID , 
        FirstName , 
        LastName , 
        MiddleInitial , 
        Gender , 
        DOB , 
        DateEntered , 
        LastActive 
       )    VALUES 
       (source.CustomerID , 
        source.LocationID , 
        source.FirstName , 
        source.LastName , 
        source.MiddleInitial , 
        source.Gender , 
        source.DOB , 
        GETDATE() , 
        NULL 
       ); 
        DELETE PU 
        FROM dbo.tPermanentTempTable PU 
        WHERE PU.CustomerID = @CustomerID 
          AND PU.LocationID = @locationID 
        COMMIT TRANSACTION MergPatientsTable 
        SET @retValue = 1 
        SELECT @retValue 
       END 
      ELSE 
       BEGIN 
       SET @retValue = -1 
        SELECT @retValue 
       END 
     END TRY 
     BEGIN CATCH 
      ROLLBACK TRANSACTION MergPatientsTable 
      DECLARE @ErrorMsg VARCHAR(MAX); 
      DECLARE @ErrorSeverity INT; 
      DECLARE @ErrorState INT; 
      SET @ErrorMsg = ERROR_MESSAGE(); 
      SET @ErrorSeverity = ERROR_SEVERITY(); 
      SET @ErrorState = ERROR_STATE(); 
     SET @retValue = 0 
     SELECT @retValue 
      -- SELECT 0 AS isSuccess 
     END CATCH 
    END