L'eccezione SqlBulkCopy non contiene il nome della colonna

.net exception sqlbulkcopy vb.net

Domanda

Se il DataTable passato a SqlBulkCopy.WriteToServer () contiene valori che non riusciranno a convertire, ricevo un InvalidOperationException che visualizza il valore che non è riuscito a convertire. Il nome della colonna non viene visualizzato da nessuna parte nell'eccezione da ciò che potrei dire. Sto cercando di registrare il nome e il valore della colonna quando questo si verifica. C'è un modo per recuperare queste informazioni?

System.InvalidOperationException: The given value of type SqlDecimal from the 
    data source cannot be converted to type decimal of the specified target column. 
    ---> System.InvalidOperationException: The given value of type SqlDecimal from 
    the data source cannot be converted to type decimal of the specified target column. 
    ---> System.ArgumentException: Parameter value '9999999999999999999999999999.00' 
    is out of range.

Risposta popolare

Penso che la risposta breve sia no, non c'è modo di ottenere SqlBulkCopy per dirti quale colonna sta causando il problema.

Nel tuo caso, penso che devi aggiungere la tua convalida a tutte le colonne decimali nel tuo codice .net. Il numero che ha esito negativo ha 28 cifre a sinistra della virgola decimale, quindi qualsiasi colonna SQL con una precisione inferiore al decimale (28, 0) fallirebbe questo inserto. Dai un'occhiata a questa domanda riguardante la convalida di .net decimali per SQL:

Convalida dei decimali in C # per l'archiviazione in SQL Server

In un senso più generale, è possibile ottenere un errore simile se l'ordinamento della colonna .net DataTable non corrisponde alla tabella SQL. In una tabella con colonne nel seguente ordine VarcharColumn, IntColumn, DecimalColumn, anche se le colonne sono state denominate, la tabella seguente non inserirà:

        DataTable tbl = new DataTable();
        tbl.Columns.Add("IntColumn", Type.GetType("System.Int32"));            
        tbl.Columns.Add("VarcharColumn", Type.GetType("System.String"));                        
        tbl.Columns.Add("DecimalColumn", Type.GetType("System.Decimal"));

Dovresti riordinare le colonne C # in alto o fornire i mapping delle colonne:

        SqlBulkCopy blkCpy = new SqlBulkCopy(conn);            
        blkCpy.ColumnMappings.Add("VarcharColumn", "VarcharColumn");
        blkCpy.ColumnMappings.Add("IntColumn", "IntColumn");
        blkCpy.ColumnMappings.Add("DecimalColumn", "DecimalColumn");

Un altro trucco è se si esegue il debug di un batch in cui non si riesce a inserire una riga specifica, è possibile utilizzare l'evento SQLRowsCopied di SQLBulkCopy per identificare quale riga sta causando il problema. Per esempio:

        SqlBulkCopy blkCpy = new SqlBulkCopy(conn);
        blkCpy.SqlRowsCopied += blkCpy_SqlRowsCopied;
        blkCpy.NotifyAfter = 1;

Quindi nel gestore dell'evento:

    static void blkCpy_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e)
    {
        Console.WriteLine("Copied {0} rows", e.RowsCopied);
    }


Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow