SqlBulkCopy Error de manejo / continuar en error

ado.net c# sqlbulkcopy

Pregunta

Estoy tratando de insertar gran cantidad de datos en el servidor SQL. Mi tabla de destino tiene un índice único llamado "Hash".

Me gustaría reemplazar mi implementación de SqlDataAdapter con SqlBulkCopy. En SqlDataAapter hay una propiedad llamada "ContinueUpdateOnError", cuando se establece en verdadero adaptador. Actualización (tabla) insertará todas las filas posibles y etiquetará las filas de error con la propiedad RowError.

La pregunta es, ¿cómo puedo usar SqlBulkCopy para insertar datos lo más rápido posible y hacer un seguimiento de qué filas se insertaron y cuáles no (debido al índice único)?

Aquí está la información adicional:

  1. El proceso es iterativo, a menudo establecido en un horario para repetir.

  2. Las tablas de origen y destino pueden ser enormes, a veces millones de filas.

  3. Aunque es posible verificar primero los valores de hash, requiere dos transacciones por fila (primero para seleccionar el hash de la tabla de destino y luego realizar la inserción). Creo que en el caso de adapter.update (table), es más rápido verificar RowError que verificar los hash hits por fila.

Respuesta aceptada

SqlBulkCopy, tiene instalaciones de manejo de errores muy limitadas, por defecto ni siquiera comprueba restricciones.

Sin embargo, es rápido, realmente muy rápido.

Si desea solucionar el problema de la clave duplicada e identificar qué filas son duplicadas en un lote. Una opción es:

  • empezar tran
  • Tome un tablockx en la mesa, seleccione todos los valores actuales de "Hash" y colóquelos en un HashSet.
  • Filtrar los duplicados e informar.
  • Insertar los datos
  • commit tran

Este proceso funcionará eficazmente si está insertando grandes conjuntos y el tamaño de los datos iniciales en la tabla no es demasiado grande.

¿Puede ampliar su pregunta para incluir el resto del contexto del problema?

EDITAR

Ahora que tengo algo más de contexto, aquí hay otra manera de hacerlo:

  • Hacer el inserto a granel en una tabla de temperatura.
  • iniciar serializable tran
  • Seleccione todas las filas temporales que ya están en la tabla de destino ... informe sobre ellas
  • Inserte los datos en la tabla temporal en la tabla real, realizando una combinación a la izquierda en el hash e incluyendo todas las filas nuevas.
  • cometer el tran

Ese proceso es muy liviano en los viajes de ida y vuelta, y teniendo en cuenta que sus especificaciones deberían ser realmente rápidas;


Respuesta popular

Un enfoque ligeramente diferente al que ya se ha sugerido; Realice la SqlBulkCopy y capture la SqlException lanzada:

    Violation of PRIMARY KEY constraint 'PK_MyPK'. Cannot insert duplicate 
key in object 'dbo.MyTable'. **The duplicate key value is (17)**.

A continuación, puede eliminar todos los elementos de su fuente de ID 17, el primer registro que se duplicó. Estoy haciendo suposiciones aquí que se aplican a mis circunstancias y posiblemente no a las suyas; es decir, que la duplicación es causada por los mismos datos exactos de un SqlBulkCopy fallido anteriormente debido a errores de SQL / Red durante la carga.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué