2009-05-04 8 views
5

Ich benutze SQL Express Express Edition und ich versuche, eine mehrzeilige einfügen durch meine C# -Anwendung.Mehrere Zeilen einfügen -> Anweisung überschreitet die maximal zulässige Anzahl von 1000 Zeilenwerten

Ich habe rund 100000 Datensätze, die eingefügt werden müssen.

Okay, alles gut geht für die ersten 1000 Datensätze dann den Fehler Ich erhalte: „Die Anzahl der Zeilenwert Ausdrücke in der INSERT-Anweisung überschreitet die maximal zulässige Anzahl von 1000 Zeilenwerte“

Ich schaute auf meine Spalte Datentyp -> Int, so sollte das nicht das Problem sein. Ich habe meinen Code überprüft und füge in Schritten von 500 Datensätzen ein.

Also ich googelte es aber konnte nichts nützliches finden. Kann mir jemand erklären, warum ich diesen Fehler bekomme und wenn möglich wie er gelöst wird.

+1

Können Sie uns etwas von Ihrem Code zeigen? Diese Fehlermeldung sollte nur auftreten, wenn Sie Zeilenwerte verwenden, z. INSERT INTO ... VALUES (...), (...), (...) <- 3 Zeilen hier, und das Limit ist 1000. –

+0

brauchen Sie eine Verzögerung zwischen den INSERT-Abfragen? – nlucaroni

+0

versuchen Sie, jeweils eine Zeile einzufügen? Versuchen Sie, eine gespeicherte Prozedur aufzurufen, um alle Einfügungen gleichzeitig auszuführen (wenn Sie dies nicht bereits tun) – northpole

Antwort

5

Sie können die Klasse SQLBulkCopy verwenden. Dies unterstützt Batching, Transaktionen und ist effizienter als Standard-Insert-Anweisungen.

+0

"Wenn sich die Quell- und Zieltabelle in derselben SQL Server-Instanz befinden, ist es einfacher und schneller, eine Transact-SQL-INSERT zu verwenden ... SELECT-Anweisung, um die Daten zu kopieren. " Quelle: http://msdn.microsoft.com/en-us/library/s4s223c6.aspx Nur für den Rekord. :) – ShdNx

0

dies ist, wie mein Code behandelt den Multieinsatz

var count = "SELECT COUNT(*) as rowcount FROM table_mysql GROUP BY id"; 

var countReader = Retrieve(count); 
var countRows = 0; 
try 
{ 
    while (countReader.Read()) 
    { 
     countRows += int.Parse(countReader.GetValue(0).ToString()); 
    } 
} 
catch (Exception ex) 
{ 
    Log.LogMessageToFile("Import.cs -> table_mssql: " + ex.StackTrace + " /n" + ex.Message); 
} 
finally 
{ 
    if (countReader != null) { countReader.Close(); _crud.close_conn(); } 
} 

for (var a = 0; a < countRows;) 
{ 
    var sql = "SELECT id, traffic_id, dow, uu, imps, impsuu, otsw, otsm FROM table_mysql LIMIT " + a + ", " + (a + 500) + ""; 

    var reader = Retrieve(sql); 
    try 
    { 
     var builder = new StringBuilder(); 
     builder.Append(
      "SET IDENTITY_INSERT table_mssql ON;INSERT INTO table_mssql(id, traffic_id, dow, uu, imps, impsuu, otsw, otsm) VALUES "); 
     while (reader.Read()) 
     { 
      Application.DoEvents(); 
      try 
      { 
       builder.Append("(" + reader.GetValue(0) + ", " + reader.GetValue(1) + ", " + 
           reader.GetValue(2) + 
           ", " + reader.GetValue(3) + ", " + reader.GetValue(4) + 
           ", " + reader.GetValue(5) + ", " + reader.GetValue(6) + ", " + 
           reader.GetValue(7) + 
           "), "); 

      } 
      catch (Exception ex) 
      { 
       Log.LogMessageToFile("Import.cs -> table_mssql: " + ex.StackTrace + " /n" + ex.Message); 
      } 
     } 

     var sqlDB = builder.ToString(0, builder.Length - 2); 

     sqlDB += ";SET IDENTITY_INSERT table_mssql OFF;"; 
     if (!InsertDB(sqlDB)) 
     { 
      Log.LogMessageToFile("Import.cs -> table_mssql: No insert happend!"); 
     } 
    } 
    catch (Exception ex) 
    { 
     Log.LogMessageToFile("Import.cs -> table_mssql: " + ex.StackTrace + " /n" + ex.Message); 
     return false; 
    } 
    finally 
    { 
     if (reader != null) 
     { 
      reader.Close(); 
      _crud.close_conn(); 
     } 
    } 
    a = a + 500; 
} 

Ich werde die SqlBulkCopy überprüfen. Vielleicht ist das eine bessere Lösung.

+0

Wie oben erwähnt, ist die Grenze für diese Methode 1000 Zeilen. Vielleicht möchten Sie in die INSERT INTO-Anweisung tblName SELECT ... FROM otherTbl schauen, da das, was Sie tun, fast direkt von einer anderen SQL-Anweisung kommt. Es gibt kein Zeilenlimit dafür. – Eric

0

Sie können das Ganze nehmen unten zu diesem:

var sql = "SET IDENTITY_INSERT table_mssql ON;" 
     + "INSERT INTO table_mssql" 
     +  "(id, traffic_id, dow, uu, imps, impsuu, otsw, otsm)" 
     + " SELECT id, traffic_id, dow, uu, imps, impsuu, otsw, otsm " 
     + " FROM table_mysql;" 
     + "SET IDENTITY_INSERT table_mssql OFF;"; 

if (!InsertDB(sqlDB)) 
{ 
    Log.LogMessageToFile("Import.cs -> table_mssql: No insert happend!"); 
} 

auch: Sie sollten wissen, dass SQL Server nicht LIMIT Schlüsselwort MySQLs unterstützt. Es verwendet stattdessen TOP oder ROW_NUMBER.

+0

Ist dies auch anwendbar, wenn die erste Abfrage auf eine MySQL-Datenbank zum Abrufen der Daten zugreift? Ich muss Daten von der MySQL-Datenbank zu meinem lokalen SQL Server 2008 Express übertragen. – Gerbrand

+0

Ah, ich bekomme jetzt deine Namenskonvention. Ihr Code-Snippet und der Text der Frage lassen es so aussehen, als würde alles durch dieselbe Verbindung gehen, Namen oder keine Namen. In diesem Fall müssen Sie die Daten auf Ihrem Client kurz halten, und BULK_INSERT ist bei weitem Ihre schnellste Option. –

+0

Oder mit viel Glück können Sie in der Lage sein, die MySQL-Datenbank mit SQL-Server als eine OLD-Datenquelle zu verbinden: http://developer.infi.nl/index.php?ID=6&article=6 –

Verwandte Themen