2012-09-20 51 views
14

Duplicar posible:
Any way to SQLBulkCopy “insert or update if exists”?C# Inserción masiva SqlBulkCopy - Actualizar si existe

estoy usando SQLBulkCopy para insertar registros a granel

¿Cómo puedo realizar en la actualización (en lugar de un inserto) en registros que ya existen? ¿Es esto posible con SQLBulkCopy?

Este es mi código para 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); 
} 

Detalles de Aplicación

  1. ASP.net MVC 3.0 Razor ver motor
  2. SQL Server 2008
+3

SqlBulkCopy no es compatible con esta operación. Copie en una tabla temporal con SqlBulkCopy y use MERGE. Las búsquedas revelarán soluciones. –

+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 (mi respuesta, sin detalles, sin embargo), http://stackoverflow.com/questions/4889123/any-way-to-sqlbulkcopy-insert-or-update-if -existe –

+0

Busque aquí para "actualización sqlbulkcopy". Hay una gran cantidad de no, no puedes hacer eso, pero podrías hacer estas respuestas. Uno de ellos podría ayudar. –

Respuesta

18

Gracias a @pst

con sus sugerencias esta es la forma en que implementé, si alguien tiene que implementar similares.

inserción masiva en al tabla temporal 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); 
      } 

A continuación, llamar a un procedimiento almacenado para combinar la tabla temporal con la tabla real

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

Esto es cómo solía Combinar en mi procedimiento almacenado

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 
Cuestiones relacionadas