2012-09-20 21 views
14

Eventuali duplicati:
Any way to SQLBulkCopy “insert or update if exists”?C# Inserimento di massa SqlBulkCopy - Update se esiste

Sto usando SQLBulkCopy per inserire i record di massa

Come posso eseguire sul aggiornamento (piuttosto che un inserto) sui record che esistono già? Questo è possibile con SQLBulkCopy?

Questo è il mio codice per 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); 
} 

Dettagli applicazione

  1. ASP.net MVC 3.0 Razor visualizzare motore
  2. SQL Server 2008
+3

SqlBulkCopy non supporta questa operazione. Copia su una tabella temporanea con SqlBulkCopy e usa MERGE. Le ricerche rivelano le soluzioni. –

+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 (la mia risposta, nessun dettaglio però), http://stackoverflow.com/questions/4889123/any-way-to-sqlbulkcopy-insert-or-update-if -exists –

+0

Cerca qui per "sqlbulkcopy update". C'è tutta una zattera di no, non puoi farlo, ma potresti fare queste risposte. Uno di loro potrebbe aiutare. –

risposta

18

Grazie a @pst

con i suoi suggerimenti questo è il modo in cui ho implementato, se qualcuno deve implementare simili.

Bulk inserire nella tabella Temp permanente

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); 
      } 

quindi chiamare una stored procedure per unire il tabella temporanea con la tabella effettiva

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

Questo è il modo che ho usato di unione nel mio stored procedure

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 
Problemi correlati