Comportamento casuale di SqlBulkCopy con DbDataReader

asp.net excel sqlbulkcopy sql-server

Domanda

Attualmente sto scrivendo un sito Asp.Net che caricare un file di Excel e salvare il contenuto in un database SQL Server e utilizzando SqlBulkCopy e un DbDataReader per farlo.

Le colonne di Excel e le tabelle del database sono denominate esattamente allo stesso modo.

Codice rilevante (numero ridotto di mappature delle colonne per maggiore chiarezza)

' Connection String to Excel Workbook
Dim excelConnectionString As String = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 8.0", path)
Dim connection As New OleDbConnection()
connection.ConnectionString = excelConnectionString
Dim command As New OleDbCommand("select * from [Sheet1$]", connection)

' Bulk Copy to SQL Server 
Dim bulkInsert As New SqlBulkCopy(sqlConnectionString)
bulkInsert.DestinationTableName = "UploadedOrders"
bulkInsert.BulkCopyTimeout = 0
bulkInsert.BatchSize = 50
bulkInsert.ColumnMappings.Add("Id", "Id")
bulkInsert.ColumnMappings.Add("CustomerId", "CustomerId")
bulkInsert.ColumnMappings.Add("Net", "Net")
... rest of columns

connection.Open()
Dim dr As DbDataReader = command.ExecuteReader()
bulkInsert.WriteToServer(dr)

L'ultima chiamata di WriteToServer genera un errore che dice

La colonna "Net" non consente DBNull.Value.

che non è così.

Tuttavia non ci sono Null in nessuno dei miei file di test. Alcuni di loro falliscono e alcuni funzionano. Si lamenta di colonne diverse per file diversi, ma sempre uguale per un file specifico.

Ecco cosa ho provato finora e conclusioni da esso:

  1. Ho diviso uno dei miei file di test in parti più piccole nel tentativo di identificare l'errore dei dati. Un file più piccolo funziona, quindi ho aggiunto sempre più file dal file originale fino a quando non si è rotto, e così è stato. Ciò indicherebbe errore nei dati. Ma la fila sembra a posto e inserendola in un altro file funziona. E spostandolo al penultimo e rimuovendo l'ultima riga (ora) e funziona. Quindi non un errore di dati.

  2. L'idea successiva era la dimensione e quando si aggiungevano le righe una alla volta finché non si rompeva c'era un comportamento ripetibile: aggiungere la riga e il file non funzionava. Rimozione e funziona. E il numero magico era 13959 righe. Ma alcuni dei file che stanno lavorando sono più grandi, quindi ho provato un altro file che non ha funzionato. Ha mostrato lo stesso identico comportamento, ma si è rotto dopo 14259 righe. Quindi non un problema di dimensioni, sebbene mostri problemi relativi alle dimensioni. Ripetibile, ma diverso per file diversi. E - ancora una volta - funzionano altri file più grandi.

  3. Ho provato tutti i tipi di timeout e bulksize di SqlBulkCopy senza fortuna.

  4. Ho provato tutti i tipi di stringhe del provider ADODB con Excel 12, 8 con o senza XML, HDR, ecc. Nessuna modifica.

  5. Ho provato tre diversi pacchetti di driver ACE (sto eseguendo Windows 10 a 64 bit e Office 2010 a 64 bit, quindi ce ne dovrebbe essere uno corretto, ma ho letto che aveva qualche problema, quindi ho provato anche Office 2007 e 32 bit). Nessun cambiamento.

  6. Aggiunto un codice tagliato per leggere effettivamente il DataReader riga per riga e cercare le righe con Net = Nothing nel caso in cui si trattasse di un problema di lettura di Excel piuttosto che scrivere nel Database. Non ho trovato nessuno.

  7. Aggiunta una domanda qui, sperando che chiunque possa fornire ulteriori elementi da testare o alcuni approfondimenti su cosa sta succedendo. Non ha senso per me ....

Grazie

AGGIORNARE:

Ho provato ad aggiungere tutti i nomi delle colonne in Excel come suggerito da Gordon (grazie!). Non ha funzionato

Ho anche provato ad aggiungere un "where xx is not null" per un paio di parametri che hanno generato errori in file diversi come suggerito da Bruce (grazie!). Questo fa scomparire l'errore e il file viene caricato. Tuttavia, viene importata solo una parte del file. Per un file sono stati caricati 14088 record di 30727 nel file e per un altro file sono stati caricati 14305 di 81195 record.

Ancora nessuna logica nel numero di record, ancora nessun errore di dati apparenti o valori nulli in Excel. Non ha senso ...

E ancora non sono sicuro se l'errore si verifica nella lettura da Excel o l'inserimento nel database.

Inoltre, è appena stato trovato nel registro eventi quando si esegue un caricamento. Non ho idea se è correlato.

"È stata eliminata una parte significativa della memoria di processo del server SQL, che potrebbe causare un peggioramento delle prestazioni Durata: 0 secondi Set di lavoro (KB): 141460, impegnato (KB): 393412, utilizzo della memoria: 35 %%."

Risposta popolare

Ok, ho trovato il problema e la soluzione.

Risulta che non era correlato a BulkCopy o al database. E 'stata la lettura da Excel che ha vacillato.

Dopo un po 'più di debug e di codice temporaneo, ho scoperto che solo alcuni record di 14' sono stati letti da Excel nel DataReader.

Aggiunto IMEX = 1 alla stringa di connessione e ripulito alcune virgolette doppie + triple e funziona. La stringa di connessione Ace è ora:

"Provider = Microsoft.ACE.OLEDB.12.0; Origine dati = {0}; Proprietà estese =" "Excel 8.0; HDR = YES; IMEX = 1;" "", percorso)

Grazie per tutti gli input. Molto apprezzato.



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché