Il "provider STREAM" OLE DB strano per il server collegato (null) ha restituito dati non validi per l'errore di colonna "[! BulkInsert] .Value"

c#-4.0 sqlbulkcopy sql-server-2008-r2

Domanda

Software utilizzato: Windows 7 64 bit Ultimate, .Net 4, SQL Server 2008 R2.

selezionare @@ restituisce la versione:

Microsoft SQL Server 2008 R2 (RTM) - 10.50.1617.0 (X64)   Apr 22 2011 19:23:43   Copyright (c) Microsoft Corporation  Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor) 

Per riprodurre e supponendo che si abbia un'istanza di R2 SQL Server SQL locale, incollare il seguente codice in linqpad ed eseguirlo come programma.

Scoppia con:

Il provider OLE DB 'STREAM' per server collegato '(null)' ha restituito dati non validi per la colonna '[! BulkInsert] .Value'.

void Main()
{
  SqlConnection cn = new SqlConnection("data source=localhost;Integrated Security=SSPI;initial catalog=tempdb;Connect Timeout=180;");
  cn.Open();

  IList<decimal> list = new List<decimal>() {-8m, 8m};

  decimal result = list.Sum(x => x);

  Console.WriteLine(result == 0);

  string tableName = "#test";

  CreateTemporaryTable(cn, tableName,
        String.Format(@"
          create table {0} (
            Value sql_variant
         );
       ", tableName));

  SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(cn);
  sqlBulkCopy.DestinationTableName = tableName;       

  DataTable dt = new DataTable();
  dt.Columns.Add("Value", typeof(object));
  dt.Rows.Add(result);
  sqlBulkCopy.WriteToServer(dt);

  sqlBulkCopy.Close();

  cn.Close();
}

// Define other methods and classes here


public static void CreateTemporaryTable(SqlConnection cn, string destinationTableName, string createTableStatement)
{
  string objectIdValue = (destinationTableName.StartsWith("#") ? "tempdb.." : "") + destinationTableName;
  string sql = String.Format(@" 
    if (object_id (N'{0}', N'U') is not null)
      begin
        drop table {1};
      end;
      {2}    
      ", objectIdValue, destinationTableName, createTableStatement);

//      Console.WriteLine(sql);
  SqlCommand cmd = new SqlCommand(sql, cn);
  try
  {
    cmd.ExecuteNonQuery();
  }
  finally
  {
    cmd.Dispose();
  }
}

Probabilmente creerò un caso con Microsoft, ma ero curioso di vedere se qualcun altro l'avesse visto prima, e se ci sono soluzioni alternative. Sembra che non tutti gli zeri siano creati uguali.

Solo un aggiornamento:

Ho aperto un caso con Microsoft. Ci sono voluti quasi 2 mesi per ottenere qualche oscuro flag dbcc non documentato che disabilita la convalida dei valori che vengono pompati tramite la copia bulk nella colonna variant. Il caso è stato rimbalzato tra i diversi team (il supporto è stato fornito da appaltatori privati ​​indiani) e non hanno mai avuto il problema di root che penso sia legato al valore prodotto dalle seguenti righe e come sia gestito dal codice di copia bulk :

  IList<decimal> list = new List<decimal>() {-8m, 8m};
  decimal result = list.Sum(x => x);

Quindi, per concludere, è stato deludente e ho rinunciato perché è un evento raro.

Risposta accettata

La soluzione indicata da Microsoft e che ho finito per utilizzare, è quella di utilizzare questo flag non documentato: DBCC TRACEON (7307, -1). È possibile abilitarlo a livello di connessione o a livello di server.


Risposta popolare

Se il tipo di dati per il valore della colonna è float, il tuo probabile problema è che tu invii un server double.NaN a sql, cosa che non gli piace.

Si noti che una chiamata come double.TryParse ("NaN", out dv) restituirà felicemente true e imposterà il dv a double.NaN

Spero che questo aiuti, K.



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