c# - net - ¿Alguna forma de SQLBulkCopy "insertar o actualizar si existe"?
max pool size web config (5)
Necesito actualizar una tabla muy grande periódicamente y SQLBulkCopy es perfecto para eso, solo que tengo un índice de 2 columnas que evita duplicados. ¿Hay alguna forma de usar SQLBulkCopy como "insertar o actualizar si existe"?
Si no, ¿cuál es la forma más eficiente de hacerlo? Una vez más, estoy hablando de una tabla con millones de registros.
Gracias
Cargaría de forma masiva los datos en una tabla de preparación temporal, luego haría un aumento en la tabla final. Consulte http://www.databasejournal.com/features/mssql/article.php/3739131/UPSERT-Functionality-in-SQL-Server-2008.htm para ver un ejemplo de cómo hacer una subida.
En lugar de crear una nueva tabla temporal, que por cierto consume más espacio y memoria.
Creé un disparador con INSTEAD OF INSERT y lo uso dentro de la sentencia MERGE.
Pero no olvide agregar el parámetro SqlBulkCopyOptions.Fire Triggers en SqlBulkCopy.
Estos son mis dos centavos.
No en un solo paso, pero en SQL Server 2008 , podría:
- carga masiva en la mesa de preparación
- aplique una declaración
MERGE
para actualizar / insertar en su tabla real
Lea más acerca de la declaración MERGE
Otra alternativa sería no usar una tabla temporal, sino usar un procedimiento almacenado con un parámetro de valor de tabla. Pase un datatable al sp y haga la fusión allí.
Publiqué un paquete nuget (SqlBulkTools) para resolver este problema.
Aquí hay un ejemplo de código que lograría un aumento de volumen.
var bulk = new BulkOperations();
var books = GetBooks();
using (TransactionScope trans = new TransactionScope())
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager
.ConnectionStrings["SqlBulkToolsTest"].ConnectionString))
{
bulk.Setup<Book>()
.ForCollection(books)
.WithTable("Books")
.AddAllColumns()
.BulkInsertOrUpdate()
.MatchTargetOn(x => x.ISBN)
.Commit(conn);
}
trans.Complete();
}
Para tablas muy grandes, hay opciones para agregar bloqueos de tabla y desactivar temporalmente los índices no agrupados. Vea la documentación de SqlBulkTools para más ejemplos.