web-dev-qa-db-fra.com

C # Bulk Insert SQLBulkCopy - Mettre à jour si existant

Duplicata possible:
Est-il possible d'insérer ou de mettre à jour SQLBulkCopy "s'il existe"?

J'utilise SQLBulkCopy pour insérer des enregistrements en bloc

Comment puis-je effectuer une mise à jour (plutôt qu'une insertion) sur des enregistrements qui existent déjà? Est-ce possible avec SQLBulkCopy?

Ceci est mon code pour 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);
}

Détails de la demande

  1. ASP.net MVC 3.0 Razor View Engine
  2. SQL Server 2008
20
HaBo

Merci à @pst

avec ses suggestions, c'est ainsi que j'ai mis en œuvre, si quelqu'un doit mettre en œuvre similaire.

Insertion en vrac dans la table de températures 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);
            } 

Appelez ensuite une procédure stockée pour fusionner la table temporaire avec la table réelle

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

Voici comment j'ai utilisé la fusion dans ma procédure stockée

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
24
HaBo