Cómo evitar que se inserten registros duplicados con SqlBulkCopy cuando no hay una clave principal

c# sql sqlbulkcopy sql-server sql-server-2008

Pregunta

Recibo un archivo XML diario que contiene miles de registros, cada uno de los cuales es una transacción comercial que necesito almacenar en una base de datos interna para uso en informes y facturación. Tenía la impresión de que el archivo de cada día contenía solo registros únicos, pero he descubierto que mi definición de único no es exactamente la misma que la del proveedor.

La aplicación actual que importa estos datos es una aplicación de consola C # .Net 3.5, lo hace utilizando SqlBulkCopy en una tabla de base de datos MS SQL Server 2008 donde las columnas coinciden exactamente con la estructura de los registros XML. Cada registro tiene un poco más de 100 campos, y no hay una clave natural en los datos, o más bien los campos que puedo encontrar tienen sentido, ya que una clave compuesta también tiene que permitir el nulo. Actualmente la tabla tiene varios índices, pero ninguna clave primaria.

Básicamente, toda la fila debe ser única. Si un campo es diferente, es lo suficientemente válido como para ser insertado. Observé cómo crear un hash MD5 de toda la fila, insertarlo en la base de datos y usar una restricción para evitar que SqlBulkCopy inserte la fila, pero no veo cómo introducir el Hash MD5 en la operación de BulkCopy y no estoy asegúrese de que toda la operación fallaría y se revertiría si fallara algún registro, o si continuaría.

El archivo contiene una gran cantidad de registros, yendo fila por fila en el XML, consultando la base de datos en busca de un registro que coincida con todos los campos, y luego decidir insertar es realmente la única forma en que puedo ver poder hacer esto. Esperaba no tener que volver a escribir la aplicación por completo, y la operación de copia masiva es mucho más rápida.

¿Alguien sabe de una manera de usar SqlBulkCopy mientras previene filas duplicadas, sin una clave principal? ¿O alguna sugerencia para una forma diferente de hacer esto?

Respuesta aceptada

Subiría los datos a una tabla de preparación y luego trataré con duplicados después de copiarlos en la tabla final.

Por ejemplo, puede crear un índice (no único) en la tabla de preparación para tratar la "clave"


Respuesta experta

¿Cuál es el volumen de datos? Tienes 2 opciones que puedo ver:

1: filtrarlo en la fuente, implementando su propio IDataReader y usando algo de hash sobre los datos, y simplemente omitiendo cualquier duplicado para que nunca se transfieran al TDS.

2: filtrarlo en el DB; en el nivel más simple, supongo que podría tener varias etapas de importación (los datos sin procesar y sin autorización) y luego copiar los datos de DISTINCT en sus tablas reales , tal vez utilizando una tabla intermedia si así lo desea. Es posible que desee utilizar CHECKSUM para algo de esto, pero depende.



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é